From e0a7478fde5a9bb1a8c87dd25165a59069551307 Mon Sep 17 00:00:00 2001 From: Pat Manning Date: Wed, 14 Sep 2022 17:42:05 +0100 Subject: [PATCH 001/429] Refresh taskbar apps show on DeviceProfile change. Fix: 244269456 Test: manual Change-Id: Ie95813c77b45b03a824542a25d1349675b1825c0 --- .../android/launcher3/taskbar/TaskbarViewController.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 992aa4bd7d..31775e2b7d 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -100,6 +100,9 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar private int mThemeIconsColor; + private final DeviceProfile.OnDeviceProfileChangeListener mDeviceProfileChangeListener = + dp -> commitRunningAppsToUI(); + public TaskbarViewController(TaskbarActivityContext activity, TaskbarView taskbarView) { mActivity = activity; mTaskbarView = taskbarView; @@ -127,10 +130,13 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar controllers.navbarButtonsViewController.getTaskbarNavButtonTranslationY(); mTaskbarNavButtonTranslationYForInAppDisplay = controllers.navbarButtonsViewController .getTaskbarNavButtonTranslationYForInAppDisplay(); + + mActivity.addOnDeviceProfileChangeListener(mDeviceProfileChangeListener); } public void onDestroy() { LauncherAppState.getInstance(mActivity).getModel().removeCallbacks(mModelCallbacks); + mActivity.removeOnDeviceProfileChangeListener(mDeviceProfileChangeListener); mModelCallbacks.unregisterListeners(); } From d887b561834bbf9dee3c98b835fcd7c691657834 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Fri, 16 Sep 2022 16:45:50 -0700 Subject: [PATCH 002/429] Reset TaskView transformations on orientationHandler change * Transformations in the old orientation handler (ex. translate X for portrait) aren't reset when device changes to fake landscape (starts modifying translate Y). The new translations are picked up correctly, this resets the old ones. Test: Bug no longer repros. Rotated device while scrolling through tasks, no change in behavior from before. Can't think of other instances where tasks are in motion and orientation handler can change. Fixes: 233316942 Change-Id: Ie07340e69a2c93b71b1dabb8029c96ad05a4d4a1 --- quickstep/src/com/android/quickstep/views/RecentsView.java | 1 + 1 file changed, 1 insertion(+) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 28a358e1c6..b7c6e6b275 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -1771,6 +1771,7 @@ public abstract class RecentsView Date: Wed, 21 Sep 2022 17:31:48 -0400 Subject: [PATCH 003/429] Change taskbar edu size to wrap around icons Bug: 217262479 Test: manual Change-Id: I766394f4f64d5ba76c1bf50de9d06526376e6662 --- quickstep/res/values/dimens.xml | 1 + .../taskbar/TaskbarEduController.java | 4 ++++ .../launcher3/taskbar/TaskbarEduView.java | 20 +++++++++++++++++++ 3 files changed, 25 insertions(+) diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index c85e71cebc..27d707bd0c 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -268,6 +268,7 @@ 4dp 25dp 4dp + 112dp 88dp 40dp 40dp diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java index 32a3c10d87..7b9fc6ac5a 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java @@ -217,5 +217,9 @@ public class TaskbarEduController implements TaskbarControllers.LoggableTaskbarC v -> mTaskbarEduView.snapToPage(currentPage + 1)); } } + + int getIconLayoutBoundsWidth() { + return mControllers.taskbarViewController.getIconLayoutBounds().width(); + } } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java index 89d67be685..c0cbbd697d 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java @@ -39,6 +39,9 @@ public class TaskbarEduView extends AbstractSlideInView private final Rect mInsets = new Rect(); + // Initialized in init. + private TaskbarEduController.TaskbarEduCallbacks mTaskbarEduCallbacks; + private Button mStartButton; private Button mEndButton; private TaskbarEduPagedView mPagedView; @@ -56,6 +59,7 @@ public class TaskbarEduView extends AbstractSlideInView if (mPagedView != null) { mPagedView.setControllerCallbacks(callbacks); } + mTaskbarEduCallbacks = callbacks; } @Override @@ -101,6 +105,22 @@ public class TaskbarEduView extends AbstractSlideInView Settings.Secure.LAUNCHER_TASKBAR_EDUCATION_SHOWING, 0); } + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + + int contentWidth = Math.min(getContentAreaWidth(), getMeasuredWidth()); + contentWidth = Math.max(contentWidth, mTaskbarEduCallbacks.getIconLayoutBoundsWidth()); + int contentAreaWidthSpec = MeasureSpec.makeMeasureSpec(contentWidth, MeasureSpec.EXACTLY); + + mContent.measure(contentAreaWidthSpec, MeasureSpec.UNSPECIFIED); + } + + private int getContentAreaWidth() { + return mTaskbarEduCallbacks.getIconLayoutBoundsWidth() + + getResources().getDimensionPixelSize(R.dimen.taskbar_edu_horizontal_margin) * 2; + } + /** Show the Education flow. */ public void show() { attachToContainer(); From 26fee57f372a58e08ae3f00f57844e4101fe357a Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Thu, 22 Sep 2022 16:25:10 -0700 Subject: [PATCH 004/429] Null out mSplitHiddenTaskView when resetting split selection state * May have accidentally been removed in ag/19984439 Fixes: 248153819 Test: Repro in bug doesn't occur Change-Id: Icdc04de84c28963d36368f9672baf5993cd87d8a --- quickstep/src/com/android/quickstep/views/RecentsView.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 96607a0b84..b7d943268f 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -4259,6 +4259,10 @@ public abstract class RecentsView Date: Wed, 14 Sep 2022 15:52:47 +0000 Subject: [PATCH 005/429] Disable split button instead of hiding it The split button remains visible when there is only a single task present, but in a disabled state. Test: Manual Bug: 227600027 Change-Id: I36e8904bf342021db210cea7355a3806c783f235 --- .../quickstep/views/OverviewActionsView.java | 52 ++++++++++++++----- .../android/quickstep/views/RecentsView.java | 5 +- 2 files changed, 40 insertions(+), 17 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java index 08a17c49f0..abace7cd7d 100644 --- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java +++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java @@ -82,10 +82,11 @@ public class OverviewActionsView extends FrameLayo private static final int INDEX_HIDDEN_FLAGS_ALPHA = 3; private static final int INDEX_SHARE_TARGET_ALPHA = 4; - public @interface SplitButtonDisabledFlags { } - + public @interface SplitButtonHiddenFlags { } public static final int FLAG_IS_NOT_TABLET = 1 << 0; - public static final int FLAG_SINGLE_TASK = 1 << 1; + + public @interface SplitButtonDisabledFlags { } + public static final int FLAG_SINGLE_TASK = 1 << 0; private MultiValueAlpha mMultiValueAlpha; private Button mSplitButton; @@ -96,6 +97,9 @@ public class OverviewActionsView extends FrameLayo @ActionsDisabledFlags protected int mDisabledFlags; + @SplitButtonHiddenFlags + private int mSplitButtonHiddenFlags; + @SplitButtonDisabledFlags private int mSplitButtonDisabledFlags; @@ -191,20 +195,40 @@ public class OverviewActionsView extends FrameLayo } boolean isEnabled = (mDisabledFlags & ~DISABLED_ROTATED) == 0; LayoutUtils.setViewEnabled(this, isEnabled); + updateSplitButtonEnabledState(); } /** - * Updates the proper flags to indicate whether the "Split screen" button should be enabled. + * Updates the proper flags to indicate whether the "Split screen" button should be hidden. * - * @param flag The flag to update. - * @param enable Whether to enable the disable flag: True will cause view to be disabled. + * @param flag The flag to update. + * @param enable Whether to enable the hidden flag: True will cause view to be hidden. */ - public void updateSplitButtonFlags(@SplitButtonDisabledFlags int flag, boolean enable) { + public void updateSplitButtonHiddenFlags(@SplitButtonHiddenFlags int flag, boolean enable) { + if (enable) { + mSplitButtonHiddenFlags |= flag; + } else { + mSplitButtonHiddenFlags &= ~flag; + } + if (mSplitButton == null) return; + boolean shouldBeVisible = mSplitButtonHiddenFlags == 0; + mSplitButton.setVisibility(shouldBeVisible ? VISIBLE : GONE); + findViewById(R.id.action_split_space).setVisibility(shouldBeVisible ? VISIBLE : GONE); + } + + /** + * Updates the proper flags to indicate whether the "Split screen" button should be disabled. + * + * @param flag The flag to update. + * @param enable Whether to enable the disable flag: True will cause view to be disabled. + */ + public void updateSplitButtonDisabledFlags(@SplitButtonDisabledFlags int flag, boolean enable) { if (enable) { mSplitButtonDisabledFlags |= flag; } else { mSplitButtonDisabledFlags &= ~flag; } + updateSplitButtonEnabledState(); } public AlphaProperty getContentAlpha() { @@ -289,16 +313,16 @@ public class OverviewActionsView extends FrameLayo } /** - * Shows/hides the "Split" button based on the status of mHiddenFlags. + * Enables/disables the "Split" button based on the status of mSplitButtonDisabledFlags and + * mDisabledFlags. */ - public void updateSplitButtonVisibility() { + private void updateSplitButtonEnabledState() { if (mSplitButton == null) { return; } - boolean shouldBeVisible = mSplitButtonDisabledFlags == 0 - // and neither of these flags are active - && (mHiddenFlags & (HIDDEN_SPLIT_SCREEN | HIDDEN_SPLIT_SELECT_ACTIVE)) == 0; - mSplitButton.setVisibility(shouldBeVisible ? VISIBLE : GONE); - findViewById(R.id.action_split_space).setVisibility(shouldBeVisible ? VISIBLE : GONE); + boolean isParentEnabled = (mDisabledFlags & ~DISABLED_ROTATED) == 0; + boolean shouldBeEnabled = mSplitButtonDisabledFlags == 0 && isParentEnabled; + mSplitButton.setEnabled(shouldBeEnabled); } + } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index f8bf3d8c59..0176b22d29 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -3391,10 +3391,9 @@ public abstract class RecentsView Date: Fri, 23 Sep 2022 17:04:29 +0000 Subject: [PATCH 006/429] Revert "Introducing new variable to enable/disable shortcuts." Revert "Introducing new variable to enable/disable shortcuts." Revert submission 19632697-cherrypick-GO-DISABLE-SHORTCUTS-tyyzrpy9oe Reason for revert: Reverting changes for the recent feature built by me. This CL was a part of the feature. Please take a call if we should revert it or not. Reverted Changes: Ib373b042f:Introducing new variable to enable/disable shortcu... I4274cb468:Introducing new variable to enable/disable shortcu... Change-Id: I81f338be71185cb008e81b020c5b3a7b01b64c58 --- go/src/com/android/launcher3/model/WidgetsModel.java | 4 +--- .../launcher3/icons/ShortcutCachingLogic.java | 4 ++-- src/com/android/launcher3/model/BgDataModel.java | 4 ++-- .../android/launcher3/shortcuts/ShortcutRequest.java | 12 ++++++------ src/com/android/launcher3/util/ShortcutUtil.java | 2 +- src/com/android/launcher3/views/AppLauncher.java | 4 ++-- .../com/android/launcher3/model/WidgetsModel.java | 2 -- 7 files changed, 14 insertions(+), 18 deletions(-) diff --git a/go/src/com/android/launcher3/model/WidgetsModel.java b/go/src/com/android/launcher3/model/WidgetsModel.java index 9a000d6b52..1aa5d03f6d 100644 --- a/go/src/com/android/launcher3/model/WidgetsModel.java +++ b/go/src/com/android/launcher3/model/WidgetsModel.java @@ -41,10 +41,8 @@ import java.util.Set; */ public class WidgetsModel { - // True if the widget support is disabled. + // True is the widget support is disabled. public static final boolean GO_DISABLE_WIDGETS = true; - // True if the shortcut support is disabled. - public static final boolean GO_DISABLE_SHORTCUTS = true; public static final boolean GO_DISABLE_NOTIFICATION_DOTS = true; private static final ArrayList EMPTY_WIDGET_LIST = new ArrayList<>(); diff --git a/src/com/android/launcher3/icons/ShortcutCachingLogic.java b/src/com/android/launcher3/icons/ShortcutCachingLogic.java index 1dc6751a34..6a8f34a93d 100644 --- a/src/com/android/launcher3/icons/ShortcutCachingLogic.java +++ b/src/com/android/launcher3/icons/ShortcutCachingLogic.java @@ -16,7 +16,7 @@ package com.android.launcher3.icons; -import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_SHORTCUTS; +import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS; import android.content.ComponentName; import android.content.Context; @@ -94,7 +94,7 @@ public class ShortcutCachingLogic implements CachingLogic { * Launcher specific checks */ public static Drawable getIcon(Context context, ShortcutInfo shortcutInfo, int density) { - if (GO_DISABLE_SHORTCUTS) { + if (GO_DISABLE_WIDGETS) { return null; } try { diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java index ffb0f2f40e..de23c4b31f 100644 --- a/src/com/android/launcher3/model/BgDataModel.java +++ b/src/com/android/launcher3/model/BgDataModel.java @@ -17,7 +17,7 @@ package com.android.launcher3.model; import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_GET_KEY_FIELDS_ONLY; -import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_SHORTCUTS; +import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS; import static com.android.launcher3.shortcuts.ShortcutRequest.PINNED; import static java.util.stream.Collectors.groupingBy; @@ -286,7 +286,7 @@ public class BgDataModel { * shortcuts and unpinning any extra shortcuts. */ public synchronized void updateShortcutPinnedState(Context context, UserHandle user) { - if (GO_DISABLE_SHORTCUTS) { + if (GO_DISABLE_WIDGETS) { return; } diff --git a/src/com/android/launcher3/shortcuts/ShortcutRequest.java b/src/com/android/launcher3/shortcuts/ShortcutRequest.java index 07d3292e3e..5291ce4620 100644 --- a/src/com/android/launcher3/shortcuts/ShortcutRequest.java +++ b/src/com/android/launcher3/shortcuts/ShortcutRequest.java @@ -16,7 +16,7 @@ package com.android.launcher3.shortcuts; -import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_SHORTCUTS; +import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS; import android.content.ComponentName; import android.content.Context; @@ -46,7 +46,7 @@ public class ShortcutRequest { | ShortcutQuery.FLAG_MATCH_MANIFEST; public static final int PINNED = ShortcutQuery.FLAG_MATCH_PINNED; - private final ShortcutQuery mQuery = GO_DISABLE_SHORTCUTS ? null : new ShortcutQuery(); + private final ShortcutQuery mQuery = GO_DISABLE_WIDGETS ? null : new ShortcutQuery(); private final Context mContext; private final UserHandle mUserHandle; @@ -73,7 +73,7 @@ public class ShortcutRequest { * @return A list of ShortcutInfo's associated with the given package. */ public ShortcutRequest forPackage(String packageName, @Nullable List shortcutIds) { - if (!GO_DISABLE_SHORTCUTS && packageName != null) { + if (!GO_DISABLE_WIDGETS && packageName != null) { mQuery.setPackage(packageName); mQuery.setShortcutIds(shortcutIds); } @@ -81,7 +81,7 @@ public class ShortcutRequest { } public ShortcutRequest withContainer(@Nullable ComponentName activity) { - if (!GO_DISABLE_SHORTCUTS) { + if (!GO_DISABLE_WIDGETS) { if (activity == null) { mFailed = true; } else { @@ -92,7 +92,7 @@ public class ShortcutRequest { } public QueryResult query(int flags) { - if (GO_DISABLE_SHORTCUTS || mFailed) { + if (GO_DISABLE_WIDGETS || mFailed) { return QueryResult.DEFAULT; } mQuery.setQueryFlags(flags); @@ -108,7 +108,7 @@ public class ShortcutRequest { public static class QueryResult extends ArrayList { - static final QueryResult DEFAULT = new QueryResult(GO_DISABLE_SHORTCUTS); + static final QueryResult DEFAULT = new QueryResult(GO_DISABLE_WIDGETS); private final boolean mWasSuccess; diff --git a/src/com/android/launcher3/util/ShortcutUtil.java b/src/com/android/launcher3/util/ShortcutUtil.java index 79cafa04a2..91cf835287 100644 --- a/src/com/android/launcher3/util/ShortcutUtil.java +++ b/src/com/android/launcher3/util/ShortcutUtil.java @@ -34,7 +34,7 @@ public class ShortcutUtil { * Returns true when we should show depp shortcuts in shortcut menu for the item. */ public static boolean supportsDeepShortcuts(ItemInfo info) { - return isActive(info) && isApp(info) && !WidgetsModel.GO_DISABLE_SHORTCUTS; + return isActive(info) && isApp(info) && !WidgetsModel.GO_DISABLE_WIDGETS; } /** diff --git a/src/com/android/launcher3/views/AppLauncher.java b/src/com/android/launcher3/views/AppLauncher.java index dc07e45e11..19e66abd78 100644 --- a/src/com/android/launcher3/views/AppLauncher.java +++ b/src/com/android/launcher3/views/AppLauncher.java @@ -16,7 +16,7 @@ package com.android.launcher3.views; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP; -import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_SHORTCUTS; +import static com.android.launcher3.model.WidgetsModel.GO_DISABLE_WIDGETS; import android.app.ActivityOptions; import android.content.ActivityNotFoundException; @@ -190,7 +190,7 @@ public interface AppLauncher extends ActivityContext { */ default void startShortcut(String packageName, String id, Rect sourceBounds, Bundle startActivityOptions, UserHandle user) { - if (GO_DISABLE_SHORTCUTS) { + if (GO_DISABLE_WIDGETS) { return; } try { diff --git a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java index 13ad7a4ec5..702f3430aa 100644 --- a/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java +++ b/src_shortcuts_overrides/com/android/launcher3/model/WidgetsModel.java @@ -62,8 +62,6 @@ public class WidgetsModel { // True is the widget support is disabled. public static final boolean GO_DISABLE_WIDGETS = false; - // True is the shortcut support is disabled. - public static final boolean GO_DISABLE_SHORTCUTS = false; public static final boolean GO_DISABLE_NOTIFICATION_DOTS = false; private static final String TAG = "WidgetsModel"; From a44d255c8fe2f3cf0a8ee62fc6ddf4c8329b49e6 Mon Sep 17 00:00:00 2001 From: Sebastian Franco Date: Tue, 20 Sep 2022 17:41:13 -0500 Subject: [PATCH 007/429] Fix ReorderWidgets by removing faulty 4x4 cases Fix: 242323136 Test: atest ReorderWidgets (the device has to be cf_x86_64_phone-userdebug) Change-Id: Ic545409ecc20420be6c7377513c704822dbaf75e --- .../testcases/MoveOutReorderCase.java | 20 +------------------ .../celllayout/testcases/PushReorderCase.java | 20 +------------------ 2 files changed, 2 insertions(+), 38 deletions(-) diff --git a/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java index a222d3d551..047d3422df 100644 --- a/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java +++ b/tests/src/com/android/launcher3/celllayout/testcases/MoveOutReorderCase.java @@ -63,25 +63,7 @@ public class MoveOutReorderCase { MOVE_TO_6x5, END_BOARD_STR_6x5); - /** 4x4 Test - **/ - private static final String START_BOARD_STR_4x4 = "" - + "xxxx\n" - + "34-m\n" - + "3511\n" - + "3211"; - private static final Point MOVE_TO_4x4 = new Point(1, 2); - private static final String END_BOARD_STR_4x4 = "" - + "xxxx\n" - + "345-\n" - + "3m11\n" - + "3211"; - private static final ReorderTestCase TEST_CASE_4x4 = new ReorderTestCase(START_BOARD_STR_4x4, - MOVE_TO_4x4, - END_BOARD_STR_4x4); - public static final Map TEST_BY_GRID_SIZE = Map.of(new Point(5, 5), TEST_CASE_5x5, - new Point(6, 5), TEST_CASE_6x5, - new Point(4, 4), TEST_CASE_4x4); + new Point(6, 5), TEST_CASE_6x5); } diff --git a/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java b/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java index e16ff42a8b..38c9aee0fd 100644 --- a/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java +++ b/tests/src/com/android/launcher3/celllayout/testcases/PushReorderCase.java @@ -64,25 +64,7 @@ public class PushReorderCase { MOVE_TO_6x5, END_BOARD_STR_6x5); - /** 4x4 Test - **/ - private static final String START_BOARD_STR_4x4 = "" - + "xxxx\n" - + "222m\n" - + "-111\n" - + "----"; - private static final Point MOVE_TO_4x4 = new Point(2, 1); - private static final String END_BOARD_STR_4x4 = "" - + "xxxx\n" - + "--m-\n" - + "222-\n" - + "-111"; - private static final ReorderTestCase TEST_CASE_4x4 = new ReorderTestCase(START_BOARD_STR_4x4, - MOVE_TO_4x4, - END_BOARD_STR_4x4); - public static final Map TEST_BY_GRID_SIZE = Map.of(new Point(5, 5), TEST_CASE_5x5, - new Point(6, 5), TEST_CASE_6x5, - new Point(4, 4), TEST_CASE_4x4); + new Point(6, 5), TEST_CASE_6x5); } From 96bed75d9f65bd8adeb5858d5508a0438d0db1ca Mon Sep 17 00:00:00 2001 From: Saumya Prakash Date: Tue, 27 Sep 2022 15:15:26 +0000 Subject: [PATCH 008/429] Updated overview exit animation for 3 button navigation Changed overview exit animation so that tiles don't slide off and only fade/scale in place for 3 button navigation. Previously, tiles would slide off when exiting for both gesture navigation and 3 button navigation. Now 3 button navigation exits with tiles staying in place. Test: Manual Fix: 245745939 Change-Id: I4144ed7e3ff29419df7fb13b6417ccc0a1f9dd45 --- .../states/QuickstepAtomicAnimationFactory.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java index f75a404821..1e90aaf433 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java @@ -113,19 +113,19 @@ public class QuickstepAtomicAnimationFactory extends config.setInterpolator(ANIM_OVERVIEW_FADE, FINAL_FRAME); config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, EMPHASIZED_DECELERATE); config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_Y, FINAL_FRAME); + + // Scroll RecentsView to page 0 as it goes offscreen, if necessary. + int numPagesToScroll = overview.getNextPage() - DEFAULT_PAGE; + long scrollDuration = Math.min(MAX_PAGE_SCROLL_DURATION, + numPagesToScroll * PER_PAGE_SCROLL_DURATION); + config.duration = Math.max(config.duration, scrollDuration); + overview.snapToPage(DEFAULT_PAGE, Math.toIntExact(config.duration)); } else { config.setInterpolator(ANIM_OVERVIEW_TRANSLATE_X, ACCEL_DEACCEL); config.setInterpolator(ANIM_OVERVIEW_SCALE, clampToProgress(ACCEL, 0, 0.9f)); config.setInterpolator(ANIM_OVERVIEW_FADE, DEACCEL_1_7); } - // Scroll RecentsView to page 0 as it goes offscreen, if necessary. - int numPagesToScroll = overview.getNextPage() - DEFAULT_PAGE; - long scrollDuration = Math.min(MAX_PAGE_SCROLL_DURATION, - numPagesToScroll * PER_PAGE_SCROLL_DURATION); - config.duration = Math.max(config.duration, scrollDuration); - overview.snapToPage(DEFAULT_PAGE, Math.toIntExact(config.duration)); - Workspace workspace = mActivity.getWorkspace(); // Start from a higher workspace scale, but only if we're invisible so we don't jump. boolean isWorkspaceVisible = workspace.getVisibility() == VISIBLE; From fa37a0ad9b062f5d2dcef60aeb749c5ebabbb456 Mon Sep 17 00:00:00 2001 From: Sebastian Franco Date: Wed, 18 May 2022 10:14:01 -0700 Subject: [PATCH 009/429] Fix repeated empty workspaces after changing the grid size. There are specific scenarios when you can force an extra empty workspace after changing the grid, fortunately there is a function that removes empty workspaces. Fix:229349287 Test: Add a widget in a new empty workspace page, change the grid then remove the widget in the new grid size then return to the previous grid and it shouldn't have an empty workspace. Change-Id: I7b73ae2ca058bc84b3b361930e3dc856c045281b --- src/com/android/launcher3/Launcher.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index a6831aafa9..aeeb41282e 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -2742,6 +2742,8 @@ public class Launcher extends StatefulActivity getViewCache().setCacheSize(R.layout.folder_page, 2); TraceHelper.INSTANCE.endSection(traceToken); + + mWorkspace.removeExtraEmptyScreen(true); } private boolean canAnimatePageChange() { From c0095e81ae65410bcb18bd9a37277cb64d7579a6 Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Wed, 28 Sep 2022 18:56:42 -0700 Subject: [PATCH 010/429] Remove ENABLE_QUICKSTEP_LIVE_TILE flag Fixes: 249627137 Test: manual - (1) swipe up from app (2) swipe home (3) quick switch (4) split in overview Change-Id: Ibe56ba3824b379b20fb3f0aa09be4d6bdb5abaa1 --- .../uioverrides/QuickstepLauncher.java | 7 +- .../NavBarToHomeTouchController.java | 13 +-- .../android/quickstep/AbsSwipeUpHandler.java | 57 ++++-------- .../quickstep/FallbackActivityInterface.java | 4 +- .../quickstep/LauncherActivityInterface.java | 6 +- .../android/quickstep/RecentsActivity.java | 11 +-- .../quickstep/TaskAnimationManager.java | 9 +- .../android/quickstep/TaskOverlayFactory.java | 13 +-- .../com/android/quickstep/TaskViewUtils.java | 3 +- .../quickstep/TouchInteractionService.java | 7 +- .../fallback/RecentsTaskController.java | 5 +- .../inputconsumers/OverviewInputConsumer.java | 29 +++--- .../quickstep/util/TaskViewSimulator.java | 3 +- .../android/quickstep/views/RecentsView.java | 89 +++++++------------ .../quickstep/views/TaskThumbnailView.java | 14 ++- .../com/android/quickstep/views/TaskView.java | 5 +- .../quickstep/AbstractQuickStepTest.java | 5 +- .../launcher3/config/FeatureFlags.java | 3 - 18 files changed, 94 insertions(+), 189 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 192ac6251e..4ca27b1145 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -29,7 +29,6 @@ import static com.android.launcher3.LauncherState.OVERVIEW_MODAL_TASK; import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT; import static com.android.launcher3.anim.Interpolators.EMPHASIZED; import static com.android.launcher3.compat.AccessibilityManagerCompat.sendCustomAccessibilityEvent; -import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE; import static com.android.launcher3.config.FeatureFlags.ENABLE_WIDGET_PICKER_DEPTH; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP; @@ -559,10 +558,8 @@ public class QuickstepLauncher extends Launcher { @Override protected void onScreenOff() { super.onScreenOff(); - if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { - RecentsView recentsView = getOverviewPanel(); - recentsView.finishRecentsAnimation(true /* toRecents */, null); - } + RecentsView recentsView = getOverviewPanel(); + recentsView.finishRecentsAnimation(true /* toRecents */, null); } /** diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java index 30bb892c9a..40dfd82f5d 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NavBarToHomeTouchController.java @@ -25,7 +25,6 @@ import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS import static com.android.launcher3.allapps.AllAppsTransitionController.ALL_APPS_PULL_BACK_TRANSLATION; 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_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_GESTURE; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; @@ -139,9 +138,7 @@ public class NavBarToHomeTouchController implements TouchController, AnimatorControllerWithResistance.createRecentsResistanceFromOverviewAnim(mLauncher, builder); - if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { - builder.addOnFrameCallback(recentsView::redrawLiveTile); - } + builder.addOnFrameCallback(recentsView::redrawLiveTile); AbstractFloatingView.closeOpenContainer(mLauncher, AbstractFloatingView.TYPE_TASK_MENU); } else if (mStartState == ALL_APPS) { @@ -182,11 +179,9 @@ public class NavBarToHomeTouchController implements TouchController, boolean success = interpolatedProgress >= SUCCESS_TRANSITION_PROGRESS || (velocity < 0 && fling); if (success) { - if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { - RecentsView recentsView = mLauncher.getOverviewPanel(); - recentsView.switchToScreenshot(null, - () -> recentsView.finishRecentsAnimation(true /* toRecents */, null)); - } + RecentsView recentsView = mLauncher.getOverviewPanel(); + recentsView.switchToScreenshot(null, + () -> recentsView.finishRecentsAnimation(true /* toRecents */, null)); if (mStartState.overviewUi) { new OverviewToHomeAnim(mLauncher, () -> onSwipeInteractionCompleted(mEndState)) .animateWithVelocity(velocity); diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index f3630c187b..a78142d4b3 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -26,7 +26,6 @@ import static com.android.launcher3.PagedView.INVALID_PAGE; 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; @@ -400,12 +399,6 @@ public abstract class AbsSwipeUpHandler, this::resetStateForAnimationCancel); mStateCallback.runOnceAtState(STATE_HANDLER_INVALIDATED | STATE_FINISH_WITH_NO_END, this::resetStateForAnimationCancel); - - 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)); - } } protected boolean onActivityInit(Boolean alreadyOnHome) { @@ -583,14 +576,10 @@ public abstract class AbsSwipeUpHandler, } private void onDeferredActivityLaunch() { - if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { - mActivityInterface.switchRunningTaskViewToScreenshot( - null, () -> { - mTaskAnimationManager.finishRunningRecentsAnimation(true /* toHome */); - }); - } else { - mTaskAnimationManager.finishRunningRecentsAnimation(true /* toHome */); - } + mActivityInterface.switchRunningTaskViewToScreenshot( + null, () -> { + mTaskAnimationManager.finishRunningRecentsAnimation(true /* toHome */); + }); } private void setupRecentsViewUi() { @@ -1719,8 +1708,7 @@ public abstract class AbsSwipeUpHandler, } private void invalidateHandler() { - if (!ENABLE_QUICKSTEP_LIVE_TILE.get() || !mActivityInterface.isInLiveTileMode() - || mGestureState.getEndTarget() != RECENTS) { + if (!mActivityInterface.isInLiveTileMode() || mGestureState.getEndTarget() != RECENTS) { mInputConsumerProxy.destroy(); mTaskAnimationManager.setLiveTileCleanUpHandler(null); } @@ -1765,10 +1753,6 @@ public abstract class AbsSwipeUpHandler, * continued quick switch gesture, which cancels the previous handler but doesn't invalidate it. */ private void resetLauncherListeners() { - // Reset the callback for deferred activity launches - if (!ENABLE_QUICKSTEP_LIVE_TILE.get()) { - mActivityInterface.setOnDeferredActivityLaunchCallback(null); - } mActivity.getRootView().setOnApplyWindowInsetsListener(null); mRecentsView.removeOnScrollChangedListener(mOnRecentsScrollListener); @@ -1790,7 +1774,6 @@ public abstract class AbsSwipeUpHandler, mStateCallback.setStateOnUiThread(STATE_SCREENSHOT_CAPTURED); } else { final int runningTaskId = mGestureState.getRunningTaskId(); - final boolean refreshView = !ENABLE_QUICKSTEP_LIVE_TILE.get() /* refreshView */; boolean finishTransitionPosted = false; if (mRecentsAnimationController != null) { // Update the screenshot of the task @@ -1801,14 +1784,14 @@ public abstract class AbsSwipeUpHandler, mRecentsAnimationController.screenshotTask(runningTaskId); MAIN_EXECUTOR.execute(() -> { mTaskSnapshot = taskSnapshot; - if (!updateThumbnail(runningTaskId, refreshView)) { + if (!updateThumbnail(runningTaskId, false /* refreshView */)) { setScreenshotCapturedState(); } }); }); return; } - finishTransitionPosted = updateThumbnail(runningTaskId, refreshView); + finishTransitionPosted = updateThumbnail(runningTaskId, false /* refreshView */); } if (!finishTransitionPosted) { setScreenshotCapturedState(); @@ -1846,17 +1829,9 @@ public abstract class AbsSwipeUpHandler, } private void finishCurrentTransitionToRecents() { - if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { - mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED); - if (mRecentsAnimationController != null) { - mRecentsAnimationController.detachNavigationBarFromApp(true); - } - } else if (!hasTargets() || mRecentsAnimationController == null) { - // If there are no targets or the animation not started, then there is nothing to finish - mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED); - } else { - mRecentsAnimationController.finish(true /* toRecents */, - () -> mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED)); + mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED); + if (mRecentsAnimationController != null) { + mRecentsAnimationController.detachNavigationBarFromApp(true); } ActiveGestureLog.INSTANCE.addLog( /* event= */ "finishRecentsAnimation", @@ -1920,13 +1895,11 @@ public abstract class AbsSwipeUpHandler, } endLauncherTransitionController(); mRecentsView.onSwipeUpAnimationSuccess(); - if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { - mTaskAnimationManager.setLiveTileCleanUpHandler(() -> { - mRecentsView.cleanupRemoteTargets(); - mInputConsumerProxy.destroy(); - }); - mTaskAnimationManager.enableLiveTileRestartListener(); - } + mTaskAnimationManager.setLiveTileCleanUpHandler(() -> { + mRecentsView.cleanupRemoteTargets(); + mInputConsumerProxy.destroy(); + }); + mTaskAnimationManager.enableLiveTileRestartListener(); SystemUiProxy.INSTANCE.get(mContext).onOverviewShown(false, TAG); doLogGesture(RECENTS, mRecentsView.getCurrentPageTaskView()); diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java index 466abbe62f..6e963f3315 100644 --- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java +++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java @@ -15,7 +15,6 @@ */ package com.android.quickstep; -import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.util.NavigationMode.NO_BUTTON; import static com.android.quickstep.fallback.RecentsState.BACKGROUND_APP; import static com.android.quickstep.fallback.RecentsState.DEFAULT; @@ -120,8 +119,7 @@ public final class FallbackActivityInterface extends public RecentsView getVisibleRecentsView() { RecentsActivity activity = getCreatedActivity(); if (activity != null) { - if (activity.hasBeenResumed() - || (ENABLE_QUICKSTEP_LIVE_TILE.get() && isInLiveTileMode())) { + if (activity.hasBeenResumed() || isInLiveTileMode()) { return activity.getOverviewPanel(); } } diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java index 1127e2c8e7..1cb17cb815 100644 --- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java +++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java @@ -21,7 +21,6 @@ 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; @@ -203,8 +202,7 @@ public final class LauncherActivityInterface extends private Launcher getVisibleLauncher() { Launcher launcher = getCreatedActivity(); return (launcher != null) && launcher.isStarted() - && ((ENABLE_QUICKSTEP_LIVE_TILE.get() && isInLiveTileMode()) - || launcher.hasBeenResumed()) ? launcher : null; + && (isInLiveTileMode() || launcher.hasBeenResumed()) ? launcher : null; } @Override @@ -213,7 +211,7 @@ public final class LauncherActivityInterface extends if (launcher == null) { return false; } - if (ENABLE_QUICKSTEP_LIVE_TILE.get() && isInLiveTileMode()) { + if (isInLiveTileMode()) { RecentsView recentsView = getVisibleRecentsView(); if (recentsView == null) { return false; diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java index c879494c7d..4f5e216336 100644 --- a/quickstep/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/src/com/android/quickstep/RecentsActivity.java @@ -18,7 +18,6 @@ package com.android.quickstep; import static com.android.launcher3.QuickstepTransitionManager.RECENTS_LAUNCH_DURATION; import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_DURATION; import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_PRE_DELAY; -import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.graphics.SysUiScrim.SYSUI_PROGRESS; import static com.android.launcher3.testing.shared.TestProtocol.OVERVIEW_STATE_ORDINAL; import static com.android.quickstep.OverviewComponentObserver.startHomeIntentSafely; @@ -393,13 +392,9 @@ public final class RecentsActivity extends StatefulActivity { } public void startHome() { - if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { - RecentsView recentsView = getOverviewPanel(); - recentsView.switchToScreenshot(() -> recentsView.finishRecentsAnimation(true, - this::startHomeInternal)); - } else { - startHomeInternal(); - } + RecentsView recentsView = getOverviewPanel(); + recentsView.switchToScreenshot(() -> recentsView.finishRecentsAnimation(true, + this::startHomeInternal)); } private void startHomeInternal() { diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java index b9a1b0629f..7f1656500a 100644 --- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java +++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java @@ -15,7 +15,6 @@ */ 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; @@ -72,7 +71,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn return; } BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface(); - if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityInterface.isInLiveTileMode() + if (activityInterface.isInLiveTileMode() && activityInterface.getCreatedActivity() != null) { RecentsView recentsView = activityInterface.getCreatedActivity().getOverviewPanel(); if (recentsView != null) { @@ -171,7 +170,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn .map(RemoteAnimationTargetCompat::unwrap) .toArray(RemoteAnimationTarget[]::new)); - if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityInterface.isInLiveTileMode() + if (activityInterface.isInLiveTileMode() && activityInterface.getCreatedActivity() != null) { RecentsView recentsView = activityInterface.getCreatedActivity().getOverviewPanel(); @@ -204,7 +203,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn @Override public boolean onSwitchToScreenshot(Runnable onFinished) { - if (!ENABLE_QUICKSTEP_LIVE_TILE.get() || !activityInterface.isInLiveTileMode() + if (!activityInterface.isInLiveTileMode() || activityInterface.getCreatedActivity() == null) { // No need to switch since tile is already a screenshot. onFinished.run(); @@ -266,7 +265,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn return; } BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface(); - if (ENABLE_QUICKSTEP_LIVE_TILE.get() && activityInterface.isInLiveTileMode() + if (activityInterface.isInLiveTileMode() && activityInterface.getCreatedActivity() != null) { RecentsView recentsView = activityInterface.getCreatedActivity().getOverviewPanel(); if (recentsView != null) { diff --git a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java index e10cab60e0..d40f2ae017 100644 --- a/quickstep/src/com/android/quickstep/TaskOverlayFactory.java +++ b/quickstep/src/com/android/quickstep/TaskOverlayFactory.java @@ -18,7 +18,6 @@ package com.android.quickstep; import static android.view.Surface.ROTATION_0; -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; @@ -174,14 +173,10 @@ public class TaskOverlayFactory implements ResourceBasedOverride { * @param callback callback to run, after switching to screenshot */ public void endLiveTileMode(@NonNull Runnable callback) { - if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { - RecentsView recentsView = mThumbnailView.getTaskView().getRecentsView(); - recentsView.switchToScreenshot( - () -> recentsView.finishRecentsAnimation(true /* toRecents */, - false /* shouldPip */, callback)); - } else { - callback.run(); - } + RecentsView recentsView = mThumbnailView.getTaskView().getRecentsView(); + recentsView.switchToScreenshot( + () -> recentsView.finishRecentsAnimation(true /* toRecents */, + false /* shouldPip */, callback)); } /** diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java index a96524e186..e7173f5c14 100644 --- a/quickstep/src/com/android/quickstep/TaskViewUtils.java +++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java @@ -35,7 +35,6 @@ import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncest import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR; 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.STATE_DEPTH; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING; @@ -637,7 +636,7 @@ public final class TaskViewUtils { }; } pa.add(launcherAnim); - if (ENABLE_QUICKSTEP_LIVE_TILE.get() && recentsView.getRunningTaskIndex() != -1) { + if (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 1999701f61..4476dcb3d8 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -20,7 +20,6 @@ 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.ActiveGestureErrorDetector.GestureEvent.MOTION_DOWN; @@ -955,8 +954,7 @@ public class TouchInteractionService extends Service boolean launcherResumedThroughShellTransition = gestureState.getActivityInterface().isResumed() && !previousGestureState.isRecentsAnimationRunning(); - if (ENABLE_QUICKSTEP_LIVE_TILE.get() - && gestureState.getActivityInterface().isInLiveTileMode()) { + if (gestureState.getActivityInterface().isInLiveTileMode()) { return createOverviewInputConsumer( previousGestureState, gestureState, @@ -1044,8 +1042,7 @@ public class TouchInteractionService extends Service previousGestureState.isRunningAnimationToLauncher(); boolean forcingOverviewInputConsumer = ASSISTANT_GIVES_LAUNCHER_FOCUS.get() && forceOverviewInputConsumer; - boolean isInLiveTileMode = ENABLE_QUICKSTEP_LIVE_TILE.get() - && gestureState.getActivityInterface().isInLiveTileMode(); + boolean isInLiveTileMode = gestureState.getActivityInterface().isInLiveTileMode(); reasonString.append(SUBSTRING_PREFIX) .append(hasWindowFocus ? "activity has window focus" diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java b/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java index eca61bb07d..db4927a0d1 100644 --- a/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java +++ b/quickstep/src/com/android/quickstep/fallback/RecentsTaskController.java @@ -15,8 +15,6 @@ */ package com.android.quickstep.fallback; -import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; - import com.android.launcher3.uioverrides.touchcontrollers.TaskViewTouchController; import com.android.quickstep.RecentsActivity; @@ -28,8 +26,7 @@ public class RecentsTaskController extends TaskViewTouchController, T extends StatefulAct @Override public void onHoverEvent(MotionEvent ev) { - if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { - mActivity.dispatchGenericMotionEvent(ev); - } + mActivity.dispatchGenericMotionEvent(ev); } @Override public void onKeyEvent(KeyEvent ev) { - if (ENABLE_QUICKSTEP_LIVE_TILE.get()) { - switch (ev.getKeyCode()) { - case KeyEvent.KEYCODE_VOLUME_DOWN: - case KeyEvent.KEYCODE_VOLUME_UP: - case KeyEvent.KEYCODE_VOLUME_MUTE: - MediaSessionManager mgr = mActivity.getSystemService(MediaSessionManager.class); - mgr.dispatchVolumeKeyEventAsSystemService(ev, - AudioManager.USE_DEFAULT_STREAM_TYPE); - break; - default: - break; - } - mActivity.dispatchKeyEvent(ev); + switch (ev.getKeyCode()) { + case KeyEvent.KEYCODE_VOLUME_DOWN: + case KeyEvent.KEYCODE_VOLUME_UP: + case KeyEvent.KEYCODE_VOLUME_MUTE: + MediaSessionManager mgr = mActivity.getSystemService(MediaSessionManager.class); + mgr.dispatchVolumeKeyEventAsSystemService(ev, + AudioManager.USE_DEFAULT_STREAM_TYPE); + break; + default: + break; } + mActivity.dispatchKeyEvent(ev); } } diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java index 1a026fc31d..4cdf557e3e 100644 --- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java +++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java @@ -17,7 +17,6 @@ package com.android.quickstep.util; import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; -import static com.android.launcher3.config.FeatureFlags.ENABLE_QUICKSTEP_LIVE_TILE; import static com.android.launcher3.states.RotationHelper.deltaRotation; import static com.android.launcher3.touch.PagedOrientationHandler.MATRIX_POST_TRANSLATE; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; @@ -393,7 +392,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { .withCornerRadius(getCurrentCornerRadius()); // If mDrawsBelowRecents is unset, no reordering will be enforced. - if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mDrawsBelowRecents != null) { + if (mDrawsBelowRecents != null) { // In legacy transitions, the animation leashes remain in same hierarchy in the // TaskDisplayArea, so we don't want to bump the layer too high otherwise it will // conflict with layers that WM core positions (ie. the input consumers). For shell diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 2f91e16566..4fba8d6385 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -41,7 +41,6 @@ import static com.android.launcher3.anim.Interpolators.FINAL_FRAME; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.OVERSHOOT_0_75; 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_OVERVIEW_ACTIONS_SPLIT; 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; @@ -817,8 +816,7 @@ public abstract class RecentsView { - TaskViewSimulator simulator = remoteTargetHandle.getTaskViewSimulator(); - simulator.taskPrimaryTranslation.value = 0; - simulator.taskSecondaryTranslation.value = 0; - simulator.fullScreenProgress.value = 0; - simulator.recentsViewScale.value = 1; - }); - // Similar to setRunningTaskHidden below, reapply the state before runningTaskView is - // null. - if (!mRunningTaskShowScreenshot) { - setRunningTaskViewShowScreenshot(mRunningTaskShowScreenshot); - } + // resetTaskVisuals is called at the end of dismiss animation which could update + // primary and secondary translation of the live tile cut out. We will need to do so + // here accordingly. + runActionOnRemoteHandles(remoteTargetHandle -> { + TaskViewSimulator simulator = remoteTargetHandle.getTaskViewSimulator(); + simulator.taskPrimaryTranslation.value = 0; + simulator.taskSecondaryTranslation.value = 0; + simulator.fullScreenProgress.value = 0; + simulator.recentsViewScale.value = 1; + }); + // Similar to setRunningTaskHidden below, reapply the state before runningTaskView is + // null. + if (!mRunningTaskShowScreenshot) { + setRunningTaskViewShowScreenshot(mRunningTaskShowScreenshot); } if (mRunningTaskTileHidden) { setRunningTaskHidden(mRunningTaskTileHidden); @@ -2036,7 +2032,7 @@ public abstract class RecentsView { runActionOnRemoteHandles( remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator() @@ -3028,8 +3018,7 @@ public abstract class RecentsView { runActionOnRemoteHandles( remoteTargetHandle -> @@ -3123,8 +3112,7 @@ public abstract class RecentsView { runActionOnRemoteHandles( @@ -3247,8 +3235,7 @@ public abstract class RecentsView() { @Override public void accept(Boolean success) { - if (ENABLE_QUICKSTEP_LIVE_TILE.get() && mEnableDrawingLiveTile - && dismissedTaskView.isRunningTask() && success) { + if (mEnableDrawingLiveTile && dismissedTaskView.isRunningTask() && success) { finishRecentsAnimation(true /* toRecents */, false /* shouldPip */, () -> onEnd(success)); } else { @@ -3265,8 +3252,7 @@ public abstract class RecentsView removeTaskInternal(dismissedTaskViewId)); } else { @@ -3925,8 +3911,7 @@ public abstract class RecentsView remoteTargetHandle.getTaskViewSimulator() .taskPrimaryTranslation.value = totalTranslation); @@ -4150,10 +4135,8 @@ public abstract class RecentsView remoteTargetHandle.getTaskViewSimulator() - .addOverviewToAppAnim(mPendingAnimation, interpolator)); - mPendingAnimation.addOnFrameCallback(this::redrawLiveTile); - } + runActionOnRemoteHandles( + remoteTargetHandle -> remoteTargetHandle.getTaskViewSimulator() + .addOverviewToAppAnim(mPendingAnimation, interpolator)); + mPendingAnimation.addOnFrameCallback(this::redrawLiveTile); mPendingAnimation.addEndListener(isSuccess -> { if (isSuccess) { if (tv.getTaskIds()[1] != -1 && mRemoteTargetHandles != null) { @@ -4535,7 +4514,7 @@ public abstract class RecentsView Date: Mon, 5 Sep 2022 16:36:32 +0100 Subject: [PATCH 011/429] Add screenshot test for edit state drop targets. see: go/tapl-run-on-hold-event Bug: 241386128 Test: HomeScreenImageTest.java Change-Id: I5d6421c8da7d06a9eb77da249957c64d413524f1 --- .../launcher3/ui/TaplTestsLauncher3.java | 20 ++++++++++++-- .../tapl/LauncherInstrumentation.java | 25 +++++++++++++++++ .../com/android/launcher3/tapl/Workspace.java | 27 +++++++++++++++++++ 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java index 07bfe4c971..cf5f5fc320 100644 --- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java +++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java @@ -18,8 +18,6 @@ package com.android.launcher3.ui; import static androidx.test.InstrumentationRegistry.getInstrumentation; -import android.platform.test.annotations.IwTest; - import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; @@ -31,6 +29,7 @@ import static org.junit.Assume.assumeTrue; import android.content.Intent; import android.graphics.Point; +import android.platform.test.annotations.IwTest; import androidx.test.filters.LargeTest; import androidx.test.runner.AndroidJUnit4; @@ -435,6 +434,23 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL); } + @Test + @PortraitLandscape + public void testDragAndCancelAppIcon() { + final HomeAppIcon homeAppIcon = createShortcutInCenterIfNotExist(GMAIL_APP_NAME); + Point positionBeforeDrag = + mLauncher.getWorkspace().getWorkspaceIconsPositions().get(GMAIL_APP_NAME); + assertNotNull("App not found in Workspace before dragging.", positionBeforeDrag); + + mLauncher.getWorkspace().dragAndCancelAppIcon(homeAppIcon); + + Point positionAfterDrag = + mLauncher.getWorkspace().getWorkspaceIconsPositions().get(GMAIL_APP_NAME); + assertNotNull("App not found in Workspace after dragging.", positionAfterDrag); + assertEquals("App not returned to same position in Workspace after drag & cancel", + positionBeforeDrag, positionAfterDrag); + } + @Test @PortraitLandscape public void testDeleteFromWorkspace() throws Exception { diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 3986df6508..03ba3b2bf9 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -138,6 +138,15 @@ public final class LauncherInstrumentation { OUTSIDE_WITH_KEYCODE, } + /** + * Represents a point in the code at which a callback can run. + */ + public enum CALLBACK_RUN_POINT { + CALLBACK_HOLD_BEFORE_DROP + } + + private Consumer mCallbackAtRunPoint = null; + // Base class for launcher containers. abstract static class VisibleContainer { protected final LauncherInstrumentation mLauncher; @@ -1935,4 +1944,20 @@ public final class LauncherInstrumentation { LauncherInstrumentation.GestureScope.INSIDE); } } + + /** + * Sets the consumer to run callbacks at all run-points. + */ + public void setRunPointCallback(Consumer callback) { + mCallbackAtRunPoint = callback; + } + + /** + * Runs the callback at the specified point if it exists. + */ + void runCallbackIfActive(CALLBACK_RUN_POINT runPoint) { + if (mCallbackAtRunPoint != null) { + mCallbackAtRunPoint.accept(runPoint); + } + } } diff --git a/tests/tapl/com/android/launcher3/tapl/Workspace.java b/tests/tapl/com/android/launcher3/tapl/Workspace.java index 2c9fdb357e..425a90a988 100644 --- a/tests/tapl/com/android/launcher3/tapl/Workspace.java +++ b/tests/tapl/com/android/launcher3/tapl/Workspace.java @@ -18,6 +18,7 @@ package com.android.launcher3.tapl; import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_SCROLLED; +import static com.android.launcher3.tapl.LauncherInstrumentation.CALLBACK_RUN_POINT.CALLBACK_HOLD_BEFORE_DROP; import static com.android.launcher3.testing.shared.TestProtocol.ALL_APPS_STATE_ORDINAL; import static com.android.launcher3.testing.shared.TestProtocol.NORMAL_STATE_ORDINAL; @@ -301,6 +302,31 @@ public final class Workspace extends Home { targetId).getVisibleCenter(); } + /** + * Drag the appIcon from the workspace and cancel by dragging icon to corner of screen where no + * drop point exists. + * + * @param homeAppIcon to be dragged. + */ + @NonNull + public Workspace dragAndCancelAppIcon(HomeAppIcon homeAppIcon) { + try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck(); + LauncherInstrumentation.Closable c = mLauncher.addContextLayer( + "dragging app icon across workspace")) { + dragIconToWorkspace( + mLauncher, + homeAppIcon, + () -> new Point(0, 0), + () -> mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, LONG_CLICK_EVENT), + null); + + try (LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer( + "dragged the app across workspace")) { + return new Workspace(mLauncher); + } + } + } + /** * Delete the appIcon from the workspace. * @@ -493,6 +519,7 @@ public final class Workspace extends Home { launcher.movePointer(dragStart, targetDest, DEFAULT_DRAG_STEPS, isDecelerating, downTime, SystemClock.uptimeMillis(), false, LauncherInstrumentation.GestureScope.INSIDE); + launcher.runCallbackIfActive(CALLBACK_HOLD_BEFORE_DROP); dropDraggedIcon(launcher, targetDest, downTime, expectDropEvents); } } From c7295ee37a442b5ee386fd877dbd6d2b5f884736 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Tue, 20 Sep 2022 16:21:37 -0700 Subject: [PATCH 012/429] Add margin to SUW back button * navButtonsLayoutParams marginEnd was removed, and SUW was relying on that value to add margins to SUW back button, but was returning 0. Fixes: 242999939 Test: Visually observed in SUW test activity adb shell am start -n com.google.android.setupwizard/.SetupWizardTestActivity Change-Id: I5ffc421e9b731b0d9c7b7c48eab807d4419721b1 --- quickstep/res/values/dimens.xml | 2 +- .../android/launcher3/taskbar/NavbarButtonsViewController.java | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index c85e71cebc..fb78ef76f5 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -258,7 +258,7 @@ 16dp 8dp 44dp - 47dp + 48dp 24dp 35dp 24dp diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index 1c345a6aa4..c27caf1dfe 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -270,7 +270,8 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT // end-aligned, so start-align instead. FrameLayout.LayoutParams navButtonsLayoutParams = (FrameLayout.LayoutParams) mNavButtonContainer.getLayoutParams(); - navButtonsLayoutParams.setMarginStart(navButtonsLayoutParams.getMarginEnd()); + navButtonsLayoutParams.setMarginStart( + resources.getDimensionPixelSize(R.dimen.taskbar_contextual_button_margin)); navButtonsLayoutParams.setMarginEnd(0); navButtonsLayoutParams.gravity = Gravity.START; mNavButtonContainer.requestLayout(); From 7523b94105838d99f2ebaedea35c1e0c88b142a0 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Tue, 20 Sep 2022 16:46:27 -0700 Subject: [PATCH 013/429] Hide back button if IME shows in SUW Fixes: 230830643 Test: Visually see no back button when IME shows up on enter pin screen Change-Id: Icdde92d39962c3891a56bb07de5b16a22635729e --- .../launcher3/taskbar/NavbarButtonsViewController.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index c27caf1dfe..725ce11dd0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -126,7 +126,8 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT public static final int ALPHA_INDEX_IMMERSIVE_MODE = 0; public static final int ALPHA_INDEX_KEYGUARD_OR_DISABLE = 1; - private static final int NUM_ALPHA_CHANNELS = 2; + public static final int ALPHA_INDEX_SUW = 2; + private static final int NUM_ALPHA_CHANNELS = 3; private final ArrayList mPropertyHolders = new ArrayList<>(); private final ArrayList mAllButtons = new ArrayList<>(); @@ -276,6 +277,11 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT navButtonsLayoutParams.gravity = Gravity.START; mNavButtonContainer.requestLayout(); + // Hide back button in SUW if keyboard is showing (IME draws its own back). + mPropertyHolders.add(new StatePropertyHolder( + mBackButtonAlpha.getProperty(ALPHA_INDEX_SUW), + flags -> (flags & FLAG_IME_VISIBLE) == 0)); + // TODO(b/210906568) Dark intensity is currently not propagated during setup, so set // it based on dark theme for now. int mode = resources.getConfiguration().uiMode From 517cafff1827c6ca3ab6d79436fc1a36f20b0fe9 Mon Sep 17 00:00:00 2001 From: Thales Lima Date: Thu, 29 Sep 2022 19:08:02 +0100 Subject: [PATCH 014/429] Check for view measurement before animating Sometimes the view is there but it was not measured yet, and that was making the animation run with wrong icon position values. Fix: 233247401 Test: manual Change-Id: Ibcce24391e99b02ecdb492191c39b62d332abe4f --- .../src/com/android/quickstep/LauncherSwipeHandlerV2.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java index 36ca993f85..d1533f0347 100644 --- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java +++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java @@ -84,7 +84,8 @@ public class LauncherSwipeHandlerV2 extends final View workspaceView = findWorkspaceView(launchCookies, mRecentsView.getRunningTaskView()); - boolean canUseWorkspaceView = workspaceView != null && workspaceView.isAttachedToWindow(); + boolean canUseWorkspaceView = workspaceView != null && workspaceView.isAttachedToWindow() + && workspaceView.getHeight() > 0; mActivity.getRootView().setForceHideBackArrow(true); if (!TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) { From 58bc28114298919af9ef168aed606e1ede279394 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Fri, 30 Sep 2022 18:14:33 +0100 Subject: [PATCH 015/429] Refactor TaskbarLauncherStateController to use a single AnimatedFLoat - Use a single iconAlignment animation - Introduced isInLauncher/goingToLauncher/FLAGS_LAUNCHER as combined FLAG_RESUMED|FLAG_RECENTS_ANIMATION_RUNNING - iconAlignment is now centralized in onStateChangeApplied with single source of truth Bug: 245320601 Test: Home<->Overview, Home<->App, App<->Overview, Home->Overview->App->Home, Home->App->Overview->Home, Overview->Home->App->Overview, Overview->App->Home->Overview, App->Overview->Home->App, App->Home->Overview->App Test: Go to AllApps, call KEYCODE_HOME, go to app and taskbar should be there Test: App->Overview->Select->Home->App Test: QuickSwitch -> App Test: Repeat above with taskbarStashed on/off Test: Repeat above with gesture and 3-button Change-Id: Ie51b602394c155aca060a84585eb0e677e23425c --- .../TaskbarLauncherStateController.java | 292 +++++++----------- .../com/android/quickstep/AnimatedFloat.java | 7 + 2 files changed, 113 insertions(+), 186 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index 58c689bc36..de37b70632 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -50,7 +50,6 @@ import java.io.PrintWriter; import java.util.HashMap; import java.util.StringJoiner; import java.util.function.Consumer; -import java.util.function.Supplier; /** * Track LauncherState, RecentsAnimation, resumed state for task bar in one place here and animate @@ -65,15 +64,12 @@ import java.util.function.Supplier; public static final int FLAG_RECENTS_ANIMATION_RUNNING = 1 << 1; public static final int FLAG_TRANSITION_STATE_RUNNING = 1 << 2; + private static final int FLAGS_LAUNCHER = FLAG_RESUMED | FLAG_RECENTS_ANIMATION_RUNNING; /** Equivalent to an int with all 1s for binary operation purposes */ private static final int FLAGS_ALL = ~0; - private final AnimatedFloat mIconAlignmentForResumedState = - new AnimatedFloat(this::onIconAlignmentRatioChangedForAppAndHomeTransition); - private final AnimatedFloat mIconAlignmentForGestureState = - new AnimatedFloat(this::onIconAlignmentRatioChangedForAppAndHomeTransition); - private final AnimatedFloat mIconAlignmentForLauncherState = - new AnimatedFloat(this::onIconAlignmentRatioChangedForStateTransition); + private final AnimatedFloat mIconAlignment = + new AnimatedFloat(this::onIconAlignmentRatioChanged); private TaskbarControllers mControllers; private AnimatedFloat mTaskbarBackgroundAlpha; @@ -86,8 +82,7 @@ import java.util.function.Supplier; private @Nullable TaskBarRecentsAnimationListener mTaskBarRecentsAnimationListener; - private boolean mIsAnimatingToLauncherViaGesture; - private boolean mIsAnimatingToLauncherViaResume; + private boolean mIsAnimatingToLauncher; private boolean mShouldDelayLauncherStateAnim; @@ -148,8 +143,8 @@ import java.util.function.Supplier; mIconAlphaForHome = taskbarIconAlpha.getProperty(ALPHA_INDEX_HOME); mIconAlphaForHome.setConsumer(mIconAlphaForHomeConsumer); - mIconAlignmentForResumedState.finishAnimation(); - onIconAlignmentRatioChangedForAppAndHomeTransition(); + mIconAlignment.finishAnimation(); + onIconAlignmentRatioChanged(); mLauncher.getStateManager().addStateListener(mStateListener); @@ -165,9 +160,7 @@ import java.util.function.Supplier; public void onDestroy() { mCanSyncViews = false; - mIconAlignmentForResumedState.finishAnimation(); - mIconAlignmentForGestureState.finishAnimation(); - mIconAlignmentForLauncherState.finishAnimation(); + mIconAlignment.finishAnimation(); mIconAlphaForHome.setConsumer(null); mLauncher.getHotseat().setIconsAlpha(1f); @@ -187,6 +180,9 @@ import java.util.function.Supplier; TaskbarStashController stashController = mControllers.taskbarStashController; stashController.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, toState.isTaskbarStashed(mLauncher)); + if (DEBUG) { + Log.d(TAG, "createAnimToLauncher - FLAG_IN_APP: " + false); + } stashController.updateStateForFlag(FLAG_IN_APP, false); updateStateForFlag(FLAG_RECENTS_ANIMATION_RUNNING, true); @@ -201,7 +197,7 @@ import java.util.function.Supplier; } public boolean isAnimatingToLauncher() { - return mIsAnimatingToLauncherViaResume || mIsAnimatingToLauncherViaGesture; + return mIsAnimatingToLauncher; } public void setShouldDelayLauncherStateAnim(boolean shouldDelayLauncherStateAnim) { @@ -261,11 +257,29 @@ import java.util.function.Supplier; } private Animator onStateChangeApplied(int changedFlags, long duration, boolean start) { + boolean goingToLauncher = isInLauncher(); + final float toAlignment; + if (goingToLauncher) { + boolean isInStashedState = mLauncherState.isTaskbarStashed(mLauncher); + boolean willStashVisually = isInStashedState + && mControllers.taskbarStashController.supportsVisualStashing(); + boolean isTaskbarAlignedWithHotseat = + mLauncherState.isTaskbarAlignedWithHotseat(mLauncher); + toAlignment = isTaskbarAlignedWithHotseat && !willStashVisually ? 1 : 0; + } else { + toAlignment = 0; + } + if (DEBUG) { + Log.d(TAG, "onStateChangeApplied - mState: " + getStateString(mState) + + ", changedFlags: " + getStateString(changedFlags) + + ", goingToLauncher: " + goingToLauncher + + ", mLauncherState: " + mLauncherState + + ", toAlignment: " + toAlignment); + } AnimatorSet animatorSet = new AnimatorSet(); // Add the state animation first to ensure FLAG_IN_STASHED_LAUNCHER_STATE is set and we can // determine whether goingToUnstashedLauncherStateChanged. - boolean wasGoingToUnstashedLauncherState = goingToUnstashedLauncherState(); if (hasAnyFlag(changedFlags, FLAG_TRANSITION_STATE_RUNNING)) { boolean committed = !hasAnyFlag(FLAG_TRANSITION_STATE_RUNNING); playStateTransitionAnim(animatorSet, duration, committed); @@ -276,95 +290,69 @@ import java.util.function.Supplier; applyState(0 /* duration */); } } - boolean goingToUnstashedLauncherStateChanged = wasGoingToUnstashedLauncherState - != goingToUnstashedLauncherState(); - boolean launcherStateChangedDuringAnimToResumeAlignment = - mIconAlignmentForResumedState.isAnimating() && goingToUnstashedLauncherStateChanged; - if (hasAnyFlag(changedFlags, FLAG_RESUMED) - || launcherStateChangedDuringAnimToResumeAlignment) { - boolean isResumed = isResumed(); - // If launcher is resumed, we show the icons when going to an unstashed launcher state - // or launcher state is not changed (e.g. in overview, launcher is paused and resumed). - float toAlignmentForResumedState = isResumed && (goingToUnstashedLauncherState() - || !goingToUnstashedLauncherStateChanged) ? 1 : 0; - // If we're already animating to the value, just leave it be instead of restarting it. - if (!mIconAlignmentForResumedState.isAnimatingToValue(toAlignmentForResumedState)) { - ObjectAnimator resumeAlignAnim = mIconAlignmentForResumedState - .animateToValue(toAlignmentForResumedState) - .setDuration(duration); - if (DEBUG) { - Log.d(TAG, "mIconAlignmentForResumedState - " - + mIconAlignmentForResumedState.value - + " -> " + toAlignmentForResumedState + ": " + duration); + if (hasAnyFlag(changedFlags, FLAGS_LAUNCHER)) { + animatorSet.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mIsAnimatingToLauncher = false; } - resumeAlignAnim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mIsAnimatingToLauncherViaResume = false; + @Override + public void onAnimationStart(Animator animation) { + mIsAnimatingToLauncher = goingToLauncher; + + TaskbarStashController stashController = + mControllers.taskbarStashController; + if (DEBUG) { + Log.d(TAG, "onAnimationStart - FLAG_IN_APP: " + !goingToLauncher); } - - @Override - public void onAnimationStart(Animator animation) { - mIsAnimatingToLauncherViaResume = isResumed; - - TaskbarStashController stashController = - mControllers.taskbarStashController; - stashController.updateStateForFlag(FLAG_IN_APP, !isResumed); - stashController.applyState(duration); - } - }); - animatorSet.play(resumeAlignAnim); - } - } - - - boolean launcherStateChangedDuringAnimToGestureAlignment = - mIconAlignmentForGestureState.isAnimating() && goingToUnstashedLauncherStateChanged; - if (hasAnyFlag(changedFlags, FLAG_RECENTS_ANIMATION_RUNNING) - || launcherStateChangedDuringAnimToGestureAlignment) { - boolean isRecentsAnimationRunning = isRecentsAnimationRunning(); - float toAlignmentForGestureState = isRecentsAnimationRunning - && goingToUnstashedLauncherState() ? 1 : 0; - // If we're already animating to the value, just leave it be instead of restarting it. - if (!mIconAlignmentForGestureState.isAnimatingToValue(toAlignmentForGestureState)) { - Animator gestureAlignAnim = mIconAlignmentForGestureState - .animateToValue(toAlignmentForGestureState); - if (isRecentsAnimationRunning) { - gestureAlignAnim.setDuration(duration); + stashController.updateStateForFlag(FLAG_IN_APP, !goingToLauncher); + stashController.applyState(duration); } - if (DEBUG) { - Log.d(TAG, "mIconAlignmentForGestureState - " - + mIconAlignmentForGestureState.value - + " -> " + toAlignmentForGestureState + ": " + duration); - } - gestureAlignAnim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mIsAnimatingToLauncherViaGesture = false; - } + }); - @Override - public void onAnimationStart(Animator animation) { - mIsAnimatingToLauncherViaGesture = isRecentsAnimationRunning(); - } - }); - animatorSet.play(gestureAlignAnim); - } - } - - if (hasAnyFlag(changedFlags, FLAG_RESUMED | FLAG_RECENTS_ANIMATION_RUNNING)) { - boolean goingToLauncher = hasAnyFlag(FLAG_RESUMED | FLAG_RECENTS_ANIMATION_RUNNING); if (goingToLauncher) { // Handle closing open popups when going home/overview AbstractFloatingView.closeAllOpenViews(mControllers.taskbarActivityContext); } - animatorSet.play(mTaskbarBackgroundAlpha.animateToValue(goingToLauncher ? 0 : 1) + } + + float backgroundAlpha = + goingToLauncher && mLauncherState.isTaskbarAlignedWithHotseat(mLauncher) + ? 0 : 1; + // Don't animate if background has reached desired value. + if (mTaskbarBackgroundAlpha.isAnimating() + || mTaskbarBackgroundAlpha.value != backgroundAlpha) { + mTaskbarBackgroundAlpha.cancelAnimation(); + if (DEBUG) { + Log.d(TAG, "onStateChangeApplied - taskbarBackgroundAlpha - " + + mTaskbarBackgroundAlpha.value + + " -> " + backgroundAlpha + ": " + duration); + } + animatorSet.play(mTaskbarBackgroundAlpha.animateToValue(backgroundAlpha) .setDuration(duration)); } + if (mIconAlignment.isAnimatingToValue(toAlignment) + || mIconAlignment.isSettledOnValue(toAlignment)) { + // Already at desired value, but make sure we run the callback at the end. + animatorSet.addListener(AnimatorListeners.forEndCallback( + this::onIconAlignmentRatioChanged)); + } else { + mIconAlignment.cancelAnimation(); + ObjectAnimator iconAlignAnim = mIconAlignment + .animateToValue(toAlignment) + .setDuration(duration); + if (DEBUG) { + Log.d(TAG, "onStateChangeApplied - iconAlignment - " + + mIconAlignment.value + + " -> " + toAlignment + ": " + duration); + } + animatorSet.play(iconAlignAnim); + } animatorSet.setInterpolator(EMPHASIZED); + if (start) { animatorSet.start(); } @@ -372,18 +360,13 @@ import java.util.function.Supplier; } /** Returns whether we're going to a state where taskbar icons should align with launcher. */ - private boolean goingToUnstashedLauncherState() { - return !mControllers.taskbarStashController.isInStashedLauncherState(); + public boolean goingToAlignedLauncherState() { + return mLauncherState.isTaskbarAlignedWithHotseat(mLauncher); } private void playStateTransitionAnim(AnimatorSet animatorSet, long duration, boolean committed) { boolean isInStashedState = mLauncherState.isTaskbarStashed(mLauncher); - boolean willStashVisually = - isInStashedState && mControllers.taskbarStashController.supportsVisualStashing(); - float toAlignment = - mLauncherState.isTaskbarAlignedWithHotseat(mLauncher) && !willStashVisually ? 1 : 0; - TaskbarStashController stashController = mControllers.taskbarStashController; stashController.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, isInStashedState); Animator stashAnimator = stashController.applyStateWithoutStart(duration); @@ -406,55 +389,23 @@ import java.util.function.Supplier; }); animatorSet.play(stashAnimator); } - if (mIconAlignmentForLauncherState.value == toAlignment) { - // Already at expected value, but make sure we run the callback at the end. - animatorSet.addListener(AnimatorListeners.forEndCallback( - this::onIconAlignmentRatioChangedForStateTransition)); - } - if (!mIconAlignmentForLauncherState.isAnimatingToValue(toAlignment)) { - // If we're already animating to the value, just leave it be instead of restarting it. - mIconAlignmentForLauncherState.finishAnimation(); - animatorSet.play(mIconAlignmentForLauncherState.animateToValue(toAlignment) - .setDuration(duration)); - if (DEBUG) { - Log.d(TAG, "mIconAlignmentForLauncherState - " - + mIconAlignmentForLauncherState.value - + " -> " + toAlignment + ": " + duration); - } - animatorSet.setInterpolator(EMPHASIZED); - } } - private boolean isResumed() { - return (mState & FLAG_RESUMED) != 0; + private boolean isInLauncher() { + return (mState & FLAGS_LAUNCHER) != 0; } - private boolean isRecentsAnimationRunning() { - return (mState & FLAG_RECENTS_ANIMATION_RUNNING) != 0; - } - - private void onIconAlignmentRatioChangedForStateTransition() { - if (!isResumed() && mTaskBarRecentsAnimationListener == null) { - return; - } - onIconAlignmentRatioChanged(this::getCurrentIconAlignmentRatioForLauncherState); - } - - private void onIconAlignmentRatioChangedForAppAndHomeTransition() { - onIconAlignmentRatioChanged(this::getCurrentIconAlignmentRatioBetweenAppAndHome); - } - - private void onIconAlignmentRatioChanged(Supplier alignmentSupplier) { - if (mControllers == null) { - return; - } - AnimatedFloat animatedFloat = alignmentSupplier.get(); + private void onIconAlignmentRatioChanged() { float currentValue = mIconAlphaForHome.getValue(); - boolean taskbarWillBeVisible = animatedFloat.value < 1; + boolean taskbarWillBeVisible = mIconAlignment.value < 1; boolean firstFrameVisChanged = (taskbarWillBeVisible && Float.compare(currentValue, 1) != 0) || (!taskbarWillBeVisible && Float.compare(currentValue, 0) != 0); - updateIconAlignment(animatedFloat.value, animatedFloat.getEndValue()); + mControllers.taskbarViewController.setLauncherIconAlignment( + mIconAlignment.value, mIconAlignment.getEndValue(), mLauncher.getDeviceProfile()); + mControllers.navbarButtonsViewController.updateTaskbarAlignment(mIconAlignment.value); + // Switch taskbar and hotseat in last frame + mIconAlphaForHome.setValue(taskbarWillBeVisible ? 1 : 0); // Sync the first frame where we swap taskbar and hotseat. if (firstFrameVisChanged && mCanSyncViews && !Utilities.IS_RUNNING_IN_TEST_HARNESS) { @@ -464,28 +415,6 @@ import java.util.function.Supplier; } } - private void updateIconAlignment(float alignment, Float endAlignment) { - mControllers.taskbarViewController.setLauncherIconAlignment( - alignment, endAlignment, mLauncher.getDeviceProfile()); - - // Switch taskbar and hotseat in last frame - setTaskbarViewVisible(alignment < 1); - mControllers.navbarButtonsViewController.updateTaskbarAlignment(alignment); - } - - private AnimatedFloat getCurrentIconAlignmentRatioBetweenAppAndHome() { - return mIconAlignmentForResumedState.value > mIconAlignmentForGestureState.value - ? mIconAlignmentForResumedState : mIconAlignmentForGestureState; - } - - private AnimatedFloat getCurrentIconAlignmentRatioForLauncherState() { - return mIconAlignmentForLauncherState; - } - - private void setTaskbarViewVisible(boolean isVisible) { - mIconAlphaForHome.setValue(isVisible ? 1 : 0); - } - private final class TaskBarRecentsAnimationListener implements RecentsAnimationCallbacks.RecentsAnimationListener { private final RecentsAnimationCallbacks mCallbacks; @@ -515,11 +444,11 @@ import java.util.function.Supplier; updateStateForFlag(FLAG_RECENTS_ANIMATION_RUNNING, false); updateStateForFlag(FLAG_RESUMED, launcherResumed); applyState(); - // Set this last because applyState() might also animate it. - mIconAlignmentForResumedState.cancelAnimation(); - mIconAlignmentForResumedState.updateValue(launcherResumed ? 1 : 0); TaskbarStashController controller = mControllers.taskbarStashController; + if (DEBUG) { + Log.d(TAG, "endGestureStateOverride - FLAG_IN_APP: " + finishedToApp); + } controller.updateStateForFlag(FLAG_IN_APP, finishedToApp); controller.applyState(); } @@ -527,29 +456,24 @@ import java.util.function.Supplier; private static String getStateString(int flags) { StringJoiner str = new StringJoiner("|"); - str.add((flags & FLAG_RESUMED) != 0 ? "FLAG_RESUMED" : ""); - str.add((flags & FLAG_RECENTS_ANIMATION_RUNNING) != 0 - ? "FLAG_RECENTS_ANIMATION_RUNNING" : ""); - str.add((flags & FLAG_TRANSITION_STATE_RUNNING) != 0 - ? "FLAG_TRANSITION_STATE_RUNNING" : ""); + if ((flags & FLAG_RESUMED) != 0) { + str.add("FLAG_RESUMED"); + } + if ((flags & FLAG_RECENTS_ANIMATION_RUNNING) != 0) { + str.add("FLAG_RECENTS_ANIMATION_RUNNING"); + } + if ((flags & FLAG_TRANSITION_STATE_RUNNING) != 0) { + str.add("FLAG_TRANSITION_STATE_RUNNING"); + } return str.toString(); } protected void dumpLogs(String prefix, PrintWriter pw) { pw.println(prefix + "TaskbarLauncherStateController:"); - pw.println(String.format( - "%s\tmIconAlignmentForResumedState=%.2f", + "%s\tmIconAlignment=%.2f", prefix, - mIconAlignmentForResumedState.value)); - pw.println(String.format( - "%s\tmIconAlignmentForGestureState=%.2f", - prefix, - mIconAlignmentForGestureState.value)); - pw.println(String.format( - "%s\tmIconAlignmentForLauncherState=%.2f", - prefix, - mIconAlignmentForLauncherState.value)); + mIconAlignment.value)); pw.println(String.format( "%s\tmTaskbarBackgroundAlpha=%.2f", prefix, mTaskbarBackgroundAlpha.value)); pw.println(String.format( @@ -558,13 +482,9 @@ import java.util.function.Supplier; pw.println(String.format("%s\tmState=%s", prefix, getStateString(mState))); pw.println(String.format("%s\tmLauncherState=%s", prefix, mLauncherState)); pw.println(String.format( - "%s\tmIsAnimatingToLauncherViaGesture=%b", + "%s\tmIsAnimatingToLauncher=%b", prefix, - mIsAnimatingToLauncherViaGesture)); - pw.println(String.format( - "%s\tmIsAnimatingToLauncherViaResume=%b", - prefix, - mIsAnimatingToLauncherViaResume)); + mIsAnimatingToLauncher)); pw.println(String.format( "%s\tmShouldDelayLauncherStateAnim=%b", prefix, mShouldDelayLauncherStateAnim)); } diff --git a/quickstep/src/com/android/quickstep/AnimatedFloat.java b/quickstep/src/com/android/quickstep/AnimatedFloat.java index a1665530a3..b06b894c6e 100644 --- a/quickstep/src/com/android/quickstep/AnimatedFloat.java +++ b/quickstep/src/com/android/quickstep/AnimatedFloat.java @@ -134,6 +134,13 @@ public class AnimatedFloat { return isAnimating() && mEndValue != null && mEndValue == endValue; } + /** + * Returns whether we are currently not animating, and the animation's value matches the given. + */ + public boolean isSettledOnValue(float endValue) { + return !isAnimating() && value == endValue; + } + /** * Returns the value we are animating to, or {@code null} if we are not currently animating. */ From b759de4769a02811e2fffd977aefd160ee3341f4 Mon Sep 17 00:00:00 2001 From: Stefan Andonian Date: Wed, 28 Sep 2022 20:48:24 +0000 Subject: [PATCH 016/429] Fix ViewCapture NPE. The ViewPropertyRefs, when copied from 1 frame to another, where also transferring the same "next" reference. Sometimes, the recycled ViewPropertyRef would be the same ViewPropertyRef instance as one of the copied ViewPropertyRefs, which would caused an NPE, since the recycled VPR would have it's next value set to null. Bug: 249125402 Test: Repro steps are dragging and dropping around an item on the workspace to different locations. This consistently repro's the crash in about 10 seconds of doing this. Afte the fix, the crash stopped. Change-Id: Ia43d8f788eb4889c0890fea0bb839cb9fed78ada --- quickstep/src/com/android/quickstep/util/ViewCapture.java | 1 - 1 file changed, 1 deletion(-) diff --git a/quickstep/src/com/android/quickstep/util/ViewCapture.java b/quickstep/src/com/android/quickstep/util/ViewCapture.java index cfcfce0b6a..6171c5dbea 100644 --- a/quickstep/src/com/android/quickstep/util/ViewCapture.java +++ b/quickstep/src/com/android/quickstep/util/ViewCapture.java @@ -421,7 +421,6 @@ public class ViewCapture { out.visibility = this.visibility; out.willNotDraw = this.willNotDraw; out.clipChildren = this.clipChildren; - out.next = this.next; out.elevation = this.elevation; } From d67ddc4920d79b06f0ec56a5ea8083a7863ae4d1 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Fri, 30 Sep 2022 18:15:56 +0100 Subject: [PATCH 017/429] Taskbar in overview - Behind ENABLE_TASKBAR_IN_OVERVIEW which is disabled by defualt - Make taskbar unstashed in overview with background visible - Ensure taskbar is touchable in overview Bug: 245320601 Test: Home<->Overview, Home<->App, App<->Overview, Home->Overview->App->Home, Home->App->Overview->Home, Overview->Home->App->Overview, Overview->App->Home->Overview, App->Overview->Home->App, App->Home->Overview->App Test: Go to AllApps, call KEYCODE_HOME, go to app and taskbar should be there Test: App->Overview->Select->Home->App Test: QuickSwitch -> App Test: Repeat above with ENABLE_TASKBAR_IN_OVERVIEW x taskbarStashed on/off Test: Repeat above with gesture and 3-button Change-Id: Ib25d68f68e89564851b226536e456d0b2f6306f8 --- .../taskbar/LauncherTaskbarUIController.java | 15 +++++++++++---- .../uioverrides/states/OverviewState.java | 8 +++++++- src/com/android/launcher3/DeviceProfile.java | 6 +++++- .../android/launcher3/config/FeatureFlags.java | 4 ++++ 4 files changed, 27 insertions(+), 6 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index a219ac6324..5178968b4a 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -38,6 +38,7 @@ import com.android.launcher3.LauncherState; import com.android.launcher3.QuickstepTransitionManager; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.logging.InstanceId; import com.android.launcher3.logging.InstanceIdSequence; import com.android.launcher3.model.data.ItemInfo; @@ -116,7 +117,8 @@ public class LauncherTaskbarUIController extends TaskbarUIController { @Override protected boolean isTaskbarTouchable() { - return !mTaskbarLauncherStateController.isAnimatingToLauncher(); + return !(mTaskbarLauncherStateController.isAnimatingToLauncher() + && mTaskbarLauncherStateController.goingToAlignedLauncherState()); } public void setShouldDelayLauncherStateAnim(boolean shouldDelayLauncherStateAnim) { @@ -291,9 +293,14 @@ public class LauncherTaskbarUIController extends TaskbarUIController { @Override public void setSystemGestureInProgress(boolean inProgress) { super.setSystemGestureInProgress(inProgress); - // Launcher's ScrimView will draw the background throughout the gesture. But once the - // gesture ends, start drawing taskbar's background again since launcher might stop drawing. - forceHideBackground(inProgress); + // TODO(b/250645563): Don't show round corners when leaving in-app state, and remove + // forceHideBackground call entirely. + if (!FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get()) { + // Launcher's ScrimView will draw the background throughout the gesture. But once the + // gesture ends, start drawing taskbar's background again since launcher might stop + // drawing. + forceHideBackground(inProgress); + } } /** diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java index 6f07568cf5..d075750330 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java @@ -26,6 +26,7 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.R; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.Themes; import com.android.quickstep.util.LayoutUtils; @@ -104,7 +105,12 @@ public class OverviewState extends LauncherState { @Override public boolean isTaskbarStashed(Launcher launcher) { - return true; + return !FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get(); + } + + @Override + public boolean isTaskbarAlignedWithHotseat(Launcher launcher) { + return !FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get(); } @Override diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 4cad919c3b..9a1bba97ce 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -43,6 +43,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.CellLayout.ContainerType; import com.android.launcher3.DevicePaddings.DevicePadding; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.icons.DotRenderer; import com.android.launcher3.icons.IconNormalizer; import com.android.launcher3.model.data.ItemInfo; @@ -1276,7 +1277,10 @@ public class DeviceProfile { return ((taskbarSize - overviewActionsHeight) / 2) + getTaskbarOffsetY(); } - return isTaskbarPresent ? stashedTaskbarSize : mInsets.bottom; + if (isTaskbarPresent) { + return FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get() ? taskbarSize : stashedTaskbarSize; + } + return mInsets.bottom; } /** Gets the space that the overview actions will take, including bottom margin. */ diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 50cf8d67f9..868ff46a90 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -238,6 +238,10 @@ public final class FeatureFlags { "ENABLE_ALL_APPS_ONE_SEARCH_IN_TASKBAR", false, "Enables One Search box in Taskbar All Apps."); + public static final BooleanFlag ENABLE_TASKBAR_IN_OVERVIEW = getDebugFlag( + "ENABLE_TASKBAR_IN_OVERVIEW", false, + "Enables accessing the system Taskbar in overview."); + public static final BooleanFlag ENABLE_SPLIT_FROM_WORKSPACE = getDebugFlag( "ENABLE_SPLIT_FROM_WORKSPACE", true, "Enable initiating split screen from workspace."); From 86065b81e00995f8699775bbf4904747fcc255d9 Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Mon, 3 Oct 2022 12:21:41 -0700 Subject: [PATCH 018/429] Fix animation slowdown when splitting from All Apps This patch fixes a tablet bug related to splitting from All Apps. Splitting from AllApps was playing a very slow animation. The bug occurred because there was no case set in QuickstepAtomicAnimationFactory for animating from the ALL_APPS state. Fixed by setting the appropriate case in QuickstepAtomicAnimationFactory. Fixes: 247053528 Test: Manual Change-Id: I7391dc7049a6ff5a7f8c7e1ae8b69e29899248fa --- .../uioverrides/states/QuickstepAtomicAnimationFactory.java | 3 ++- quickstep/src/com/android/quickstep/views/RecentsView.java | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java index bcd722f4e3..da07edf9bf 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/QuickstepAtomicAnimationFactory.java @@ -197,7 +197,8 @@ public class QuickstepAtomicAnimationFactory extends config.setInterpolator(ANIM_OVERVIEW_ACTIONS_FADE, clampToProgress(LINEAR, timings.getActionsFadeStartOffset(), timings.getActionsFadeEndOffset())); - } else if (fromState == NORMAL && toState == OVERVIEW_SPLIT_SELECT) { + } else if ((fromState == NORMAL || fromState == ALL_APPS) + && toState == OVERVIEW_SPLIT_SELECT) { // Splitting from Home is currently only available on tablets SplitAnimationTimings timings = SplitAnimationTimings.TABLET_HOME_TO_SPLIT; config.setInterpolator(ANIM_SCRIM_FADE, clampToProgress(LINEAR, diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 2f91e16566..1f601df162 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -4156,6 +4156,9 @@ public abstract class RecentsView Date: Mon, 3 Oct 2022 22:22:08 +0000 Subject: [PATCH 019/429] Updating launcher for pip interface cleanup Bug: 238217847 Test: atest WMShellUnitTests Change-Id: I375e67eeb07ffe50bf15eafb65c1e9d215118c73 --- .../android/quickstep/AbsSwipeUpHandler.java | 4 +-- .../com/android/quickstep/SystemUiProxy.java | 35 +++++++++---------- .../android/quickstep/views/RecentsView.java | 6 ++-- 3 files changed, 22 insertions(+), 23 deletions(-) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index f3630c187b..5837525506 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -1010,8 +1010,8 @@ public abstract class AbsSwipeUpHandler, switch (endTarget) { case HOME: mStateCallback.setState(STATE_SCALED_CONTROLLER_HOME | STATE_CAPTURE_SCREENSHOT); - // Notify swipe-to-home (recents animation) is finished - SystemUiProxy.INSTANCE.get(mContext).notifySwipeToHomeFinished(); + // Notify the SysUI to use fade-in animation when entering PiP + SystemUiProxy.INSTANCE.get(mContext).setPipAnimationTypeToAlpha(); break; case RECENTS: mStateCallback.setState(STATE_SCALED_CONTROLLER_RECENTS | STATE_CAPTURE_SCREENSHOT diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index 3b2df315b1..35d73946f3 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -187,7 +187,7 @@ public class SystemUiProxy implements ISystemUiProxy { linkToDeath(); // re-attach the listeners once missing due to setProxy has not been initialized yet. if (mPipAnimationListener != null && mPip != null) { - setPinnedStackAnimationListener(mPipAnimationListener); + setPipAnimationListener(mPipAnimationListener); } if (mSplitScreenListener != null && mSplitScreen != null) { registerSplitScreenListener(mSplitScreenListener); @@ -357,20 +357,6 @@ public class SystemUiProxy implements ISystemUiProxy { } } - /** - * Notifies that swipe-to-home action is finished. - */ - @Override - public void notifySwipeToHomeFinished() { - if (mSystemUiProxy != null) { - try { - mSystemUiProxy.notifySwipeToHomeFinished(); - } catch (RemoteException e) { - Log.w(TAG, "Failed call notifySwipeToHomeFinished", e); - } - } - } - @Override public void notifyPrioritizedRotation(int rotation) { if (mSystemUiProxy != null) { @@ -475,12 +461,12 @@ public class SystemUiProxy implements ISystemUiProxy { } /** - * Sets listener to get pinned stack animation callbacks. + * Sets listener to get pip animation callbacks. */ - public void setPinnedStackAnimationListener(IPipAnimationListener listener) { + public void setPipAnimationListener(IPipAnimationListener listener) { if (mPip != null) { try { - mPip.setPinnedStackAnimationListener(listener); + mPip.setPipAnimationListener(listener); } catch (RemoteException e) { Log.w(TAG, "Failed call setPinnedStackAnimationListener", e); } @@ -522,6 +508,19 @@ public class SystemUiProxy implements ISystemUiProxy { } } + /** + * Sets the next pip animation type to be the alpha animation. + */ + public void setPipAnimationTypeToAlpha() { + if (mPip != null) { + try { + mPip.setPipAnimationTypeToAlpha(); + } catch (RemoteException e) { + Log.w(TAG, "Failed call setPipAnimationTypeToAlpha", e); + } + } + } + // // Splitscreen // diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 2f91e16566..3a118210ad 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -941,7 +941,7 @@ public abstract class RecentsView Date: Mon, 3 Oct 2022 17:46:03 -0700 Subject: [PATCH 020/429] Include additional error log around widget removal As observed in b/248291728, widgets are disappeared after OTA update, this CL includes additional logging to reveal more information. Bug: 248291728 Test: manual Change-Id: I5cf968efc358c3315e5e6ecc4861d5bc888569f1 --- src/com/android/launcher3/LauncherProvider.java | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java index a20ff8c06f..58e85fea7e 100644 --- a/src/com/android/launcher3/LauncherProvider.java +++ b/src/com/android/launcher3/LauncherProvider.java @@ -85,6 +85,7 @@ import java.util.Arrays; import java.util.Locale; import java.util.concurrent.TimeUnit; import java.util.function.Supplier; +import java.util.stream.Collectors; public class LauncherProvider extends ContentProvider { private static final String TAG = "LauncherProvider"; @@ -944,16 +945,28 @@ public class LauncherProvider extends ContentProvider { final IntSet validWidgets = IntSet.wrap(LauncherDbUtils.queryIntArray(false, db, Favorites.TABLE_NAME, Favorites.APPWIDGET_ID, "itemType=" + Favorites.ITEM_TYPE_APPWIDGET, null, null)); + boolean isAnyWidgetRemoved = false; for (int widgetId : allWidgets) { if (!validWidgets.contains(widgetId)) { try { FileLog.d(TAG, "Deleting invalid widget " + widgetId); host.deleteAppWidgetId(widgetId); + isAnyWidgetRemoved = true; } catch (RuntimeException e) { // Ignore } } } + if (isAnyWidgetRemoved) { + final String allWidgetsIds = Arrays.stream(allWidgets).mapToObj(String::valueOf) + .collect(Collectors.joining(",", "[", "]")); + final String validWidgetsIds = Arrays.stream( + validWidgets.getArray().toArray()).mapToObj(String::valueOf) + .collect(Collectors.joining(",", "[", "]")); + FileLog.d(TAG, "One or more widgets was removed. db_path=" + db.getPath() + + " allWidgetsIds=" + allWidgetsIds + + ", validWidgetsIds=" + validWidgetsIds); + } } /** From e5a49f4b48c0ae1403ecdd793164cefe78c389c7 Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Mon, 3 Oct 2022 14:47:07 -0700 Subject: [PATCH 021/429] Hide FloatingHeaderView while in Search state. This prevents touches on the profile buttons (which were already hidden due to the header view having alpha 0, but touches were still registered). Fix: 248338523 Test: Manually tap where the work profile button is before and after this change. Before: switches to work profile. Afer: does nothing in 0 state; otherwise launches item at that position. Change-Id: Ie30661146d25740000d7a9cbe79234ac15347253 --- src/com/android/launcher3/allapps/BaseAllAppsContainerView.java | 2 ++ .../android/launcher3/allapps/SearchTransitionController.java | 1 + 2 files changed, 3 insertions(+) diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java index f08254204e..c717310659 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java @@ -532,9 +532,11 @@ public abstract class BaseAllAppsContainerView Date: Wed, 7 Sep 2022 17:35:01 +0100 Subject: [PATCH 022/429] Use wm shell splash screen animation to reveal app after tasks have appeared. Bug: 202826469 Test: manual Change-Id: I6a9e8a932849c30f7b572119a7f607178b5a6437 --- quickstep/res/values/dimens.xml | 5 ++ .../android/quickstep/AbsSwipeUpHandler.java | 73 +++++++++++++++++-- .../quickstep/views/TaskThumbnailView.java | 2 +- .../com/android/quickstep/views/TaskView.java | 5 +- 4 files changed, 74 insertions(+), 11 deletions(-) diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index c85e71cebc..d2d1f52116 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -283,4 +283,9 @@ 47dp 47dp 47dp + + + + + 20dp diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index f3630c187b..d68db579cc 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -76,6 +76,7 @@ import android.util.Log; import android.view.MotionEvent; import android.view.View; import android.view.View.OnApplyWindowInsetsListener; +import android.view.ViewGroup; import android.view.ViewTreeObserver.OnDrawListener; import android.view.ViewTreeObserver.OnScrollChangedListener; import android.view.WindowInsets; @@ -128,12 +129,17 @@ import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; +import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; +import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; +import com.android.wm.shell.common.TransactionPool; +import com.android.wm.shell.startingsurface.SplashScreenExitAnimationUtils; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.Optional; import java.util.function.Consumer; /** @@ -249,6 +255,13 @@ public abstract class AbsSwipeUpHandler, private static final float MAX_QUICK_SWITCH_RECENTS_SCALE_PROGRESS = 0.07f; + // Controls task thumbnail splash's reveal animation after landing on a task from quickswitch. + // These values match WindowManager/Shell starting_window_app_reveal_* config values. + private static final int SPLASH_FADE_OUT_DURATION = 133; + private static final int SPLASH_APP_REVEAL_DELAY = 83; + private static final int SPLASH_APP_REVEAL_DURATION = 266; + private static final int SPLASH_ANIMATION_DURATION = 349; + /** * Used as the page index for logging when we return to the last task at the end of the gesture. */ @@ -286,6 +299,8 @@ public abstract class AbsSwipeUpHandler, private final long mTouchTimeMs; private long mLauncherFrameDrawnTime; + private final int mSplashMainWindowShiftLength; + private final Runnable mOnDeferredActivityLaunch = this::onDeferredActivityLaunch; private SwipePipToHomeAnimator mSwipePipToHomeAnimator; @@ -321,6 +336,9 @@ public abstract class AbsSwipeUpHandler, mQuickSwitchScaleScrollThreshold = context.getResources().getDimension( R.dimen.quick_switch_scaling_scroll_threshold); + mSplashMainWindowShiftLength = -context.getResources().getDimensionPixelSize( + R.dimen.starting_surface_exit_animation_window_shift_length); + initAfterSubclassConstructor(); initStateCallbacks(); } @@ -2061,16 +2079,59 @@ public abstract class AbsSwipeUpHandler, public void onTasksAppeared(RemoteAnimationTargetCompat[] appearedTaskTargets) { if (mRecentsAnimationController != null) { if (handleTaskAppeared(appearedTaskTargets)) { - mRecentsAnimationController.finish(false /* toRecents */, - null /* onFinishComplete */); - ActiveGestureLog.INSTANCE.addLog( - /* event= */ "finishRecentsAnimation", - /* extras= */ false, - /* gestureEvent= */ FINISH_RECENTS_ANIMATION); + Optional taskTargetOptional = + Arrays.stream(appearedTaskTargets) + .filter(targetCompat -> + targetCompat.taskId == mGestureState.getLastStartedTaskId()) + .findFirst(); + if (!taskTargetOptional.isPresent()) { + finishRecentsAnimationOnTasksAppeared(); + return; + } + RemoteAnimationTargetCompat taskTarget = taskTargetOptional.get(); + TaskView taskView = mRecentsView.getTaskViewByTaskId(taskTarget.taskId); + if (taskView == null || !taskView.getThumbnail().shouldShowSplashView()) { + finishRecentsAnimationOnTasksAppeared(); + return; + } + + ViewGroup splashView = mActivity.getDragLayer(); + + // When revealing the app with launcher splash screen, make the app visible + // and behind the splash view before the splash is animated away. + SyncRtSurfaceTransactionApplierCompat surfaceApplier = + new SyncRtSurfaceTransactionApplierCompat(splashView); + ArrayList params = new ArrayList<>(); + for (RemoteAnimationTargetCompat target : appearedTaskTargets) { + SurfaceParams.Builder builder = new SurfaceParams.Builder(target.leash); + builder.withAlpha(1); + builder.withLayer(-1); + params.add(builder.build()); + } + surfaceApplier.scheduleApply(params.toArray(new SurfaceParams[0])); + + SplashScreenExitAnimationUtils.startAnimations(splashView, taskTarget.leash, + mSplashMainWindowShiftLength, new TransactionPool(), new Rect(), + SPLASH_ANIMATION_DURATION, SPLASH_FADE_OUT_DURATION, + /* iconStartAlpha= */ 0, /* brandingStartAlpha= */ 0, + SPLASH_APP_REVEAL_DELAY, SPLASH_APP_REVEAL_DURATION, + new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + finishRecentsAnimationOnTasksAppeared(); + } + }); } } } + private void finishRecentsAnimationOnTasksAppeared() { + if (mRecentsAnimationController != null) { + mRecentsAnimationController.finish(false /* toRecents */, null /* onFinishComplete */); + } + ActiveGestureLog.INSTANCE.addLog("finishRecentsAnimation", false); + } + /** * @return The index of the TaskView in RecentsView whose taskId matches the task that will * resume if we finish the controller. diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java index d7a8599eae..1e044dbc7d 100644 --- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java +++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java @@ -373,7 +373,7 @@ public class TaskThumbnailView extends View { *

We want to show the splash if the aspect ratio or rotation of the thumbnail would be * different from the task. */ - boolean shouldShowSplashView() { + public boolean shouldShowSplashView() { return isThumbnailAspectRatioDifferentFromThumbnailData() || isThumbnailRotationDifferentFromTask(); } diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index a81f95f3ac..25cc28fd50 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -18,7 +18,6 @@ package com.android.quickstep.views; import static android.view.Display.DEFAULT_DISPLAY; import static android.widget.Toast.LENGTH_SHORT; -import static android.window.SplashScreen.SPLASH_SCREEN_STYLE_SOLID_COLOR; import static com.android.launcher3.Utilities.comp; import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor; @@ -667,9 +666,7 @@ public class TaskView extends FrameLayout implements Reusable { if (freezeTaskList) { opts.setFreezeRecentTasksReordering(); } - // TODO(b/202826469): Replace setSplashScreenStyle with setDisableStartingWindow. - opts.setSplashScreenStyle(mSnapshotView.shouldShowSplashView() - ? SPLASH_SCREEN_STYLE_SOLID_COLOR : opts.getSplashScreenStyle()); + opts.setDisableStartingWindow(mSnapshotView.shouldShowSplashView()); Task.TaskKey key = mTask.key; UI_HELPER_EXECUTOR.execute(() -> { if (!ActivityManagerWrapper.getInstance().startActivityFromRecents(key, opts)) { From e3f95693efb6293c53e5608f769068dc78f2cdd5 Mon Sep 17 00:00:00 2001 From: Jerry Chang Date: Tue, 4 Oct 2022 10:29:49 +0000 Subject: [PATCH 023/429] Remove stage concept from split screen APIs Since split screen has transferred from stage-based model to app-pair model. Update to remove the stage concept from split screen APIs, so the caller won't need to deal with stage concept. Bug: 250875492 Test: atest WMShellFlickerTests Test: manual check start tasks or start intent/shortcut with task flow Change-Id: I36bfb54f3f690cfafd18ba31ab23f5745ead6d97 --- .../com/android/quickstep/SystemUiProxy.java | 36 +++++++++---------- .../util/SplitSelectStateController.java | 28 ++++++--------- 2 files changed, 28 insertions(+), 36 deletions(-) diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index 3b2df315b1..7186de702b 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -549,15 +549,15 @@ public class SystemUiProxy implements ISystemUiProxy { } /** Start multiple tasks in split-screen simultaneously. */ - public void startTasks(int mainTaskId, Bundle mainOptions, int sideTaskId, Bundle sideOptions, - @SplitConfigurationOptions.StagePosition int sidePosition, float splitRatio, + public void startTasks(int taskId1, Bundle options1, int taskId2, Bundle options2, + @SplitConfigurationOptions.StagePosition int splitPosition, float splitRatio, RemoteTransitionCompat remoteTransition, InstanceId instanceId) { if (mSystemUiProxy != null) { try { - mSplitScreen.startTasks(mainTaskId, mainOptions, sideTaskId, sideOptions, - sidePosition, splitRatio, remoteTransition.getTransition(), instanceId); + mSplitScreen.startTasks(taskId1, options1, taskId2, options2, splitPosition, + splitRatio, remoteTransition.getTransition(), instanceId); } catch (RemoteException e) { - Log.w(TAG, "Failed call startTask"); + Log.w(TAG, "Failed call startTasks"); } } } @@ -565,13 +565,13 @@ public class SystemUiProxy implements ISystemUiProxy { /** * Start multiple tasks in split-screen simultaneously. */ - public void startTasksWithLegacyTransition(int mainTaskId, Bundle mainOptions, int sideTaskId, - Bundle sideOptions, @SplitConfigurationOptions.StagePosition int sidePosition, + public void startTasksWithLegacyTransition(int taskId1, Bundle options1, int taskId2, + Bundle options2, @SplitConfigurationOptions.StagePosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { if (mSystemUiProxy != null) { try { - mSplitScreen.startTasksWithLegacyTransition(mainTaskId, mainOptions, sideTaskId, - sideOptions, sidePosition, splitRatio, adapter, instanceId); + mSplitScreen.startTasksWithLegacyTransition(taskId1, options1, taskId2, options2, + splitPosition, splitRatio, adapter, instanceId); } catch (RemoteException e) { Log.w(TAG, "Failed call startTasksWithLegacyTransition"); } @@ -579,28 +579,26 @@ public class SystemUiProxy implements ISystemUiProxy { } public void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, - Intent fillInIntent, int taskId, Bundle mainOptions, Bundle sideOptions, - @SplitConfigurationOptions.StagePosition int sidePosition, float splitRatio, + Intent fillInIntent, Bundle options1, int taskId, Bundle options2, + @SplitConfigurationOptions.StagePosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { if (mSystemUiProxy != null) { try { mSplitScreen.startIntentAndTaskWithLegacyTransition(pendingIntent, fillInIntent, - taskId, mainOptions, sideOptions, sidePosition, splitRatio, adapter, - instanceId); + options1, taskId, options2, splitPosition, splitRatio, adapter, instanceId); } catch (RemoteException e) { Log.w(TAG, "Failed call startIntentAndTaskWithLegacyTransition"); } } } - public void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo, int taskId, - Bundle mainOptions, Bundle sideOptions, - @SplitConfigurationOptions.StagePosition int sidePosition, float splitRatio, - RemoteAnimationAdapter adapter, InstanceId instanceId) { + public void startShortcutAndTaskWithLegacyTransition(ShortcutInfo shortcutInfo, Bundle options1, + int taskId, Bundle options2, @SplitConfigurationOptions.StagePosition int splitPosition, + float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { if (mSystemUiProxy != null) { try { - mSplitScreen.startShortcutAndTaskWithLegacyTransition(shortcutInfo, taskId, - mainOptions, sideOptions, sidePosition, splitRatio, adapter, instanceId); + mSplitScreen.startShortcutAndTaskWithLegacyTransition(shortcutInfo, options1, + taskId, options2, splitPosition, splitRatio, adapter, instanceId); } catch (RemoteException e) { Log.w(TAG, "Failed call startShortcutAndTaskWithLegacyTransition"); } diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java index efbe783125..19709d80b8 100644 --- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java @@ -22,8 +22,6 @@ import static android.app.PendingIntent.FLAG_MUTABLE; import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.SplitConfigurationOptions.DEFAULT_SPLIT_RATIO; -import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; -import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT; import android.annotation.NonNull; import android.app.ActivityOptions; @@ -216,16 +214,12 @@ public class SplitSelectStateController { @Nullable InstanceId shellInstanceId) { TestLogging.recordEvent( TestProtocol.SEQUENCE_MAIN, "launchSplitTasks"); - // Assume initial task is for top/left part of screen - final int[] taskIds = stagePosition == STAGE_POSITION_TOP_OR_LEFT - ? new int[]{taskId1, taskId2} - : new int[]{taskId2, taskId1}; if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) { RemoteSplitLaunchTransitionRunner animationRunner = new RemoteSplitLaunchTransitionRunner(taskId1, taskPendingIntent, taskId2, callback); - mSystemUiProxy.startTasks(taskIds[0], null /* mainOptions */, taskIds[1], - null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT, splitRatio, + mSystemUiProxy.startTasks(taskId1, null /* options1 */, taskId2, + null /* options2 */, stagePosition, splitRatio, new RemoteTransitionCompat(animationRunner, MAIN_EXECUTOR, ActivityThread.currentActivityThread().getApplicationThread()), shellInstanceId); @@ -239,24 +233,24 @@ public class SplitSelectStateController { 300, 150, ActivityThread.currentActivityThread().getApplicationThread()); - ActivityOptions mainOpts = ActivityOptions.makeBasic(); + ActivityOptions options1 = ActivityOptions.makeBasic(); if (freezeTaskList) { - mainOpts.setFreezeRecentTasksReordering(); + options1.setFreezeRecentTasksReordering(); } if (taskPendingIntent == null) { - mSystemUiProxy.startTasksWithLegacyTransition(taskIds[0], mainOpts.toBundle(), - taskIds[1], null /* sideOptions */, STAGE_POSITION_BOTTOM_OR_RIGHT, - splitRatio, adapter, shellInstanceId); + mSystemUiProxy.startTasksWithLegacyTransition(taskId1, options1.toBundle(), + taskId2, null /* options2 */, stagePosition, splitRatio, adapter, + shellInstanceId); } else { final ShortcutInfo shortcutInfo = getShortcutInfo(mInitialTaskIntent, taskPendingIntent.getCreatorUserHandle()); if (shortcutInfo != null) { - mSystemUiProxy.startShortcutAndTaskWithLegacyTransition(shortcutInfo, taskId2, - mainOpts.toBundle(), null /* sideOptions */, stagePosition, splitRatio, - adapter, shellInstanceId); + mSystemUiProxy.startShortcutAndTaskWithLegacyTransition(shortcutInfo, + options1.toBundle(), taskId2, null /* options2 */, stagePosition, + splitRatio, adapter, shellInstanceId); } else { mSystemUiProxy.startIntentAndTaskWithLegacyTransition(taskPendingIntent, - fillInIntent, taskId2, mainOpts.toBundle(), null /* sideOptions */, + fillInIntent, options1.toBundle(), taskId2, null /* options2 */, stagePosition, splitRatio, adapter, shellInstanceId); } } From 4d4f62ac77dff74a6c3d57da7eff8d8dad9bf923 Mon Sep 17 00:00:00 2001 From: Ming-Shin Lu Date: Thu, 15 Sep 2022 09:36:45 +0800 Subject: [PATCH 024/429] TAPL: add setIgnoreTaskbarVisibility in LauncherInstrumentation As now FlickerTests is leveraging TAPL to interact devices CUJs, we realized in LauncherInstrumentation will verify task bar visibility automatically to expect it always visible when quick-switch, which is not always reliable since the task bar may be hidden by manual or when the activity requests to show IME. Add setIgnoreTaskbarVisibility in LauncherInstrumentation for the caller to ignore taskbar visibility if the test does not need to verify it. Bug: 228012334 Bug: 240306344 Test: atest FlickerTests:SwitchImeWindowsFromGestureNavTest in tablet device Test: atest NexusLauncherOutOfProcTests:com.android.quickstep.\ TaplTestsQuickstep#testQuickSwitchToPreviousAppForTablet Change-Id: Id0a35561523d733b8434acb702ec7dcaa466a1c2 --- .../android/quickstep/TaplTestsQuickstep.java | 22 +++++++++++++++ tests/Android.bp | 1 + tests/AndroidManifest-common.xml | 10 +++++++ .../testcomponent/BaseTestingActivity.java | 16 +++++++++++ .../testcomponent/ImeTestActivity.java | 27 +++++++++++++++++++ .../launcher3/ui/AbstractLauncherUiTest.java | 10 +++++++ .../android/launcher3/tapl/Background.java | 19 +++++++++---- .../launcher3/tapl/LaunchedAppState.java | 10 +++++++ .../tapl/LauncherInstrumentation.java | 18 ++++++++++++- 9 files changed, 127 insertions(+), 6 deletions(-) create mode 100644 tests/src/com/android/launcher3/testcomponent/ImeTestActivity.java diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java index 42e9be32e3..cc561c6c23 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java @@ -309,6 +309,28 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest { launchedAppState.switchToOverview(); } + @Test + @ScreenRecord // b/242163205 + public void testQuickSwitchToPreviousAppForTablet() throws Exception { + assumeTrue(mLauncher.isTablet()); + startTestActivity(2); + startImeTestActivity(); + + // Set ignoreTaskbarVisibility to true to verify the task bar visibility explicitly. + mLauncher.setIgnoreTaskbarVisibility(true); + + // Expect task bar invisible when the launched app was the IME activity. + LaunchedAppState launchedAppState = getAndAssertLaunchedApp(); + launchedAppState.assertTaskbarHidden(); + + // Quick-switch to the test app with swiping to right. + launchedAppState.quickSwitchToPreviousApp(); + + // Expect task bar visible when the launched app was the test activity. + launchedAppState = getAndAssertLaunchedApp(); + launchedAppState.assertTaskbarVisible(); + } + private boolean isTestActivityRunning(int activityNumber) { return mDevice.wait(Until.hasObject(By.pkg(getAppPackageName()) .text("TestActivity" + activityNumber)), diff --git a/tests/Android.bp b/tests/Android.bp index 1584308091..39bd3074a3 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -60,6 +60,7 @@ filegroup { "src/com/android/launcher3/testcomponent/CustomShortcutConfigActivity.java", "src/com/android/launcher3/testcomponent/TestCommandReceiver.java", "src/com/android/launcher3/testcomponent/TestLauncherActivity.java", + "src/com/android/launcher3/testcomponent/ImeTestActivity.java", ], } diff --git a/tests/AndroidManifest-common.xml b/tests/AndroidManifest-common.xml index 9cc3aeda1f..ae1060ec92 100644 --- a/tests/AndroidManifest-common.xml +++ b/tests/AndroidManifest-common.xml @@ -277,6 +277,16 @@ + + + + + + + mDiagnosticContext = new LinkedList<>(); private Function mSystemHealthSupplier; + private boolean mIgnoreTaskbarVisibility = false; + private Consumer mOnSettledStateAction; private LogEventChecker mEventChecker; private boolean mCheckEventsForSuccessfulGestures = false; private Runnable mOnLauncherCrashed; - private static Pattern getTouchEventPattern(String prefix, String action) { // The pattern includes checks that we don't get a multi-touch events or other surprises. return Pattern.compile( @@ -680,6 +681,18 @@ public final class LauncherInstrumentation { } } + /** + * Whether to ignore verifying the task bar visibility during instrumenting. + * + * @param ignoreTaskbarVisibility {@code true} will ignore the instrumentation implicitly + * verifying the task bar visibility with + * {@link VisibleContainer#verifyActiveContainer}. + * {@code false} otherwise. + */ + public void setIgnoreTaskbarVisibility(boolean ignoreTaskbarVisibility) { + mIgnoreTaskbarVisibility = ignoreTaskbarVisibility; + } + public void setExpectedRotation(int expectedRotation) { mExpectedRotation = expectedRotation; } @@ -798,6 +811,9 @@ public final class LauncherInstrumentation { waitUntilLauncherObjectGone(WIDGETS_RES_ID); waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); + if (mIgnoreTaskbarVisibility) { + return null; + } if (isTablet() && !isFallbackOverview()) { waitForLauncherObject(TASKBAR_RES_ID); } else { From 3d39bfcda7ea6011994da019a5e9e06b3dda3413 Mon Sep 17 00:00:00 2001 From: Jerry Chang Date: Tue, 4 Oct 2022 14:41:26 +0000 Subject: [PATCH 025/429] Support starts a pair of intent/shortcut and task to split Add startIntentAndTask and startShortcutAndTask APIs to support starts a pair of intent/shortcut and task to split with shell-transition. Fix: 250875492 Test: atest WMShellFlickerTests Test: manual check start tasks or start intent/shortcut with task flow with shell-transition enabled Change-Id: Ibce60f3a10e2bbc99ef17185f45680dc23ef5f48 --- .../com/android/quickstep/SystemUiProxy.java | 28 ++++++++++++++ .../com/android/quickstep/TaskViewUtils.java | 7 ++-- .../util/SplitSelectStateController.java | 38 +++++++++++++------ 3 files changed, 58 insertions(+), 15 deletions(-) diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index 7186de702b..a07feff8d1 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -562,6 +562,34 @@ public class SystemUiProxy implements ISystemUiProxy { } } + public void startIntentAndTask(PendingIntent pendingIntent, Intent fillInIntent, + Bundle options1, int taskId, Bundle options2, + @SplitConfigurationOptions.StagePosition int splitPosition, float splitRatio, + RemoteTransitionCompat remoteTransition, InstanceId instanceId) { + if (mSystemUiProxy != null) { + try { + mSplitScreen.startIntentAndTask(pendingIntent, fillInIntent, options1, + taskId, options2, splitPosition, splitRatio, + remoteTransition.getTransition(), instanceId); + } catch (RemoteException e) { + Log.w(TAG, "Failed call startIntentAndTask"); + } + } + } + + public void startShortcutAndTask(ShortcutInfo shortcutInfo, Bundle options1, int taskId, + Bundle options2, @SplitConfigurationOptions.StagePosition int splitPosition, + float splitRatio, RemoteTransitionCompat remoteTransition, InstanceId instanceId) { + if (mSystemUiProxy != null) { + try { + mSplitScreen.startShortcutAndTask(shortcutInfo, options1, taskId, options2, + splitPosition, splitRatio, remoteTransition.getTransition(), instanceId); + } catch (RemoteException e) { + Log.w(TAG, "Failed call startShortcutAndTask"); + } + } + } + /** * Start multiple tasks in split-screen simultaneously. */ diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java index a96524e186..73e9a28438 100644 --- a/quickstep/src/com/android/quickstep/TaskViewUtils.java +++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java @@ -15,7 +15,6 @@ */ package com.android.quickstep; -import static android.app.ActivityTaskManager.INVALID_TASK_ID; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.TRANSIT_OPEN; import static android.view.WindowManager.TRANSIT_TO_FRONT; @@ -426,8 +425,10 @@ public final class TaskViewUtils { TransitionInfo.Change splitRoot2 = null; for (int i = 0; i < transitionInfo.getChanges().size(); ++i) { final TransitionInfo.Change change = transitionInfo.getChanges().get(i); - final int taskId = change.getTaskInfo() != null ? change.getTaskInfo().taskId : -1; + if (change.getTaskInfo() == null) continue; + final int taskId = change.getTaskInfo().taskId; final int mode = change.getMode(); + // Find the target tasks' root tasks since those are the split stages that need to // be animated (the tasks themselves are children and thus inherit animation). if (taskId == initialTaskId || taskId == secondTaskId) { @@ -440,7 +441,7 @@ public final class TaskViewUtils { + "root of " + taskId + " is already visible or has broken hierarchy."); } } - if (taskId == initialTaskId && initialTaskId != INVALID_TASK_ID) { + if (taskId == initialTaskId) { splitRoot1 = transitionInfo.getChange(change.getParent()); } if (taskId == secondTaskId) { diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java index 19709d80b8..f07f9903c2 100644 --- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java @@ -214,18 +214,36 @@ public class SplitSelectStateController { @Nullable InstanceId shellInstanceId) { TestLogging.recordEvent( TestProtocol.SEQUENCE_MAIN, "launchSplitTasks"); + final ActivityOptions options1 = ActivityOptions.makeBasic(); + if (freezeTaskList) { + options1.setFreezeRecentTasksReordering(); + } if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) { - RemoteSplitLaunchTransitionRunner animationRunner = + final RemoteSplitLaunchTransitionRunner animationRunner = new RemoteSplitLaunchTransitionRunner(taskId1, taskPendingIntent, taskId2, callback); - mSystemUiProxy.startTasks(taskId1, null /* options1 */, taskId2, - null /* options2 */, stagePosition, splitRatio, - new RemoteTransitionCompat(animationRunner, MAIN_EXECUTOR, - ActivityThread.currentActivityThread().getApplicationThread()), - shellInstanceId); - // TODO(b/237635859): handle intent/shortcut + task with shell transition + final RemoteTransitionCompat remoteTransition = new RemoteTransitionCompat( + animationRunner, MAIN_EXECUTOR, + ActivityThread.currentActivityThread().getApplicationThread()); + if (taskPendingIntent == null) { + mSystemUiProxy.startTasks(taskId1, options1.toBundle(), taskId2, + null /* options2 */, stagePosition, splitRatio, remoteTransition, + shellInstanceId); + } else { + final ShortcutInfo shortcutInfo = getShortcutInfo(mInitialTaskIntent, + taskPendingIntent.getCreatorUserHandle()); + if (shortcutInfo != null) { + mSystemUiProxy.startShortcutAndTask(shortcutInfo, + options1.toBundle(), taskId2, null /* options2 */, stagePosition, + splitRatio, remoteTransition, shellInstanceId); + } else { + mSystemUiProxy.startIntentAndTask(taskPendingIntent, + fillInIntent, options1.toBundle(), taskId2, null /* options2 */, + stagePosition, splitRatio, remoteTransition, shellInstanceId); + } + } } else { - RemoteSplitLaunchAnimationRunner animationRunner = + final RemoteSplitLaunchAnimationRunner animationRunner = new RemoteSplitLaunchAnimationRunner(taskId1, taskPendingIntent, taskId2, callback); final RemoteAnimationAdapter adapter = new RemoteAnimationAdapter( @@ -233,10 +251,6 @@ public class SplitSelectStateController { 300, 150, ActivityThread.currentActivityThread().getApplicationThread()); - ActivityOptions options1 = ActivityOptions.makeBasic(); - if (freezeTaskList) { - options1.setFreezeRecentTasksReordering(); - } if (taskPendingIntent == null) { mSystemUiProxy.startTasksWithLegacyTransition(taskId1, options1.toBundle(), taskId2, null /* options2 */, stagePosition, splitRatio, adapter, From 0d3c3d8fc551cab0fad8a47375898bcbf5acd3cf Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Wed, 5 Oct 2022 00:57:09 -0700 Subject: [PATCH 026/429] Differentiate between app row and shortcut icons. This is a simplified version of ag/20118087. It fixes the bug with rows of shortcuts being in the search results (e.g. Gmail and WhatsApp conversations), but it will not handle cases where there are multiple rows of app icons. Currently I do not know of any cases where that would happen. Test: Manual with and without inject_web_top (which moves app row) for WhatsApp and Gmail with AiAi fishfood. Bug: 239927522 Change-Id: Ie9c62c0ee81086801942328c8770f37d5bf622c3 --- .../launcher3/allapps/SearchTransitionController.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/allapps/SearchTransitionController.java b/src/com/android/launcher3/allapps/SearchTransitionController.java index a1f5bc696f..11ceb0a55c 100644 --- a/src/com/android/launcher3/allapps/SearchTransitionController.java +++ b/src/com/android/launcher3/allapps/SearchTransitionController.java @@ -20,6 +20,7 @@ import static android.view.View.VISIBLE; import static androidx.recyclerview.widget.RecyclerView.NO_POSITION; +import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; import static com.android.launcher3.anim.AnimatorListeners.forEndCallback; import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback; import static com.android.launcher3.anim.Interpolators.DEACCEL_1_7; @@ -38,6 +39,7 @@ import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.model.data.ItemInfo; /** Coordinates the transition between Search and A-Z in All Apps. */ public class SearchTransitionController { @@ -186,7 +188,9 @@ public class SearchTransitionController { top = searchResultView.getTop(); } - if (searchResultView instanceof BubbleTextView) { + if (searchResultView instanceof BubbleTextView + && searchResultView.getTag() instanceof ItemInfo + && ((ItemInfo) searchResultView.getTag()).itemType == ITEM_TYPE_APPLICATION) { // The first app icon will set appRowHeight, which will also contribute to // totalHeight. Additional app icons should remove the appRowHeight to remain in // the same row as the first app. @@ -196,6 +200,8 @@ public class SearchTransitionController { totalHeight += appRowHeight; } // Don't scale/fade app row. + searchResultView.setScaleY(1); + searchResultView.setAlpha(1); continue; } From cbfb35edc7fffd3b41eff3f62e23a4b5aa4a7d3e Mon Sep 17 00:00:00 2001 From: Nick Chameyev Date: Fri, 23 Sep 2022 12:04:18 +0100 Subject: [PATCH 027/429] Extract PreviewPositionHelper to shared library Moves Launcher's PreviewPositionHelper to shared library between SystemUI and Launcher to reuse it in the future in the partial screensharing recents selector. There should be no functional changes in the code itself. Bug: 240924926 Test: presubmit Change-Id: Ib38b6f9db91e63a2598bf81229e3cd3e1a49ca60 --- .../quickstep/util/TaskViewSimulator.java | 8 +- .../quickstep/views/TaskThumbnailView.java | 217 +----------------- .../com/android/quickstep/views/TaskView.java | 14 +- ...iewTest.kt => FullscreenDrawParamsTest.kt} | 32 ++- src/com/android/launcher3/Utilities.java | 10 - 5 files changed, 51 insertions(+), 230 deletions(-) rename quickstep/tests/src/com/android/quickstep/{TaskThumbnailViewTest.kt => FullscreenDrawParamsTest.kt} (64%) diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java index 4cdf557e3e..c03aa3f446 100644 --- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java +++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java @@ -46,9 +46,9 @@ import com.android.launcher3.util.TraceHelper; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.BaseActivityInterface; import com.android.quickstep.TaskAnimationManager; -import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper; import com.android.quickstep.views.TaskView.FullscreenDrawParams; import com.android.systemui.shared.recents.model.ThumbnailData; +import com.android.systemui.shared.recents.utilities.PreviewPositionHelper; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder; @@ -317,9 +317,9 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { // mIsRecentsRtl is the inverse of TaskView RTL. boolean isRtlEnabled = !mIsRecentsRtl; mPositionHelper.updateThumbnailMatrix( - mThumbnailPosition, mThumbnailData, - mTaskRect.width(), mTaskRect.height(), - mDp, mOrientationState.getRecentsActivityRotation(), isRtlEnabled); + mThumbnailPosition, mThumbnailData, mTaskRect.width(), mTaskRect.height(), + mDp.widthPx, mDp.taskbarSize, mDp.isTablet, + mOrientationState.getRecentsActivityRotation(), isRtlEnabled); mPositionHelper.getMatrix().invert(mInversePositionMatrix); if (DEBUG) { Log.d(TAG, " taskRect: " + mTaskRect); diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java index 43d38a7304..04a0af15c5 100644 --- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java +++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java @@ -16,10 +16,12 @@ package com.android.quickstep.views; -import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_NAVIGATION_BARS; import static android.view.WindowInsetsController.APPEARANCE_LIGHT_STATUS_BARS; +import static com.android.systemui.shared.recents.utilities.PreviewPositionHelper.MAX_PCT_BEFORE_ASPECT_RATIOS_CONSIDERED_DIFFERENT; +import static com.android.systemui.shared.recents.utilities.Utilities.isRelativePercentDifferenceGreaterThan; + import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapShader; @@ -39,7 +41,6 @@ import android.os.Build; import android.util.AttributeSet; import android.util.FloatProperty; import android.util.Property; -import android.view.Surface; import android.view.View; import android.widget.ImageView; @@ -58,6 +59,7 @@ import com.android.quickstep.TaskOverlayFactory.TaskOverlay; import com.android.quickstep.views.TaskView.FullscreenDrawParams; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; +import com.android.systemui.shared.recents.utilities.PreviewPositionHelper; /** * A task in the Recents view. @@ -65,7 +67,6 @@ import com.android.systemui.shared.recents.model.ThumbnailData; public class TaskThumbnailView extends View { private static final MainThreadInitializedObject TEMP_PARAMS = new MainThreadInitializedObject<>(FullscreenDrawParams::new); - private static final float MAX_PCT_BEFORE_ASPECT_RATIOS_CONSIDERED_DIFFERENT = 0.1f; public static final Property DIM_ALPHA = new FloatProperty("dimAlpha") { @@ -417,7 +418,7 @@ public class TaskThumbnailView extends View { float thumbnailDataAspect = mThumbnailData.thumbnail.getWidth() / (float) mThumbnailData.thumbnail.getHeight(); - return Utilities.isRelativePercentDifferenceGreaterThan(thumbnailViewAspect, + return isRelativePercentDifferenceGreaterThan(thumbnailViewAspect, thumbnailDataAspect, MAX_PCT_BEFORE_ASPECT_RATIOS_CONSIDERED_DIFFERENT); } @@ -441,8 +442,8 @@ public class TaskThumbnailView extends View { */ private void refreshOverlay() { if (mOverlayEnabled) { - getTaskOverlay().initOverlay(mTask, mThumbnailData, mPreviewPositionHelper.mMatrix, - mPreviewPositionHelper.mIsOrientationChanged); + getTaskOverlay().initOverlay(mTask, mThumbnailData, mPreviewPositionHelper.getMatrix(), + mPreviewPositionHelper.isOrientationChanged()); } else { getTaskOverlay().reset(); } @@ -463,18 +464,19 @@ public class TaskThumbnailView extends View { } private void updateThumbnailMatrix() { - mPreviewPositionHelper.mIsOrientationChanged = false; + mPreviewPositionHelper.setOrientationChanged(false); if (mBitmapShader != null && mThumbnailData != null) { mPreviewRect.set(0, 0, mThumbnailData.thumbnail.getWidth(), mThumbnailData.thumbnail.getHeight()); int currentRotation = getTaskView().getRecentsView().getPagedViewOrientedState() .getRecentsActivityRotation(); boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; + DeviceProfile dp = mActivity.getDeviceProfile(); mPreviewPositionHelper.updateThumbnailMatrix(mPreviewRect, mThumbnailData, - getMeasuredWidth(), getMeasuredHeight(), mActivity.getDeviceProfile(), - currentRotation, isRtl); + getMeasuredWidth(), getMeasuredHeight(), dp.widthPx, dp.taskbarSize, + dp.isTablet, currentRotation, isRtl); - mBitmapShader.setLocalMatrix(mPreviewPositionHelper.mMatrix); + mBitmapShader.setLocalMatrix(mPreviewPositionHelper.getMatrix()); mPaint.setShader(mBitmapShader); } getTaskView().updateCurrentFullscreenParams(mPreviewPositionHelper); @@ -514,199 +516,4 @@ public class TaskThumbnailView extends View { } return mThumbnailData.isRealSnapshot && !mTask.isLocked; } - - /** - * Utility class to position the thumbnail in the TaskView - */ - public static class PreviewPositionHelper { - - private static final RectF EMPTY_RECT_F = new RectF(); - - // Contains the portion of the thumbnail that is unclipped when fullscreen progress = 1. - private final RectF mClippedInsets = new RectF(); - private final Matrix mMatrix = new Matrix(); - private boolean mIsOrientationChanged; - - public Matrix getMatrix() { - return mMatrix; - } - - /** - * Updates the matrix based on the provided parameters - */ - public void updateThumbnailMatrix(Rect thumbnailBounds, ThumbnailData thumbnailData, - int canvasWidth, int canvasHeight, DeviceProfile dp, int currentRotation, - boolean isRtl) { - boolean isRotated = false; - boolean isOrientationDifferent; - - int thumbnailRotation = thumbnailData.rotation; - int deltaRotate = getRotationDelta(currentRotation, thumbnailRotation); - RectF thumbnailClipHint = new RectF(); - float canvasScreenRatio = canvasWidth / (float) dp.widthPx; - float scaledTaskbarSize = dp.taskbarSize * canvasScreenRatio; - thumbnailClipHint.bottom = dp.isTablet ? scaledTaskbarSize : 0; - - float scale = thumbnailData.scale; - final float thumbnailScale; - - // Landscape vs portrait change. - // Note: Disable rotation in grid layout. - boolean windowingModeSupportsRotation = - thumbnailData.windowingMode == WINDOWING_MODE_FULLSCREEN && !dp.isTablet; - isOrientationDifferent = isOrientationChange(deltaRotate) - && windowingModeSupportsRotation; - if (canvasWidth == 0 || canvasHeight == 0 || scale == 0) { - // If we haven't measured , skip the thumbnail drawing and only draw the background - // color - thumbnailScale = 0f; - } else { - // Rotate the screenshot if not in multi-window mode - isRotated = deltaRotate > 0 && windowingModeSupportsRotation; - - float surfaceWidth = thumbnailBounds.width() / scale; - float surfaceHeight = thumbnailBounds.height() / scale; - float availableWidth = surfaceWidth - - (thumbnailClipHint.left + thumbnailClipHint.right); - float availableHeight = surfaceHeight - - (thumbnailClipHint.top + thumbnailClipHint.bottom); - - float canvasAspect = canvasWidth / (float) canvasHeight; - float availableAspect = isRotated - ? availableHeight / availableWidth - : availableWidth / availableHeight; - boolean isAspectLargelyDifferent = - Utilities.isRelativePercentDifferenceGreaterThan(canvasAspect, - availableAspect, MAX_PCT_BEFORE_ASPECT_RATIOS_CONSIDERED_DIFFERENT); - if (isRotated && isAspectLargelyDifferent) { - // Do not rotate thumbnail if it would not improve fit - isRotated = false; - isOrientationDifferent = false; - } - - if (isAspectLargelyDifferent) { - // Crop letterbox insets if insets isn't already clipped - thumbnailClipHint.left = thumbnailData.letterboxInsets.left; - thumbnailClipHint.right = thumbnailData.letterboxInsets.right; - thumbnailClipHint.top = thumbnailData.letterboxInsets.top; - thumbnailClipHint.bottom = thumbnailData.letterboxInsets.bottom; - availableWidth = surfaceWidth - - (thumbnailClipHint.left + thumbnailClipHint.right); - availableHeight = surfaceHeight - - (thumbnailClipHint.top + thumbnailClipHint.bottom); - } - - final float targetW, targetH; - if (isOrientationDifferent) { - targetW = canvasHeight; - targetH = canvasWidth; - } else { - targetW = canvasWidth; - targetH = canvasHeight; - } - float targetAspect = targetW / targetH; - - // Update the clipHint such that - // > the final clipped position has same aspect ratio as requested by canvas - // > first fit the width and crop the extra height - // > if that will leave empty space, fit the height and crop the width instead - float croppedWidth = availableWidth; - float croppedHeight = croppedWidth / targetAspect; - if (croppedHeight > availableHeight) { - croppedHeight = availableHeight; - if (croppedHeight < targetH) { - croppedHeight = Math.min(targetH, surfaceHeight); - } - croppedWidth = croppedHeight * targetAspect; - - // One last check in case the task aspect radio messed up something - if (croppedWidth > surfaceWidth) { - croppedWidth = surfaceWidth; - croppedHeight = croppedWidth / targetAspect; - } - } - - // Update the clip hints. Align to 0,0, crop the remaining. - if (isRtl) { - thumbnailClipHint.left += availableWidth - croppedWidth; - if (thumbnailClipHint.right < 0) { - thumbnailClipHint.left += thumbnailClipHint.right; - thumbnailClipHint.right = 0; - } - } else { - thumbnailClipHint.right += availableWidth - croppedWidth; - if (thumbnailClipHint.left < 0) { - thumbnailClipHint.right += thumbnailClipHint.left; - thumbnailClipHint.left = 0; - } - } - thumbnailClipHint.bottom += availableHeight - croppedHeight; - if (thumbnailClipHint.top < 0) { - thumbnailClipHint.bottom += thumbnailClipHint.top; - thumbnailClipHint.top = 0; - } else if (thumbnailClipHint.bottom < 0) { - thumbnailClipHint.top += thumbnailClipHint.bottom; - thumbnailClipHint.bottom = 0; - } - - thumbnailScale = targetW / (croppedWidth * scale); - } - - if (!isRotated) { - mMatrix.setTranslate( - -thumbnailClipHint.left * scale, - -thumbnailClipHint.top * scale); - } else { - setThumbnailRotation(deltaRotate, thumbnailBounds); - } - - mClippedInsets.set(0, 0, 0, scaledTaskbarSize); - - mMatrix.postScale(thumbnailScale, thumbnailScale); - mIsOrientationChanged = isOrientationDifferent; - } - - private int getRotationDelta(int oldRotation, int newRotation) { - int delta = newRotation - oldRotation; - if (delta < 0) delta += 4; - return delta; - } - - /** - * @param deltaRotation the number of 90 degree turns from the current orientation - * @return {@code true} if the change in rotation results in a shift from landscape to - * portrait or vice versa, {@code false} otherwise - */ - private boolean isOrientationChange(int deltaRotation) { - return deltaRotation == Surface.ROTATION_90 || deltaRotation == Surface.ROTATION_270; - } - - private void setThumbnailRotation(int deltaRotate, Rect thumbnailPosition) { - float translateX = 0; - float translateY = 0; - - mMatrix.setRotate(90 * deltaRotate); - switch (deltaRotate) { /* Counter-clockwise */ - case Surface.ROTATION_90: - translateX = thumbnailPosition.height(); - break; - case Surface.ROTATION_270: - translateY = thumbnailPosition.width(); - break; - case Surface.ROTATION_180: - translateX = thumbnailPosition.width(); - translateY = thumbnailPosition.height(); - break; - } - mMatrix.postTranslate(translateX, translateY); - } - - /** - * Insets to used for clipping the thumbnail (in case it is drawing outside its own space) - */ - public RectF getInsetsToDrawInFullscreen(DeviceProfile dp) { - return dp.isTaskbarPresent && !dp.isTaskbarPresentInApps - ? mClippedInsets : EMPTY_RECT_F; - } - } } diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index 07d8989858..0125775684 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -98,9 +98,9 @@ import com.android.quickstep.util.RecentsOrientedState; import com.android.quickstep.util.SplitSelectStateController; import com.android.quickstep.util.TaskCornerRadius; import com.android.quickstep.util.TransformParams; -import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; +import com.android.systemui.shared.recents.utilities.PreviewPositionHelper; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; @@ -121,6 +121,8 @@ public class TaskView extends FrameLayout implements Reusable { private static final String TAG = TaskView.class.getSimpleName(); private static final boolean DEBUG = false; + private static final RectF EMPTY_RECT_F = new RectF(); + public static final int FLAG_UPDATE_ICON = 1; public static final int FLAG_UPDATE_THUMBNAIL = FLAG_UPDATE_ICON << 1; @@ -1572,7 +1574,7 @@ public class TaskView extends FrameLayout implements Reusable { */ public void setProgress(float fullscreenProgress, float parentScale, float taskViewScale, int previewWidth, DeviceProfile dp, PreviewPositionHelper pph) { - RectF insets = pph.getInsetsToDrawInFullscreen(dp); + RectF insets = getInsetsToDrawInFullscreen(pph, dp); float currentInsetsLeft = insets.left * fullscreenProgress; float currentInsetsTop = insets.top * fullscreenProgress; @@ -1591,6 +1593,14 @@ public class TaskView extends FrameLayout implements Reusable { mScale = previewWidth / (previewWidth + currentInsetsLeft + currentInsetsRight); } } + + /** + * Insets to used for clipping the thumbnail (in case it is drawing outside its own space) + */ + private static RectF getInsetsToDrawInFullscreen(PreviewPositionHelper pph, DeviceProfile dp) { + return dp.isTaskbarPresent && !dp.isTaskbarPresentInApps + ? pph.getClippedInsets() : EMPTY_RECT_F; + } } public class TaskIdAttributeContainer { diff --git a/quickstep/tests/src/com/android/quickstep/TaskThumbnailViewTest.kt b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt similarity index 64% rename from quickstep/tests/src/com/android/quickstep/TaskThumbnailViewTest.kt rename to quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt index cf3c8c9b8d..478535051c 100644 --- a/quickstep/tests/src/com/android/quickstep/TaskThumbnailViewTest.kt +++ b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt @@ -20,26 +20,34 @@ import android.graphics.RectF import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.launcher3.DeviceProfileBaseTest -import com.android.quickstep.views.TaskThumbnailView.PreviewPositionHelper +import com.android.quickstep.views.TaskView.FullscreenDrawParams import com.android.systemui.shared.recents.model.ThumbnailData +import com.android.systemui.shared.recents.utilities.PreviewPositionHelper import com.google.common.truth.Truth.assertThat +import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.mock /** - * Test for TaskThumbnailView class. + * Test for FullscreenDrawParams class. */ @SmallTest @RunWith(AndroidJUnit4::class) -class TaskThumbnailViewTest : DeviceProfileBaseTest() { +class FullscreenDrawParamsTest : DeviceProfileBaseTest() { private var mThumbnailData: ThumbnailData = mock(ThumbnailData::class.java) private val mPreviewPositionHelper = PreviewPositionHelper() + private lateinit var params: FullscreenDrawParams + + @Before + fun setup() { + params = FullscreenDrawParams(context) + } @Test - fun getInsetsToDrawInFullscreen_clipTaskbarSizeFromBottomForTablets() { + fun setFullProgress_currentDrawnInsets_clipTaskbarSizeFromBottomForTablets() { initializeVarsForTablet() val dp = newDP() val previewRect = Rect(0, 0, 100, 100) @@ -49,15 +57,18 @@ class TaskThumbnailViewTest : DeviceProfileBaseTest() { val isRtl = false mPreviewPositionHelper.updateThumbnailMatrix(previewRect, mThumbnailData, canvasWidth, - canvasHeight, dp, currentRotation, isRtl) + canvasHeight, dp.widthPx, dp.taskbarSize, dp.isTablet, currentRotation, + isRtl) + params.setProgress(/* fullscreenProgress= */ 1.0f, /* parentScale= */ 1.0f, + /* taskViewScale= */ 1.0f, /* previewWidth= */ 0, dp, mPreviewPositionHelper) val expectedClippedInsets = RectF(0f, 0f, 0f, dp.taskbarSize / 2f) - assertThat(mPreviewPositionHelper.getInsetsToDrawInFullscreen(dp)) + assertThat(params.mCurrentDrawnInsets) .isEqualTo(expectedClippedInsets) } @Test - fun getInsetsToDrawInFullscreen_doNotClipTaskbarSizeFromBottomForPhones() { + fun setFullProgress_currentDrawnInsets_doNotClipTaskbarSizeFromBottomForPhones() { initializeVarsForPhone() val dp = newDP() val previewRect = Rect(0, 0, 100, 100) @@ -67,10 +78,13 @@ class TaskThumbnailViewTest : DeviceProfileBaseTest() { val isRtl = false mPreviewPositionHelper.updateThumbnailMatrix(previewRect, mThumbnailData, canvasWidth, - canvasHeight, dp, currentRotation, isRtl) + canvasHeight, dp.widthPx, dp.taskbarSize, dp.isTablet, currentRotation, + isRtl) + params.setProgress(/* fullscreenProgress= */ 1.0f, /* parentScale= */ 1.0f, + /* taskViewScale= */ 1.0f, /* previewWidth= */ 0, dp, mPreviewPositionHelper) val expectedClippedInsets = RectF(0f, 0f, 0f, 0f) - assertThat(mPreviewPositionHelper.getInsetsToDrawInFullscreen(dp)) + assertThat(params.mCurrentDrawnInsets) .isEqualTo(expectedClippedInsets) } } \ No newline at end of file diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 616b08a908..f70511af7b 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -818,16 +818,6 @@ public final class Utilities { }; } - /** - * Compares the ratio of two quantities and returns whether that ratio is greater than the - * provided bound. Order of quantities does not matter. Bound should be a decimal representation - * of a percentage. - */ - public static boolean isRelativePercentDifferenceGreaterThan(float first, float second, - float bound) { - return (Math.abs(first - second) / Math.abs((first + second) / 2.0f)) > bound; - } - /** * Rotates `inOutBounds` by `delta` 90-degree increments. Rotation is visually CCW. Parent * sizes represent the "space" that will rotate carrying inOutBounds along with it to determine From 72c08d9255c19c2a18261b985fc42425d72881b4 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Wed, 5 Oct 2022 15:46:31 +0100 Subject: [PATCH 028/429] Set controllersInitialized to false when destroying taskbar controllers Bug: 250912179 Test: presubmit Change-Id: I16532e99b8f74542def4283b6cc753673eb5ee2d --- .../src/com/android/launcher3/taskbar/TaskbarControllers.java | 1 + 1 file changed, 1 insertion(+) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java index 2b80b753fb..707023b2ec 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java @@ -165,6 +165,7 @@ public class TaskbarControllers { * Cleans up all controllers. */ public void onDestroy() { + mAreAllControllersInitialized = false; mSharedState = null; navbarButtonsViewController.onDestroy(); From 7539d7649c2578212830b55c495fb764e79f29f1 Mon Sep 17 00:00:00 2001 From: Federico Baron Date: Thu, 29 Sep 2022 09:47:04 -0700 Subject: [PATCH 029/429] Change delightful pagination flag and use it for workspace Before the flag name would only fit 'delightful pagination' for folders, but now we're adding that feature to workspace also, hence the flag rename. The flag is now also used in launcher to show the new XML file that uses PageIndicatorDots rather than WorkspacePageIndicator Bug: 249773534 Test: manual Change-Id: I6cf6d52e76ad1ec60ecb54c5cca204e9ac35cc39 --- res/layout/page_indicator_dots.xml | 22 +++++++++++++++++++ src/com/android/launcher3/Launcher.java | 13 +++++++++++ .../launcher3/config/FeatureFlags.java | 20 ++++++++--------- .../pageindicators/PageIndicatorDots.java | 16 +++++++------- 4 files changed, 53 insertions(+), 18 deletions(-) create mode 100644 res/layout/page_indicator_dots.xml diff --git a/res/layout/page_indicator_dots.xml b/res/layout/page_indicator_dots.xml new file mode 100644 index 0000000000..d5fe51e734 --- /dev/null +++ b/res/layout/page_indicator_dots.xml @@ -0,0 +1,22 @@ + + + + \ No newline at end of file diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index a6831aafa9..6b10e5fc54 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -43,6 +43,7 @@ import static com.android.launcher3.LauncherState.SPRING_LOADED; import static com.android.launcher3.Utilities.postAsyncCallback; import static com.android.launcher3.accessibility.LauncherAccessibilityDelegate.getSupportedActions; import static com.android.launcher3.anim.Interpolators.EMPHASIZED; +import static com.android.launcher3.config.FeatureFlags.SHOW_DELIGHTFUL_PAGINATION; import static com.android.launcher3.logging.StatsLogManager.EventEnum; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME; @@ -97,6 +98,7 @@ import android.os.Trace; import android.os.UserHandle; import android.text.TextUtils; import android.text.method.TextKeyListener; +import android.util.AttributeSet; import android.util.FloatProperty; import android.util.Log; import android.util.SparseArray; @@ -163,6 +165,7 @@ import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.notification.NotificationListener; +import com.android.launcher3.pageindicators.WorkspacePageIndicator; import com.android.launcher3.pm.PinRequestHelper; import com.android.launcher3.pm.UserCache; import com.android.launcher3.popup.ArrowPopup; @@ -1291,6 +1294,16 @@ public class Launcher extends StatefulActivity mAllAppsController.setupViews(mScrimView, mAppsView); } + @Override + public View onCreateView(View parent, String name, Context context, AttributeSet attrs) { + if (SHOW_DELIGHTFUL_PAGINATION.get() + && WorkspacePageIndicator.class.getName().equals(name)) { + return LayoutInflater.from(context).inflate(R.layout.page_indicator_dots, + (ViewGroup) parent, false); + } + return super.onCreateView(parent, name, context, attrs); + } + /** * Creates a view representing a shortcut. * diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 6eeabc5ecd..d4593e5e37 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -37,7 +37,8 @@ public final class FeatureFlags { public static final String FLAGS_PREF_NAME = "featureFlags"; - private FeatureFlags() { } + private FeatureFlags() { + } public static boolean showFlagTogglerUi(Context context) { return Utilities.IS_DEBUG_DEVICE && Utilities.isDevelopersOptionsEnabled(context); @@ -61,7 +62,7 @@ public final class FeatureFlags { * To add a new flag that can be toggled through the flags UI: * * Declare a new ToggleableFlag below. Give it a unique key (e.g. "QSB_ON_FIRST_SCREEN"), - * and set a default value for the flag. This will be the default value on Debug builds. + * and set a default value for the flag. This will be the default value on Debug builds. */ public static final BooleanFlag ENABLE_INPUT_CONSUMER_REASON_LOGGING = getDebugFlag( "ENABLE_INPUT_CONSUMER_REASON_LOGGING", @@ -154,14 +155,14 @@ public final class FeatureFlags { /** * Enables region sampling for text color: Needs system health assessment before turning on */ - public static final BooleanFlag ENABLE_REGION_SAMPLING = getDebugFlag( + public static final BooleanFlag ENABLE_REGION_SAMPLING = getDebugFlag( "ENABLE_REGION_SAMPLING", false, "Enable region sampling to determine color of text on screen."); public static final BooleanFlag ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS = getDebugFlag( - "ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS", false, - "Always use hardware optimization for folder animations."); + "ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS", false, + "Always use hardware optimization for folder animations."); public static final BooleanFlag SEPARATE_RECENTS_ACTIVITY = getDebugFlag( "SEPARATE_RECENTS_ACTIVITY", false, @@ -281,11 +282,10 @@ public final class FeatureFlags { public static final BooleanFlag ENABLE_WIDGET_PICKER_DEPTH = new DeviceFlag( "ENABLE_WIDGET_PICKER_DEPTH", false, "Enable changing depth in widget picker."); - public static final BooleanFlag SHOW_DELIGHTFUL_PAGINATION_FOLDER = new DeviceFlag( - "SHOW_DELIGHTFUL_PAGINATION_FOLDER", false, - "Enable showing the new 'delightful pagination'" - + " which is a brand new animation for folder pagination"); - + public static final BooleanFlag SHOW_DELIGHTFUL_PAGINATION = new DeviceFlag( + "SHOW_DELIGHTFUL_PAGINATION", false, + "Enable showing the new 'delightful pagination' which is a brand" + + " new animation for folder pagination and workspace pagination"); public static final BooleanFlag POPUP_MATERIAL_U = new DeviceFlag( "POPUP_MATERIAL_U", false, "Switch popup UX to use material U"); diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java index b4cb0eef6e..5f9fbca1d4 100644 --- a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java +++ b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java @@ -16,7 +16,7 @@ package com.android.launcher3.pageindicators; -import static com.android.launcher3.config.FeatureFlags.SHOW_DELIGHTFUL_PAGINATION_FOLDER; +import static com.android.launcher3.config.FeatureFlags.SHOW_DELIGHTFUL_PAGINATION; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -129,7 +129,7 @@ public class PageIndicatorDots extends View implements PageIndicator { mDotRadius = getResources().getDimension(R.dimen.page_indicator_dot_size) / 2; - if (SHOW_DELIGHTFUL_PAGINATION_FOLDER.get()) { + if (SHOW_DELIGHTFUL_PAGINATION.get()) { mPageIndicatorSize = getResources().getDimension( R.dimen.page_indicator_size); mPageIndicatorRadius = mPageIndicatorSize / 2; @@ -144,7 +144,7 @@ public class PageIndicatorDots extends View implements PageIndicator { mPageIndicatorDrawable = null; mCircleGap = DOT_GAP_FACTOR * mDotRadius; } - if (!SHOW_DELIGHTFUL_PAGINATION_FOLDER.get()) { + if (!SHOW_DELIGHTFUL_PAGINATION.get()) { setOutlineProvider(new MyOutlineProver()); } mIsRtl = Utilities.isRtl(getResources()); @@ -161,7 +161,7 @@ public class PageIndicatorDots extends View implements PageIndicator { currentScroll = totalScroll - currentScroll; } - if (SHOW_DELIGHTFUL_PAGINATION_FOLDER.get()) { + if (SHOW_DELIGHTFUL_PAGINATION.get()) { mCurrentScroll = currentScroll; mTotalScroll = totalScroll; invalidate(); @@ -296,7 +296,7 @@ public class PageIndicatorDots extends View implements PageIndicator { } for (int i = 0; i < mEntryAnimationRadiusFactors.length; i++) { mPaginationPaint.setAlpha(i == mActivePage ? PAGE_INDICATOR_ALPHA : DOT_ALPHA); - if (SHOW_DELIGHTFUL_PAGINATION_FOLDER.get()) { + if (SHOW_DELIGHTFUL_PAGINATION.get()) { if (i != mActivePage) { canvas.drawCircle(x, y, mDotRadius * mEntryAnimationRadiusFactors[i], mPaginationPaint); @@ -313,7 +313,7 @@ public class PageIndicatorDots extends View implements PageIndicator { // Here we draw the dots mPaginationPaint.setAlpha(DOT_ALPHA); for (int i = 0; i < mNumPages; i++) { - if (SHOW_DELIGHTFUL_PAGINATION_FOLDER.get()) { + if (SHOW_DELIGHTFUL_PAGINATION.get()) { canvas.drawCircle(x, y, getRadius(x), mPaginationPaint); } else { canvas.drawCircle(x, y, mDotRadius, mPaginationPaint); @@ -323,7 +323,7 @@ public class PageIndicatorDots extends View implements PageIndicator { // Here we draw the current page indicator mPaginationPaint.setAlpha(PAGE_INDICATOR_ALPHA); - if (SHOW_DELIGHTFUL_PAGINATION_FOLDER.get()) { + if (SHOW_DELIGHTFUL_PAGINATION.get()) { drawPageIndicator(canvas, 1); } else { canvas.drawRoundRect(getActiveRect(), mDotRadius, mDotRadius, mPaginationPaint); @@ -389,7 +389,7 @@ public class PageIndicatorDots extends View implements PageIndicator { float diameter = 2 * mDotRadius; float startX; - if (SHOW_DELIGHTFUL_PAGINATION_FOLDER.get()) { + if (SHOW_DELIGHTFUL_PAGINATION.get()) { startX = ((getWidth() - (mNumPages * mCircleGap) + mDotRadius) / 2) - getOffset(); sTempRect.top = (getHeight() - mPageIndicatorSize) * 0.5f; sTempRect.bottom = (getHeight() + mPageIndicatorSize) * 0.5f; From 471e2178f8702143f8dac18d9a15178ada6c7a82 Mon Sep 17 00:00:00 2001 From: Federico Baron Date: Mon, 3 Oct 2022 12:24:20 -0700 Subject: [PATCH 030/429] Fix page indicator dots height in workspace In workspace, the page indicator dots end up in the bottom because we were missing a setInsets method (WorkspacePageInidcator.java uses this method to set the page indicator to the right height). Bug: 249773534 Test: manual Change-Id: I03636e28244f329b249453a6d22eb0ec7d85c45f --- src/com/android/launcher3/Workspace.java | 22 +++++++++++++++++++ .../pageindicators/PageIndicatorDots.java | 13 +++++++++-- .../WorkspacePageIndicator.java | 21 ++++-------------- 3 files changed, 37 insertions(+), 19 deletions(-) diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index b49d64625b..1092af056c 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -53,12 +53,14 @@ import android.os.Parcelable; import android.util.AttributeSet; import android.util.Log; import android.util.SparseArray; +import android.view.Gravity; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver; import android.view.accessibility.AccessibilityNodeInfo; +import android.widget.FrameLayout; import android.widget.Toast; import androidx.annotation.Nullable; @@ -322,6 +324,26 @@ public class Workspace extends PagedView updateCellLayoutPadding(); updateWorkspaceWidgetsSizes(); + setPageIndicatorInset(); + } + + private void setPageIndicatorInset() { + DeviceProfile grid = mLauncher.getDeviceProfile(); + + FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) mPageIndicator.getLayoutParams(); + + // Set insets for page indicator + Rect padding = grid.workspacePadding; + if (grid.isVerticalBarLayout()) { + lp.leftMargin = padding.left + grid.workspaceCellPaddingXPx; + lp.rightMargin = padding.right + grid.workspaceCellPaddingXPx; + lp.bottomMargin = padding.bottom; + } else { + lp.leftMargin = lp.rightMargin = 0; + lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; + lp.bottomMargin = grid.hotseatBarSizePx; + } + mPageIndicator.setLayoutParams(lp); } private void updateCellLayoutPadding() { diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java index 5f9fbca1d4..98ce9511a2 100644 --- a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java +++ b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java @@ -29,6 +29,7 @@ import android.graphics.Canvas; import android.graphics.Outline; import android.graphics.Paint; import android.graphics.Paint.Style; +import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.Drawable; import android.util.AttributeSet; @@ -38,6 +39,7 @@ import android.view.ViewOutlineProvider; import android.view.animation.Interpolator; import android.view.animation.OvershootInterpolator; +import com.android.launcher3.Insettable; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.Interpolators; @@ -47,7 +49,7 @@ import com.android.launcher3.util.Themes; * {@link PageIndicator} which shows dots per page. The active page is shown with the current * accent color. */ -public class PageIndicatorDots extends View implements PageIndicator { +public class PageIndicatorDots extends View implements Insettable, PageIndicator { private static final float SHIFT_PER_ANIMATION = 0.5f; private static final float SHIFT_THRESHOLD = 0.1f; @@ -128,7 +130,6 @@ public class PageIndicatorDots extends View implements PageIndicator { mPaginationPaint.setColor(Themes.getAttrColor(context, R.attr.folderPaginationColor)); mDotRadius = getResources().getDimension(R.dimen.page_indicator_dot_size) / 2; - if (SHOW_DELIGHTFUL_PAGINATION.get()) { mPageIndicatorSize = getResources().getDimension( R.dimen.page_indicator_size); @@ -483,4 +484,12 @@ public class PageIndicatorDots extends View implements PageIndicator { } } } + + /** + * We need to override setInsets to prevent InsettableFrameLayout from applying different + * margins on the pagination. + */ + @Override + public void setInsets(Rect insets) { + } } diff --git a/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java b/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java index 87ae890894..bde4e525a1 100644 --- a/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java +++ b/src/com/android/launcher3/pageindicators/WorkspacePageIndicator.java @@ -14,12 +14,9 @@ import android.os.Handler; import android.os.Looper; import android.util.AttributeSet; import android.util.Property; -import android.view.Gravity; import android.view.View; import android.view.ViewConfiguration; -import android.widget.FrameLayout; -import com.android.launcher3.DeviceProfile; import com.android.launcher3.Insettable; import com.android.launcher3.Launcher; import com.android.launcher3.R; @@ -258,21 +255,11 @@ public class WorkspacePageIndicator extends View implements Insettable, PageIndi } } + /** + * We need to override setInsets to prevent InsettableFrameLayout from applying different + * margins on the page indicator. + */ @Override public void setInsets(Rect insets) { - DeviceProfile grid = mLauncher.getDeviceProfile(); - FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) getLayoutParams(); - - if (grid.isVerticalBarLayout()) { - Rect padding = grid.workspacePadding; - lp.leftMargin = padding.left + grid.workspaceCellPaddingXPx; - lp.rightMargin = padding.right + grid.workspaceCellPaddingXPx; - lp.bottomMargin = padding.bottom; - } else { - lp.leftMargin = lp.rightMargin = 0; - lp.gravity = Gravity.CENTER_HORIZONTAL | Gravity.BOTTOM; - lp.bottomMargin = grid.hotseatBarSizePx; - } - setLayoutParams(lp); } } From 3559740ea05cbe88abbdebbc8a21f540c6d09132 Mon Sep 17 00:00:00 2001 From: Sihua Ma Date: Tue, 4 Oct 2022 14:01:37 -0700 Subject: [PATCH 031/429] Change padding of widget recommendation table for correct size Previously, the margin of the recommendation table was changed to fix the bug b/209579563 , but this leaves a bug where the left/right sides of the recommendation table would be too close to the screen border. This CL should leave enough space for both sides and reveal the scroll bar again, while keeping the talkback focused on the title first once it enters the widget picker. Test: Manual Bug: 206481237 Change-Id: I808c279c3264a51b21a0bb7af8ca455d284e36ff --- res/layout/widgets_full_sheet_recyclerview.xml | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/res/layout/widgets_full_sheet_recyclerview.xml b/res/layout/widgets_full_sheet_recyclerview.xml index 9da3e87b17..b2a3a0d3d7 100644 --- a/res/layout/widgets_full_sheet_recyclerview.xml +++ b/res/layout/widgets_full_sheet_recyclerview.xml @@ -30,6 +30,7 @@ android:layout_height="wrap_content" android:layout_below="@id/collapse_handle" android:paddingBottom="16dp" + android:paddingHorizontal="@dimen/widget_list_horizontal_margin" android:orientation="vertical"> @@ -63,7 +62,6 @@ android:layout_marginTop="8dp" android:background="@drawable/widgets_recommendation_background" android:paddingVertical="@dimen/recommended_widgets_table_vertical_padding" - android:paddingHorizontal="@dimen/widget_list_horizontal_margin" android:visibility="gone" /> From dafd14d9dcb1800ba6fa64172274604bbd3a4315 Mon Sep 17 00:00:00 2001 From: Federico Baron Date: Wed, 5 Oct 2022 14:51:37 -0700 Subject: [PATCH 032/429] Add flags for new home gardening mode We're going to follow this new design for the home screen edit mode (home gardening): https://docs.google.com/presentation/d/1FOmmCdmGmSMR77_901IOMbvbPVxPmjaAdxZjy-D9tw0/edit#slide=id.g11f697f283a_0_0. This new design will be guarded by this flag. Bug: 251259222 Test: manual Change-Id: I36d0d1dddb463154140802b945dd092b072d6eaf --- .../android/launcher3/config/FeatureFlags.java | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 6eeabc5ecd..5ba268e53f 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -37,7 +37,8 @@ public final class FeatureFlags { public static final String FLAGS_PREF_NAME = "featureFlags"; - private FeatureFlags() { } + private FeatureFlags() { + } public static boolean showFlagTogglerUi(Context context) { return Utilities.IS_DEBUG_DEVICE && Utilities.isDevelopersOptionsEnabled(context); @@ -61,7 +62,7 @@ public final class FeatureFlags { * To add a new flag that can be toggled through the flags UI: * * Declare a new ToggleableFlag below. Give it a unique key (e.g. "QSB_ON_FIRST_SCREEN"), - * and set a default value for the flag. This will be the default value on Debug builds. + * and set a default value for the flag. This will be the default value on Debug builds. */ public static final BooleanFlag ENABLE_INPUT_CONSUMER_REASON_LOGGING = getDebugFlag( "ENABLE_INPUT_CONSUMER_REASON_LOGGING", @@ -154,14 +155,14 @@ public final class FeatureFlags { /** * Enables region sampling for text color: Needs system health assessment before turning on */ - public static final BooleanFlag ENABLE_REGION_SAMPLING = getDebugFlag( + public static final BooleanFlag ENABLE_REGION_SAMPLING = getDebugFlag( "ENABLE_REGION_SAMPLING", false, "Enable region sampling to determine color of text on screen."); public static final BooleanFlag ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS = getDebugFlag( - "ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS", false, - "Always use hardware optimization for folder animations."); + "ALWAYS_USE_HARDWARE_OPTIMIZATION_FOR_FOLDER_ANIMATIONS", false, + "Always use hardware optimization for folder animations."); public static final BooleanFlag SEPARATE_RECENTS_ACTIVITY = getDebugFlag( "SEPARATE_RECENTS_ACTIVITY", false, @@ -289,6 +290,10 @@ public final class FeatureFlags { public static final BooleanFlag POPUP_MATERIAL_U = new DeviceFlag( "POPUP_MATERIAL_U", false, "Switch popup UX to use material U"); + public static final BooleanFlag SHOW_HOME_GARDENING = new DeviceFlag( + "SHOW_HOME_GARDENING", false, + "Show the new home gardening mode"); + public static void initialize(Context context) { synchronized (sDebugFlags) { for (DebugFlag flag : sDebugFlags) { From f6cb65f63a57c0a2a7a51d1f49b0346889b48cdd Mon Sep 17 00:00:00 2001 From: Rajat Jain Date: Thu, 22 Sep 2022 17:18:20 +0000 Subject: [PATCH 033/429] Low contrast for Personal and Work Tab in launcher There is low contrast between font and background of Personal and Work Tab in Launcher which makes it difficult to read text Bug: 235573969 Test: manual test Change-Id: Idfbb7a27cc48de145cf2962facad06bf34ac35f8 --- res/color-night-v31/all_apps_tab_text.xml | 4 ++-- .../all_apps_tabs_background.xml | 18 ++++++++++++++++++ 2 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 res/color-night-v31/all_apps_tabs_background.xml diff --git a/res/color-night-v31/all_apps_tab_text.xml b/res/color-night-v31/all_apps_tab_text.xml index 83237b49e5..54b95aee8d 100644 --- a/res/color-night-v31/all_apps_tab_text.xml +++ b/res/color-night-v31/all_apps_tab_text.xml @@ -14,6 +14,6 @@ limitations under the License. --> - - + + \ No newline at end of file diff --git a/res/color-night-v31/all_apps_tabs_background.xml b/res/color-night-v31/all_apps_tabs_background.xml new file mode 100644 index 0000000000..9213274d5c --- /dev/null +++ b/res/color-night-v31/all_apps_tabs_background.xml @@ -0,0 +1,18 @@ + + + + + \ No newline at end of file From bda972b2c92ce54ce5d0d2cd11228a5588205d1f Mon Sep 17 00:00:00 2001 From: Luca Zuccarini Date: Mon, 3 Oct 2022 11:48:27 +0000 Subject: [PATCH 034/429] [Toast] Switch to using device config to control keyboard sync. Bug: 234812580 Test: followed the existing pattern and tested by manually setting and unsetting the flag through command line - `adb shell device_config put launcher enable_web_suggest_on_default_browser ` Change-Id: Idd479e93b628b78fdf55d826c56f69c5cfdaf46e --- src/com/android/launcher3/Launcher.java | 8 ++++++++ .../launcher3/allapps/AllAppsTransitionController.java | 3 +-- src/com/android/launcher3/config/FeatureFlags.java | 5 ----- 3 files changed, 9 insertions(+), 7 deletions(-) diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index a6831aafa9..5be63e3c5f 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -1579,6 +1579,14 @@ public class Launcher extends StatefulActivity return mOldConfig.orientation; } + /** + * Whether keyboard sync is enabled for transitions between Home and All Apps. + * TODO(b/251387263): move this method inside an All Apps specific config class. + */ + public boolean isKeyboardSyncEnabled() { + return false; + } + @Override protected void onNewIntent(Intent intent) { if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index 872c4fd5cd..001b494439 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -39,7 +39,6 @@ import com.android.launcher3.LauncherState; import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PropertySetter; -import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.util.MultiPropertyFactory; @@ -229,7 +228,7 @@ public class AllAppsTransitionController StateAnimationConfig config, PendingAnimation builder) { if (mLauncher.isInState(ALL_APPS) && !ALL_APPS.equals(toState)) { // For atomic animations, we close the keyboard immediately. - if (!config.userControlled && !FeatureFlags.ENABLE_KEYBOARD_TRANSITION_SYNC.get()) { + if (!config.userControlled && !mLauncher.isKeyboardSyncEnabled()) { mLauncher.getAppsView().getSearchUiManager().getEditText().hideKeyboard(); } diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 50cf8d67f9..046378ab3f 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -249,11 +249,6 @@ public final class FeatureFlags { public static final BooleanFlag ENABLE_ONE_SEARCH_MOTION = new DeviceFlag( "ENABLE_ONE_SEARCH_MOTION", true, "Enables animations in OneSearch."); - public static final BooleanFlag ENABLE_KEYBOARD_TRANSITION_SYNC = new DeviceFlag( - "ENABLE_KEYBOARD_TRANSITION_SYNC", IS_STUDIO_BUILD, - "Enable option to synchronize the keyboard open and close animations when transitioning" - + " between home and all apps"); - public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = new DeviceFlag( "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", true, "Enable option to show keyboard when going to all-apps"); From 24b9554086b85766974e875fd1e592ff093ddf59 Mon Sep 17 00:00:00 2001 From: Pat Manning Date: Tue, 9 Aug 2022 18:06:58 +0100 Subject: [PATCH 035/429] Add logging to help debug flake when swiping home to overview. Bug: 238461210 Bug: 246283207 Test: TaplTestsQuickstep#testSwitchToOverview Change-Id: I8ee9af4f4a331c43761ba3738e12acb376ababc2 (cherry picked from commit 1edba8b0a6026b04c667343608b5309b5be3248d) Merged-In: I8ee9af4f4a331c43761ba3738e12acb376ababc2 --- .../uioverrides/RecentsViewStateController.java | 9 +++++++++ .../src/com/android/quickstep/views/RecentsView.java | 7 +++++++ src/com/android/launcher3/PagedView.java | 7 +++++++ 3 files changed, 23 insertions(+) diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index 910b99b36a..3fe2e59471 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -31,11 +31,13 @@ import android.animation.AnimatorSet; import android.annotation.TargetApi; import android.os.Build; import android.util.FloatProperty; +import android.util.Log; import android.util.Pair; import androidx.annotation.NonNull; import com.android.launcher3.LauncherState; +import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PropertySetter; @@ -88,6 +90,13 @@ public final class RecentsViewStateController extends // While animating into recents, update the visible task data as needed builder.addOnFrameCallback(() -> mRecentsView.loadVisibleTaskData(FLAG_UPDATE_ALL)); mRecentsView.updateEmptyMessage(); + // TODO(b/238461210): Remove logging once root cause of flake detected. + if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { + Log.d("b/238461210", "RecentsView#setStateWithAnimationInternal getCurrentPage(): " + + mRecentsView.getCurrentPage() + + ", getScrollForPage(getCurrentPage())): " + + mRecentsView.getScrollForPage(mRecentsView.getCurrentPage())); + } } else { builder.addListener( AnimatorListeners.forSuccessCallback(mRecentsView::resetTaskVisuals)); diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 68b80c26f6..5b4415a440 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -1505,6 +1505,13 @@ public abstract class RecentsView !settlingOnNewTask -> " + + "previousCurrentPage: " + previousCurrentPage + + ", getScrollForPage(previousCurrentPage): " + + getScrollForPage(previousCurrentPage)); + } setCurrentPage(previousCurrentPage); } diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index 68c54c7667..377843cb3b 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -772,6 +772,13 @@ public abstract class PagedView extends ViewGrou } if (mScroller.isFinished() && pageScrollChanged) { + // TODO(b/238461210): Remove logging once root cause of flake detected. + if (Utilities.IS_RUNNING_IN_TEST_HARNESS && !(this instanceof Workspace)) { + Log.d("b/238461210", this.getClass().getSimpleName() + "#onLayout() -> " + + "if(mScroller.isFinished() && pageScrollChanged) -> getNextPage(): " + + getNextPage() + ", getScrollForPage(getNextPage()): " + + getScrollForPage(getNextPage())); + } setCurrentPage(getNextPage()); } onPageScrollsInitialized(); From 2b17c4b9d081d2da975617b3fe057b06554e17c6 Mon Sep 17 00:00:00 2001 From: Holly Sun Date: Mon, 19 Sep 2022 10:24:43 -0700 Subject: [PATCH 036/429] Quick launch v2. Set auto-append text in selected text mode. Clicking enter key launches the app. Delete the selected text to remove auto-append text and highlight. Clicking enter key sends raw query to search. Test: manual Bug: 210661150 Change-Id: Iee8e716b81a2dde64e60462fd33d4a6eb4abcf01 --- .../launcher3/allapps/search/AllAppsSearchBarController.java | 5 ++++- src/com/android/launcher3/config/FeatureFlags.java | 4 ++++ src/com/android/launcher3/util/LogConfig.java | 5 +++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java index 886460e5c7..4c461aa5d4 100644 --- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java +++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java @@ -84,7 +84,10 @@ public class AllAppsSearchBarController mTextConversions = extractTextConversions(s); } - private static String[] extractTextConversions(CharSequence text) { + /** + * Extract text conversions from composing text and send them for search. + */ + public static String[] extractTextConversions(CharSequence text) { if (text instanceof SpannableStringBuilder) { SpannableStringBuilder spanned = (SpannableStringBuilder) text; SuggestionSpan[] suggestionSpans = diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index a2d9dd400c..882d6a6323 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -91,6 +91,10 @@ public final class FeatureFlags { getDebugFlag("ENABLE_FLOATING_SEARCH_BAR", false, "Keep All Apps search bar at the bottom (but above keyboard if open)"); + public static final BooleanFlag ENABLE_QUICK_LAUNCH_V2 = new DeviceFlag( + "ENABLE_QUICK_LAUNCH_V2", false, "Use quick launch v2 " + + "behavior. Quick search and quick launch v1 would be unavailable if this is enabled"); + public static final BooleanFlag ENABLE_HIDE_HEADER = new DeviceFlag("ENABLE_HIDE_HEADER", true, "Hide header on keyboard before typing in all apps"); diff --git a/src/com/android/launcher3/util/LogConfig.java b/src/com/android/launcher3/util/LogConfig.java index ee1d1ff361..5abf95c000 100644 --- a/src/com/android/launcher3/util/LogConfig.java +++ b/src/com/android/launcher3/util/LogConfig.java @@ -50,4 +50,9 @@ public class LogConfig { * When turned on, we enable web suggest appSearch related logging. */ public static final String WEB_APP_SEARCH_LOGGING = "WebAppSearchLogging"; + + /** + * When turned on, we enable quick launch v2 related logging. + */ + public static final String QUICK_LAUNCH_V2 = "QuickLaunchV2"; } From 2e72e4cda6d1c1b0fee2e41508a6cb3755077a1e Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Wed, 5 Oct 2022 17:43:45 +0100 Subject: [PATCH 037/429] Fix taskbar in overview touch and stash behavior - When taskbar is unstashed in Launcher (e.g. overview), make the unstashed height touchable - When AllApps button is pressed in taskbar overview, also stash taskbar Bug: 245320601 Test: manual Change-Id: Iadd0bea13cf9a779c68e953d25f21f663c15865a --- .../taskbar/TaskbarInsetsController.kt | 11 +++++---- .../taskbar/TaskbarStashController.java | 23 +++++++++++++------ .../allapps/TaskbarAllAppsViewController.java | 4 ++-- 3 files changed, 24 insertions(+), 14 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt index 7b2b7eca7f..079e8a1f2d 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt @@ -44,7 +44,7 @@ class TaskbarInsetsController(val context: TaskbarActivityContext): LoggableTask /** The bottom insets taskbar provides to the IME when IME is visible. */ val taskbarHeightForIme: Int = context.resources.getDimensionPixelSize( KtR.dimen.taskbar_ime_size) - private val contentRegion: Region = Region() + private val touchableRegion: Region = Region() private val deviceProfileChangeListener = { _: DeviceProfile -> onTaskbarWindowHeightOrInsetsChanged() } @@ -77,10 +77,11 @@ class TaskbarInsetsController(val context: TaskbarActivityContext): LoggableTask } fun onTaskbarWindowHeightOrInsetsChanged() { - var contentHeight = controllers.taskbarStashController.contentHeightToReportToApps - contentRegion.set(0, windowLayoutParams.height - contentHeight, + val touchableHeight = controllers.taskbarStashController.touchableHeight + touchableRegion.set(0, windowLayoutParams.height - touchableHeight, context.deviceProfile.widthPx, windowLayoutParams.height) - var tappableHeight = controllers.taskbarStashController.tappableHeightToReportToApps + val contentHeight = controllers.taskbarStashController.contentHeightToReportToApps + val tappableHeight = controllers.taskbarStashController.tappableHeightToReportToApps for (provider in windowLayoutParams.providedInsets) { if (provider.type == ITYPE_EXTRA_NAVIGATION_BAR) { provider.insetsSize = Insets.of(0, 0, 0, contentHeight) @@ -154,7 +155,7 @@ class TaskbarInsetsController(val context: TaskbarActivityContext): LoggableTask if (context.isTaskbarWindowFullscreen) { TOUCHABLE_INSETS_FRAME } else { - insetsInfo.touchableRegion.set(contentRegion) + insetsInfo.touchableRegion.set(touchableRegion) TOUCHABLE_INSETS_REGION } ) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 4b0adb192f..b9bcf1bb81 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -67,7 +67,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba public static final int FLAG_STASHED_IN_APP_SETUP = 1 << 4; // setup wizard and AllSetActivity public static final int FLAG_STASHED_IN_APP_IME = 1 << 5; // IME is visible public static final int FLAG_IN_STASHED_LAUNCHER_STATE = 1 << 6; - public static final int FLAG_STASHED_IN_APP_ALL_APPS = 1 << 7; // All apps is visible. + public static final int FLAG_STASHED_IN_TASKBAR_ALL_APPS = 1 << 7; // All apps is visible. public static final int FLAG_IN_SETUP = 1 << 8; // In the Setup Wizard public static final int FLAG_STASHED_SMALL_SCREEN = 1 << 9; // phone screen gesture nav, stashed @@ -77,8 +77,8 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba // If we're in an app and any of these flags are enabled, taskbar should be stashed. 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 | FLAG_STASHED_IN_APP_ALL_APPS | - FLAG_STASHED_SMALL_SCREEN; + | FLAG_STASHED_IN_APP_IME | FLAG_STASHED_IN_TASKBAR_ALL_APPS + | FLAG_STASHED_SMALL_SCREEN; private static final int FLAGS_STASHED_IN_APP_IGNORING_IME = FLAGS_STASHED_IN_APP & ~FLAG_STASHED_IN_APP_IME; @@ -88,7 +88,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba // Currently any flag that causes us to stash in an app is included, except for IME or All Apps // since those cover 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 & ~FLAG_STASHED_IN_APP_ALL_APPS; + & ~FLAG_STASHED_IN_APP_IME & ~FLAG_STASHED_IN_TASKBAR_ALL_APPS; /** * How long to stash/unstash when manually invoked via long press. @@ -168,9 +168,11 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba boolean inApp = hasAnyFlag(flags, FLAGS_IN_APP); boolean stashedInApp = hasAnyFlag(flags, FLAGS_STASHED_IN_APP); boolean stashedLauncherState = hasAnyFlag(flags, FLAG_IN_STASHED_LAUNCHER_STATE); + boolean stashedInTaskbarAllApps = + hasAnyFlag(flags, FLAG_STASHED_IN_TASKBAR_ALL_APPS); boolean stashedForSmallScreen = hasAnyFlag(flags, FLAG_STASHED_SMALL_SCREEN); return (inApp && stashedInApp) || (!inApp && stashedLauncherState) - || stashedForSmallScreen; + || stashedInTaskbarAllApps || stashedForSmallScreen; }); public TaskbarStashController(TaskbarActivityContext activity) { @@ -316,6 +318,13 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba return hasAnyFlag(FLAGS_IN_APP); } + /** + * Returns the height that taskbar will be touchable. + */ + public int getTouchableHeight() { + return mIsStashed ? mStashedHeight : mUnstashedHeight; + } + /** * Returns the height that taskbar will inset when inside apps. * @see WindowInsets.Type#navigationBars() @@ -659,7 +668,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba return; } - updateStateForFlag(FLAG_STASHED_IN_APP_ALL_APPS, false); + updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, false); if (applyState) { applyState(ALL_APPS.getTransitionDuration( mControllers.taskbarActivityContext, false /* isToState */)); @@ -779,7 +788,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba appendFlag(str, flags, FLAG_STASHED_IN_APP_SETUP, "FLAG_STASHED_IN_APP_SETUP"); appendFlag(str, flags, FLAG_STASHED_IN_APP_IME, "FLAG_STASHED_IN_APP_IME"); appendFlag(str, flags, FLAG_IN_STASHED_LAUNCHER_STATE, "FLAG_IN_STASHED_LAUNCHER_STATE"); - appendFlag(str, flags, FLAG_STASHED_IN_APP_ALL_APPS, "FLAG_STASHED_IN_APP_ALL_APPS"); + appendFlag(str, flags, FLAG_STASHED_IN_TASKBAR_ALL_APPS, "FLAG_STASHED_IN_APP_ALL_APPS"); appendFlag(str, flags, FLAG_IN_SETUP, "FLAG_IN_SETUP"); return str.toString(); } diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java index b0d3528e2c..128fa5e81e 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java @@ -16,7 +16,7 @@ package com.android.launcher3.taskbar.allapps; import static com.android.launcher3.LauncherState.ALL_APPS; -import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_APP_ALL_APPS; +import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_TASKBAR_ALL_APPS; import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT; import com.android.launcher3.AbstractFloatingView; @@ -84,7 +84,7 @@ final class TaskbarAllAppsViewController { } private void setUpTaskbarStashing() { - mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_APP_ALL_APPS, true); + mTaskbarStashController.updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, true); mTaskbarStashController.applyState( ALL_APPS.getTransitionDuration(mContext, true /* isToState */)); mNavbarButtonsViewController.setSlideInViewVisible(true); From 73ab56a355e41566333b9d3a4f47ac63c67f1f32 Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Mon, 26 Sep 2022 21:24:23 +0000 Subject: [PATCH 038/429] Update constants used for resolving shell services Bug: 238217847 Test: atest WMShellUnitTests Change-Id: I0bf0d258fb9c6c9e7d6ce2a17bd120fe7a45ad9f Merged-In: I0bf0d258fb9c6c9e7d6ce2a17bd120fe7a45ad9f --- .../quickstep/TouchInteractionService.java | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 1999701f61..148866fdcc 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -26,19 +26,19 @@ import static com.android.quickstep.GestureState.DEFAULT_STATE; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.MOTION_DOWN; import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.MOTION_UP; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_RECENTS; -import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_RECENT_TASKS; -import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_BACK_ANIMATION; -import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_DESKTOP_MODE; -import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_FLOATING_TASKS; -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; -import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_SHELL_TRANSITIONS; -import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_SPLIT_SCREEN; -import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SHELL_STARTING_WINDOW; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY; import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED; +import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_BACK_ANIMATION; +import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_DESKTOP_MODE; +import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_FLOATING_TASKS; +import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_ONE_HANDED; +import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_PIP; +import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_RECENT_TASKS; +import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_SHELL_TRANSITIONS; +import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_SPLIT_SCREEN; +import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_STARTING_WINDOW; import android.annotation.TargetApi; import android.app.PendingIntent; @@ -183,7 +183,7 @@ public class TouchInteractionService extends Service ISysuiUnlockAnimationController.Stub.asInterface( bundle.getBinder(KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER)); IRecentTasks recentTasks = IRecentTasks.Stub.asInterface( - bundle.getBinder(KEY_EXTRA_RECENT_TASKS)); + bundle.getBinder(KEY_EXTRA_SHELL_RECENT_TASKS)); IBackAnimation backAnimation = IBackAnimation.Stub.asInterface( bundle.getBinder(KEY_EXTRA_SHELL_BACK_ANIMATION)); IDesktopMode desktopMode = IDesktopMode.Stub.asInterface( From a1d24cb85e38276b52ed169c080d4e771f2af761 Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Thu, 6 Oct 2022 16:23:20 -0700 Subject: [PATCH 039/429] Use correct interpolator for tablet split confirm This patch makes it so that the split-to-confirm animation on tablets uses the EMPHASIZED interpolator instead of the (incorrect) LINEAR interpolator. Fixes: 241126570 Test: Manual Change-Id: Ic3c91d439a79a492da7f32bdcd56b954edf6c947 --- .../quickstep/util/PhoneSplitToConfirmTimings.java | 8 -------- .../android/quickstep/util/SplitToConfirmTimings.java | 10 ++++++---- .../quickstep/util/TabletSplitToConfirmTimings.java | 8 -------- 3 files changed, 6 insertions(+), 20 deletions(-) diff --git a/quickstep/src/com/android/quickstep/util/PhoneSplitToConfirmTimings.java b/quickstep/src/com/android/quickstep/util/PhoneSplitToConfirmTimings.java index 9e7351a2de..3d9e09ee81 100644 --- a/quickstep/src/com/android/quickstep/util/PhoneSplitToConfirmTimings.java +++ b/quickstep/src/com/android/quickstep/util/PhoneSplitToConfirmTimings.java @@ -16,10 +16,6 @@ package com.android.quickstep.util; -import static com.android.launcher3.anim.Interpolators.EMPHASIZED; - -import android.view.animation.Interpolator; - /** * Timings for the OverviewSplitSelect > confirmed animation on phones. */ @@ -33,8 +29,4 @@ public class PhoneSplitToConfirmTimings public int getStagedRectSlideEnd() { return 333; } public int getDuration() { return PHONE_CONFIRM_DURATION; } - public Interpolator getStagedRectXInterpolator() { return EMPHASIZED; } - public Interpolator getStagedRectYInterpolator() { return EMPHASIZED; } - public Interpolator getStagedRectScaleXInterpolator() { return EMPHASIZED; } - public Interpolator getStagedRectScaleYInterpolator() { return EMPHASIZED; } } diff --git a/quickstep/src/com/android/quickstep/util/SplitToConfirmTimings.java b/quickstep/src/com/android/quickstep/util/SplitToConfirmTimings.java index 3026e98aa9..f5b00cf42b 100644 --- a/quickstep/src/com/android/quickstep/util/SplitToConfirmTimings.java +++ b/quickstep/src/com/android/quickstep/util/SplitToConfirmTimings.java @@ -16,6 +16,8 @@ package com.android.quickstep.util; +import static com.android.launcher3.anim.Interpolators.EMPHASIZED; + import android.view.animation.Interpolator; /** @@ -33,12 +35,12 @@ abstract class SplitToConfirmTimings implements SplitAnimationTimings { // Common timings public int getInstructionsFadeStart() { return 0; } public int getInstructionsFadeEnd() { return 67; } + public Interpolator getStagedRectXInterpolator() { return EMPHASIZED; } + public Interpolator getStagedRectYInterpolator() { return EMPHASIZED; } + public Interpolator getStagedRectScaleXInterpolator() { return EMPHASIZED; } + public Interpolator getStagedRectScaleYInterpolator() { return EMPHASIZED; } abstract public int getDuration(); - abstract public Interpolator getStagedRectXInterpolator(); - abstract public Interpolator getStagedRectYInterpolator(); - abstract public Interpolator getStagedRectScaleXInterpolator(); - abstract public Interpolator getStagedRectScaleYInterpolator(); public float getInstructionsFadeStartOffset() { return (float) getInstructionsFadeStart() / getDuration(); diff --git a/quickstep/src/com/android/quickstep/util/TabletSplitToConfirmTimings.java b/quickstep/src/com/android/quickstep/util/TabletSplitToConfirmTimings.java index 3ea8466148..580cc99d4e 100644 --- a/quickstep/src/com/android/quickstep/util/TabletSplitToConfirmTimings.java +++ b/quickstep/src/com/android/quickstep/util/TabletSplitToConfirmTimings.java @@ -16,10 +16,6 @@ package com.android.quickstep.util; -import static com.android.launcher3.anim.Interpolators.LINEAR; - -import android.view.animation.Interpolator; - /** * Timings for the OverviewSplitSelect > confirmed animation on tablets. */ @@ -33,8 +29,4 @@ public class TabletSplitToConfirmTimings public int getStagedRectSlideEnd() { return 383; } public int getDuration() { return TABLET_CONFIRM_DURATION; } - public Interpolator getStagedRectXInterpolator() { return LINEAR; } - public Interpolator getStagedRectYInterpolator() { return LINEAR; } - public Interpolator getStagedRectScaleXInterpolator() { return LINEAR; } - public Interpolator getStagedRectScaleYInterpolator() { return LINEAR; } } From 696fbd66bd281215166258b2de007c14a1cecbfa Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Wed, 5 Oct 2022 16:26:04 -0700 Subject: [PATCH 040/429] Fix bug with DWB banners causing Action Bar to vanish This patch fixes a bug where entering Overview with 3+ DWB banners active would cause the Actions Bar to disappear, rendering it unusable. The bug occurred because while the Actions Bar was animating itself in, the entry animation of the DWB banners caused a competing animation to be fired, which attempted to set the Actions Bar alpha back to 0 in a race-conditiony situation. Fixed by using setAutoCancel() on the Actions View alpha animator, which auto-cancels a running animation when another animation is called on the same target, preventing race conditions. Outstanding issue: 251277899 Fixes: 241163178 Test: Manual Change-Id: I4edb5678b4aad5612cd5ef58141d8e22bf8587f0 --- quickstep/src/com/android/quickstep/views/RecentsView.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index d9a4be8c7e..e344bee176 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -1878,6 +1878,8 @@ public abstract class RecentsView Date: Thu, 6 Oct 2022 17:28:57 -0700 Subject: [PATCH 041/429] Improve splitscreen recents animation in seascape * We need to swap the primary and secondary thumbnail positions in fake seascape since the primary is the visually left app (which is the bottom in portrait) Bug: 249693334 Change-Id: I325133ab86e4fcd26c6162a3de007d68e9ba6bf1 --- .../touch/PortraitPagedViewHandler.java | 10 ++++ .../touch/SeascapePagedViewHandler.java | 47 ++++++++++++++++++- 2 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java index bc1b6345b4..3c386e4129 100644 --- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java +++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java @@ -662,6 +662,16 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { secondarySnapshotHeight = totalThumbnailHeight - primarySnapshotHeight - dividerBar; int translationY = primarySnapshotHeight + spaceAboveSnapshot + dividerBar; secondarySnapshot.setTranslationY(translationY); + + FrameLayout.LayoutParams primaryParams = + (FrameLayout.LayoutParams) primarySnapshot.getLayoutParams(); + FrameLayout.LayoutParams secondaryParams = + (FrameLayout.LayoutParams) secondarySnapshot.getLayoutParams(); + secondaryParams.topMargin = 0; + primaryParams.topMargin = spaceAboveSnapshot; + + // Reset unused translations + primarySnapshot.setTranslationY(0); secondarySnapshot.setTranslationX(0); primarySnapshot.setTranslationX(0); } diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java index 55bb5e85e5..bbdd958c45 100644 --- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java +++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java @@ -121,9 +121,9 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler { // the screen. This is to preserve consistency when the user rotates: From the user's POV, // the primary should always be on the left. if (desiredStagePosition == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) { - outRect.top += (int) (outRect.height() * (topLeftTaskPercent + dividerBarPercent)); + outRect.top += (int) (outRect.height() * ((1 - topLeftTaskPercent))); } else { - outRect.bottom = outRect.top + (int) (outRect.height() * topLeftTaskPercent); + outRect.bottom -= (int) (outRect.height() * (topLeftTaskPercent + dividerBarPercent)); } } @@ -266,6 +266,49 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler { secondaryIconView.setLayoutParams(secondaryIconParams); } + @Override + public void measureGroupedTaskViewThumbnailBounds(View primarySnapshot, View secondarySnapshot, + int parentWidth, int parentHeight, SplitBounds splitBoundsConfig, DeviceProfile dp, + boolean isRtl) { + FrameLayout.LayoutParams primaryParams = + (FrameLayout.LayoutParams) primarySnapshot.getLayoutParams(); + FrameLayout.LayoutParams secondaryParams = + (FrameLayout.LayoutParams) secondarySnapshot.getLayoutParams(); + + // Swap the margins that are set in TaskView#setRecentsOrientedState() + secondaryParams.topMargin = dp.overviewTaskThumbnailTopMarginPx; + primaryParams.topMargin = 0; + + // Measure and layout the thumbnails bottom up, since the primary is on the visual left + // (portrait bottom) and secondary is on the right (portrait top) + int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx; + int totalThumbnailHeight = parentHeight - spaceAboveSnapshot; + int dividerBar = splitBoundsConfig.appsStackedVertically + ? (int) (splitBoundsConfig.dividerHeightPercent * parentHeight) + : (int) (splitBoundsConfig.dividerWidthPercent * parentWidth); + int primarySnapshotHeight; + int primarySnapshotWidth; + int secondarySnapshotHeight; + int secondarySnapshotWidth; + + float taskPercent = splitBoundsConfig.appsStackedVertically ? + splitBoundsConfig.topTaskPercent : splitBoundsConfig.leftTaskPercent; + primarySnapshotWidth = parentWidth; + primarySnapshotHeight = (int) (totalThumbnailHeight * (taskPercent)); + + secondarySnapshotWidth = parentWidth; + secondarySnapshotHeight = totalThumbnailHeight - primarySnapshotHeight - dividerBar; + secondarySnapshot.setTranslationY(0); + primarySnapshot.setTranslationY(secondarySnapshotHeight + spaceAboveSnapshot + dividerBar); + primarySnapshot.measure( + View.MeasureSpec.makeMeasureSpec(primarySnapshotWidth, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(primarySnapshotHeight, View.MeasureSpec.EXACTLY)); + secondarySnapshot.measure( + View.MeasureSpec.makeMeasureSpec(secondarySnapshotWidth, View.MeasureSpec.EXACTLY), + View.MeasureSpec.makeMeasureSpec(secondarySnapshotHeight, + View.MeasureSpec.EXACTLY)); + } + /* ---------- The following are only used by TaskViewTouchHandler. ---------- */ @Override From 8f54d597bfaec7322322c60ef415d2fe0c6e9e7d Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Fri, 7 Oct 2022 14:46:25 -0700 Subject: [PATCH 042/429] Round split layout values instead of using int cast * Silly us, we forgot that int casting always floors. Math.round() does a mathematical round. Fixes: 248575056 Test: Wallpaper no longer bleeds through on split animation. Change-Id: I068c030ce6b86fc12faee7778c0d87a0d5aea487 --- .../android/launcher3/touch/LandscapePagedViewHandler.java | 6 +++--- .../android/launcher3/touch/PortraitPagedViewHandler.java | 6 +++--- .../android/launcher3/touch/SeascapePagedViewHandler.java | 6 +++--- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java index 9afca4f380..ceebc2e168 100644 --- a/src/com/android/launcher3/touch/LandscapePagedViewHandler.java +++ b/src/com/android/launcher3/touch/LandscapePagedViewHandler.java @@ -504,9 +504,9 @@ public class LandscapePagedViewHandler implements PagedOrientationHandler { DeviceProfile dp, boolean isRtl) { int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx; int totalThumbnailHeight = parentHeight - spaceAboveSnapshot; - int dividerBar = splitBoundsConfig.appsStackedVertically - ? (int) (splitBoundsConfig.dividerHeightPercent * parentHeight) - : (int) (splitBoundsConfig.dividerWidthPercent * parentWidth); + int dividerBar = Math.round(totalThumbnailHeight * (splitBoundsConfig.appsStackedVertically + ? splitBoundsConfig.dividerHeightPercent + : splitBoundsConfig.dividerWidthPercent)); int primarySnapshotHeight; int primarySnapshotWidth; int secondarySnapshotHeight; diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java index 3c386e4129..a9ae7dc4bd 100644 --- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java +++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java @@ -630,9 +630,9 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { DeviceProfile dp, boolean isRtl) { int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx; int totalThumbnailHeight = parentHeight - spaceAboveSnapshot; - int dividerBar = splitBoundsConfig.appsStackedVertically - ? (int) (splitBoundsConfig.dividerHeightPercent * parentHeight) - : (int) (splitBoundsConfig.dividerWidthPercent * parentWidth); + int dividerBar = Math.round(splitBoundsConfig.appsStackedVertically + ? splitBoundsConfig.dividerHeightPercent * totalThumbnailHeight + : splitBoundsConfig.dividerWidthPercent * totalThumbnailHeight); int primarySnapshotHeight; int primarySnapshotWidth; int secondarySnapshotHeight; diff --git a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java index bbdd958c45..a616a8b6eb 100644 --- a/src/com/android/launcher3/touch/SeascapePagedViewHandler.java +++ b/src/com/android/launcher3/touch/SeascapePagedViewHandler.java @@ -283,9 +283,9 @@ public class SeascapePagedViewHandler extends LandscapePagedViewHandler { // (portrait bottom) and secondary is on the right (portrait top) int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx; int totalThumbnailHeight = parentHeight - spaceAboveSnapshot; - int dividerBar = splitBoundsConfig.appsStackedVertically - ? (int) (splitBoundsConfig.dividerHeightPercent * parentHeight) - : (int) (splitBoundsConfig.dividerWidthPercent * parentWidth); + int dividerBar = Math.round(totalThumbnailHeight * (splitBoundsConfig.appsStackedVertically + ? splitBoundsConfig.dividerHeightPercent + : splitBoundsConfig.dividerWidthPercent)); int primarySnapshotHeight; int primarySnapshotWidth; int secondarySnapshotHeight; From b1840e3f36ed5ce06984f905abb755cd3d8d275b Mon Sep 17 00:00:00 2001 From: Brandon Dayauon Date: Thu, 6 Oct 2022 09:57:11 -0700 Subject: [PATCH 043/429] Add variable to check if button should apply keyboard insets bug: 251460671 test: manual Change-Id: I90045c96c0fbf385ad8dd5978089491f3f106dd8 --- .../launcher3/allapps/BaseAllAppsContainerView.java | 11 +++++++++++ src/com/android/launcher3/allapps/WorkModeSwitch.java | 7 ++++++- 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java index f08254204e..016c577296 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java @@ -797,6 +797,17 @@ public abstract class BaseAllAppsContainerView workspace and determines if window inset + * should be applied.. ex) the work mode switch. + */ + public void setApplyWindowInset(boolean shouldApplyWindowInset) { + if (mWorkManager.getWorkModeSwitch() != null) { + mWorkManager.getWorkModeSwitch().setApplyWindowInset(shouldApplyWindowInset); + } + } + /** Holds a {@link BaseAllAppsAdapter} and related fields. */ public class AdapterHolder { public static final int MAIN = 0; diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java index 15fb77cfb3..0a938b219f 100644 --- a/src/com/android/launcher3/allapps/WorkModeSwitch.java +++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java @@ -52,6 +52,7 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi private int mFlags; private boolean mWorkEnabled; private boolean mOnWorkTab; + private boolean mApplyWindowInset; public WorkModeSwitch(Context context) { this(context, null, 0); @@ -168,7 +169,7 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi @Override public WindowInsets onApplyWindowInsets(WindowInsets insets) { - if (!Utilities.ATLEAST_R) { + if (!Utilities.ATLEAST_R || !mApplyWindowInset) { return insets; } if (insets.isVisible(WindowInsets.Type.ime())) { @@ -197,4 +198,8 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi private void removeFlag(int flag) { mFlags &= ~flag; } + + public void setApplyWindowInset(boolean applyWindowInset){ + mApplyWindowInset = applyWindowInset; + } } From 9b024eb01f4e4e252f677fba3b7200024715e4a0 Mon Sep 17 00:00:00 2001 From: Holly Sun Date: Fri, 7 Oct 2022 16:40:38 -0700 Subject: [PATCH 044/429] [QL-v2] Use subtitle as hint if title doesn't apply. Test: manual Change-Id: Ib5ace9acda9618de905a85854d92e6f865f5fad0 --- src/com/android/launcher3/allapps/SearchUiManager.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/allapps/SearchUiManager.java b/src/com/android/launcher3/allapps/SearchUiManager.java index 6138bc4a9d..228b02bbc1 100644 --- a/src/com/android/launcher3/allapps/SearchUiManager.java +++ b/src/com/android/launcher3/allapps/SearchUiManager.java @@ -64,7 +64,8 @@ public interface SearchUiManager { /** * sets highlight result's title */ - default void setFocusedResultTitle(@Nullable CharSequence title) { } + default void setFocusedResultTitle( + @Nullable CharSequence title, @Nullable CharSequence subtitle) {} /** Refresh the currently displayed list of results. */ default void refreshResults() {} From 8949c583eeef8ae2c5e896413613b773ae2791af Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Fri, 7 Oct 2022 12:31:20 +0100 Subject: [PATCH 045/429] Fix positioning of split instruction and share targets with taskbar in overview - When taskbar is in overview, overview actions has dedicated space and no need to align to nav buttons - Add a bottom margin to split instruction and share targetse that is equal to the space below overview actions Bug: 245320601 Test: Test split select and share target with different screen sizes Change-Id: I6aec325da9cc4c43c84ba8bed5f0e087c57d6925 --- .../android/quickstep/views/OverviewActionsView.java | 8 ++++++-- .../quickstep/views/SplitInstructionsView.java | 5 ++++- src/com/android/launcher3/DeviceProfile.java | 4 +++- .../launcher3/touch/PortraitPagedViewHandler.java | 11 +++++++++-- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java index abace7cd7d..514d5b98bf 100644 --- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java +++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java @@ -31,6 +31,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Insettable; import com.android.launcher3.R; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.MultiValueAlpha.AlphaProperty; @@ -258,7 +259,9 @@ public class OverviewActionsView extends FrameLayo // If in 3-button mode, shift action buttons to accommodate 3-button layout. // (Special exception for landscape tablets, where there is enough room and we don't need to // shift the action buttons.) - if (mDp.areNavButtonsInline && !largeScreenLandscape) { + if (mDp.areNavButtonsInline && !largeScreenLandscape + // If taskbar is in overview, overview action has dedicated space above nav buttons + && !FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get()) { // Add extra horizontal spacing int additionalPadding = mDp.hotseatBarEndOffset; if (isLayoutRtl()) { @@ -288,7 +291,8 @@ public class OverviewActionsView extends FrameLayo return 0; } - if (!mDp.isGestureMode && mDp.isTaskbarPresent) { + if (!mDp.isGestureMode && mDp.isTaskbarPresent + && !FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get()) { return mDp.getOverviewActionsClaimedSpaceBelow(); } diff --git a/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java b/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java index 27ec01a640..fae96dc49c 100644 --- a/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java +++ b/quickstep/src/com/android/quickstep/views/SplitInstructionsView.java @@ -29,6 +29,7 @@ import androidx.appcompat.widget.AppCompatTextView; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.util.DisplayController; @@ -114,7 +115,9 @@ public class SplitInstructionsView extends FrameLayout { int getThreeButtonNavShift() { DeviceProfile dp = mLauncher.getDeviceProfile(); if ((DisplayController.getNavigationMode(getContext()) == THREE_BUTTONS) - && ((dp.isTwoPanels) || (dp.isTablet && !dp.isLandscape))) { + && ((dp.isTwoPanels) || (dp.isTablet && !dp.isLandscape)) + // If taskbar is in overview, overview action has dedicated space above nav buttons + && !FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get()) { int navButtonWidth = getResources().getDimensionPixelSize( R.dimen.taskbar_nav_buttons_size); int extraMargin = getResources().getDimensionPixelSize( diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 9a1bba97ce..7881a261ad 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -1272,7 +1272,9 @@ public class DeviceProfile { * Returns the number of pixels required below OverviewActions excluding insets. */ public int getOverviewActionsClaimedSpaceBelow() { - if (isTaskbarPresent && !isGestureMode) { + if (isTaskbarPresent && !isGestureMode + // If taskbar is in overview, overview action has dedicated space above nav buttons + && !FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get()) { // Align vertically to where nav buttons are. return ((taskbarSize - overviewActionsHeight) / 2) + getTaskbarOffsetY(); } diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java index bc1b6345b4..fc3350d09b 100644 --- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java +++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java @@ -50,6 +50,7 @@ import android.widget.LinearLayout; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.SplitConfigurationOptions; import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds; @@ -524,7 +525,9 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { out.setRotation(getDegreesRotated()); int distanceToEdge; if ((DisplayController.getNavigationMode(out.getContext()) == THREE_BUTTONS) - && (dp.isTwoPanels || dp.isTablet)) { + && (dp.isTwoPanels || dp.isTablet) + // If taskbar is in overview, overview action has dedicated space above nav buttons + && !FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get()) { // If 3-button nav is active, align the splitInstructionsView with it. distanceToEdge = dp.getTaskbarOffsetY() + ((dp.taskbarSize - splitInstructionsHeight) / 2); @@ -561,8 +564,12 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { int insetCorrectionX = (dp.getInsets().right - dp.getInsets().left) / 2; // Adjust for any insets on the bottom edge int insetCorrectionY = dp.getInsets().bottom; + // Adjust for taskbar in overview + int taskbarCorrectionY = + dp.isTaskbarPresent && FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get() + ? dp.taskbarSize : 0; out.setTranslationX(insetCorrectionX + threeButtonNavShift); - out.setTranslationY(-distanceToEdge + insetCorrectionY); + out.setTranslationY(-distanceToEdge + insetCorrectionY - taskbarCorrectionY); FrameLayout.LayoutParams lp = (FrameLayout.LayoutParams) out.getLayoutParams(); lp.gravity = CENTER_HORIZONTAL | BOTTOM; out.setLayoutParams(lp); From 897d7d4d859731ed0b4080179c3e2b207f6e156c Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sun, 9 Oct 2022 22:33:43 -0700 Subject: [PATCH 046/429] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I7a6bab3de85a4fd441ecc3e9bdabd2d1a901e853 --- res/values-as/strings.xml | 2 +- res/values-te/strings.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index 0add9ae6af..ab9ef5dfe3 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -110,7 +110,7 @@ "জাননী বিন্দু" "অন আছে" "অফ আছে" - "জাননী চাবলৈ অনুমতিৰ প্ৰয়োজন" + "জাননীৰ এক্সেছৰ প্ৰয়োজন" "জাননী সম্পৰ্কীয় বিন্দুবোৰ দেখুৱাবলৈ %1$sৰ বাবে এপৰ জাননীসমূহ অন কৰক" "ছেটিং সলনি কৰক" "জাননী বিন্দু দেখুৱাওক" diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index 8a9cfbe2c0..c26437120c 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -58,7 +58,7 @@ "విడ్జెట్ సెట్టింగ్‌లను మార్చండి" "యాప్‌ల కోసం సెర్చ్ చేయండి" "అప్లికేషన్‌లను లోడ్ చేస్తోంది…" - "\"%1$s\"కి సరిపోలే అప్లికేషన్‌లేవీ కనుగొనబడలేదు" + "\"%1$s\"కి మ్యాచ్ అయ్యే అప్లికేషన్‌లేవీ కనుగొనబడలేదు" "మరిన్ని యాప్‌ల కోసం సెర్చ్ చేయండి" "యాప్" "అన్ని యాప్‌లు" @@ -147,12 +147,12 @@ "ఈ పేరుతో ఫోల్డర్‌ను క్రియేట్ చేయండి: %1$s" "ఫోల్డర్ క్రియేట్ చేయబడింది" "మొదటి స్క్రీన్‌కు తరలించండి" - "పరిమాణం మార్చు" + "సైజ్‌ మార్చు" "వెడల్పును పెంచు" "ఎత్తును పెంచు" "వెడల్పును తగ్గించు" "ఎత్తును తగ్గించు" - "విడ్జెట్ పరిమాణం వెడల్పు %1$sకి, ఎత్తు %2$sకి మార్చబడింది" + "విడ్జెట్ సైజ్‌ వెడల్పు %1$sకి, ఎత్తు %2$sకి మార్చబడింది" "షార్ట్‌కట్స్" "షార్ట్‌కట్‌లు మరియు నోటిఫికేషన్‌లు" "తీసివేయండి" From 50c515b16440a57134dc9f599bb69fd6705c5732 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sun, 9 Oct 2022 22:34:15 -0700 Subject: [PATCH 047/429] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I8ca4ae6223e9c9e3f965c1374e73ed80d65c636d --- res/values-as/strings.xml | 2 +- res/values-te/strings.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index eee5ae27d0..0a4943ecf7 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -109,7 +109,7 @@ "জাননী বিন্দু" "অন আছে" "অফ আছে" - "জাননী চাবলৈ অনুমতিৰ প্ৰয়োজন" + "জাননীৰ এক্সেছৰ প্ৰয়োজন" "জাননী সম্পৰ্কীয় বিন্দুবোৰ দেখুৱাবলৈ %1$sৰ বাবে এপৰ জাননীসমূহ অন কৰক" "ছেটিং সলনি কৰক" "জাননী বিন্দু দেখুৱাওক" diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index e70466f24b..605278f8e7 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -58,7 +58,7 @@ "విడ్జెట్ సెట్టింగ్‌లను మార్చండి" "యాప్‌ల కోసం సెర్చ్ చేయండి" "అప్లికేషన్‌లను లోడ్ చేస్తోంది…" - "\"%1$s\"కి సరిపోలే అప్లికేషన్‌లేవీ కనుగొనబడలేదు" + "\"%1$s\"కి మ్యాచ్ అయ్యే అప్లికేషన్‌లేవీ కనుగొనబడలేదు" "యాప్" "అన్ని యాప్‌లు" "నోటిఫికేషన్‌లు" @@ -146,12 +146,12 @@ "ఈ పేరుతో ఫోల్డర్‌ను క్రియేట్ చేయండి: %1$s" "ఫోల్డర్ క్రియేట్ చేయబడింది" "మొదటి స్క్రీన్‌కు తరలించండి" - "పరిమాణం మార్చు" + "సైజ్‌ మార్చు" "వెడల్పును పెంచు" "ఎత్తును పెంచు" "వెడల్పును తగ్గించు" "ఎత్తును తగ్గించు" - "విడ్జెట్ పరిమాణం వెడల్పు %1$sకి, ఎత్తు %2$sకి మార్చబడింది" + "విడ్జెట్ సైజ్‌ వెడల్పు %1$sకి, ఎత్తు %2$sకి మార్చబడింది" "షార్ట్‌కట్స్" "షార్ట్‌కట్‌లు మరియు నోటిఫికేషన్‌లు" "తీసివేయండి" From 63438f1c65d08388717bc3f3fcb69d8314ed7835 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sun, 9 Oct 2022 22:34:48 -0700 Subject: [PATCH 048/429] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I867e47ef07267f94bc4a7d4c1fab5cfb3dd6cd85 --- res/values-as/strings.xml | 2 +- res/values-te/strings.xml | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index 0add9ae6af..ab9ef5dfe3 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -110,7 +110,7 @@ "জাননী বিন্দু" "অন আছে" "অফ আছে" - "জাননী চাবলৈ অনুমতিৰ প্ৰয়োজন" + "জাননীৰ এক্সেছৰ প্ৰয়োজন" "জাননী সম্পৰ্কীয় বিন্দুবোৰ দেখুৱাবলৈ %1$sৰ বাবে এপৰ জাননীসমূহ অন কৰক" "ছেটিং সলনি কৰক" "জাননী বিন্দু দেখুৱাওক" diff --git a/res/values-te/strings.xml b/res/values-te/strings.xml index 8a9cfbe2c0..c26437120c 100644 --- a/res/values-te/strings.xml +++ b/res/values-te/strings.xml @@ -58,7 +58,7 @@ "విడ్జెట్ సెట్టింగ్‌లను మార్చండి" "యాప్‌ల కోసం సెర్చ్ చేయండి" "అప్లికేషన్‌లను లోడ్ చేస్తోంది…" - "\"%1$s\"కి సరిపోలే అప్లికేషన్‌లేవీ కనుగొనబడలేదు" + "\"%1$s\"కి మ్యాచ్ అయ్యే అప్లికేషన్‌లేవీ కనుగొనబడలేదు" "మరిన్ని యాప్‌ల కోసం సెర్చ్ చేయండి" "యాప్" "అన్ని యాప్‌లు" @@ -147,12 +147,12 @@ "ఈ పేరుతో ఫోల్డర్‌ను క్రియేట్ చేయండి: %1$s" "ఫోల్డర్ క్రియేట్ చేయబడింది" "మొదటి స్క్రీన్‌కు తరలించండి" - "పరిమాణం మార్చు" + "సైజ్‌ మార్చు" "వెడల్పును పెంచు" "ఎత్తును పెంచు" "వెడల్పును తగ్గించు" "ఎత్తును తగ్గించు" - "విడ్జెట్ పరిమాణం వెడల్పు %1$sకి, ఎత్తు %2$sకి మార్చబడింది" + "విడ్జెట్ సైజ్‌ వెడల్పు %1$sకి, ఎత్తు %2$sకి మార్చబడింది" "షార్ట్‌కట్స్" "షార్ట్‌కట్‌లు మరియు నోటిఫికేషన్‌లు" "తీసివేయండి" From 0e4f04d85f8653863d250a8f0eab2aeccd8b1326 Mon Sep 17 00:00:00 2001 From: Andras Kloczl Date: Mon, 11 Jul 2022 13:06:39 +0000 Subject: [PATCH 049/429] Fix flaky/failing two panel TAPL tests Since Cuttlefish emulators are quite slow, some of the two panel related TAPL tests were failing due to multiple page changes instead of single ones. Test: atest -c NexusLauncherTests:com.android.launcher3.ui.workspace.TwoPanelWorkspaceTest Bug: 236136463 Fix: 252747355 Change-Id: Ib154cf97040fcea3b4d2d7082352c06de74f8c2a (cherry picked from commit 486f7c8766bdc9400faa49e13caa39a81021132b) Merged-In: Ib154cf97040fcea3b4d2d7082352c06de74f8c2a --- .../dragndrop/SpringLoadedDragController.java | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/src/com/android/launcher3/dragndrop/SpringLoadedDragController.java b/src/com/android/launcher3/dragndrop/SpringLoadedDragController.java index fb8a1bc99e..08e50dd96d 100644 --- a/src/com/android/launcher3/dragndrop/SpringLoadedDragController.java +++ b/src/com/android/launcher3/dragndrop/SpringLoadedDragController.java @@ -20,12 +20,14 @@ import com.android.launcher3.Alarm; import com.android.launcher3.CellLayout; import com.android.launcher3.Launcher; import com.android.launcher3.OnAlarmListener; +import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; public class SpringLoadedDragController implements OnAlarmListener { // how long the user must hover over a mini-screen before it unshrinks - final long ENTER_SPRING_LOAD_HOVER_TIME = 500; - final long ENTER_SPRING_LOAD_CANCEL_HOVER_TIME = 950; + private static final long ENTER_SPRING_LOAD_HOVER_TIME = 500; + private static final long ENTER_SPRING_LOAD_HOVER_TIME_IN_TEST = 1500; + private static final long ENTER_SPRING_LOAD_CANCEL_HOVER_TIME = 950; Alarm mAlarm; @@ -39,6 +41,13 @@ public class SpringLoadedDragController implements OnAlarmListener { mAlarm.setOnAlarmListener(this); } + private long getEnterSpringLoadHoverTime() { + // Some TAPL tests are flaky on Cuttlefish with a low waiting time + return Utilities.IS_RUNNING_IN_TEST_HARNESS + ? ENTER_SPRING_LOAD_HOVER_TIME_IN_TEST + : ENTER_SPRING_LOAD_HOVER_TIME; + } + public void cancel() { mAlarm.cancelAlarm(); } @@ -46,8 +55,8 @@ public class SpringLoadedDragController implements OnAlarmListener { // Set a new alarm to expire for the screen that we are hovering over now public void setAlarm(CellLayout cl) { mAlarm.cancelAlarm(); - mAlarm.setAlarm((cl == null) ? ENTER_SPRING_LOAD_CANCEL_HOVER_TIME : - ENTER_SPRING_LOAD_HOVER_TIME); + mAlarm.setAlarm((cl == null) ? ENTER_SPRING_LOAD_CANCEL_HOVER_TIME + : getEnterSpringLoadHoverTime()); mScreen = cl; } From 3c59d9b345d918eaff121d18bf3f156f4522ed91 Mon Sep 17 00:00:00 2001 From: Ats Jenk Date: Thu, 22 Sep 2022 11:47:47 -0700 Subject: [PATCH 050/429] Desktop tile that is a snapshot of desktop Create a desktop recents tile that shows a snapshot of the freeform tasks running on desktop. Scales them down and positions them in the same location as they would be on the desktop. Bug: 244348395 Test: manual Change-Id: Ieb5830a331691844769003189f557c4b7e4cd35c --- quickstep/res/layout/task_desktop.xml | 46 ++ .../android/quickstep/AbsSwipeUpHandler.java | 1 + .../android/quickstep/RecentTasksList.java | 28 +- .../com/android/quickstep/TaskViewUtils.java | 18 +- .../android/quickstep/util/DesktopTask.java | 56 +++ .../com/android/quickstep/util/GroupTask.java | 40 +- .../quickstep/views/DesktopTaskView.java | 467 ++++++++++++++++++ .../quickstep/views/GroupedTaskView.java | 6 + .../android/quickstep/views/RecentsView.java | 65 ++- .../com/android/quickstep/views/TaskView.java | 43 +- .../launcher3/model/data/ItemInfo.java | 8 +- 11 files changed, 718 insertions(+), 60 deletions(-) create mode 100644 quickstep/res/layout/task_desktop.xml create mode 100644 quickstep/src/com/android/quickstep/util/DesktopTask.java create mode 100644 quickstep/src/com/android/quickstep/views/DesktopTaskView.java diff --git a/quickstep/res/layout/task_desktop.xml b/quickstep/res/layout/task_desktop.xml new file mode 100644 index 0000000000..0c8543f414 --- /dev/null +++ b/quickstep/res/layout/task_desktop.xml @@ -0,0 +1,46 @@ + + + + + + + + + + + diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 9106a8fc15..7e5201c4c5 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -1829,6 +1829,7 @@ public abstract class AbsSwipeUpHandler, } private void finishCurrentTransitionToRecents() { + // TODO(b/245569277#comment2): enable once isFreeformActive is implemented mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED); if (mRecentsAnimationController != null) { mRecentsAnimationController.detachNavigationBarFromApp(true); diff --git a/quickstep/src/com/android/quickstep/RecentTasksList.java b/quickstep/src/com/android/quickstep/RecentTasksList.java index 6b616b1b07..7bcc661af7 100644 --- a/quickstep/src/com/android/quickstep/RecentTasksList.java +++ b/quickstep/src/com/android/quickstep/RecentTasksList.java @@ -17,6 +17,8 @@ package com.android.quickstep; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; +import static com.android.quickstep.views.DesktopTaskView.DESKTOP_MODE_SUPPORTED; +import static com.android.wm.shell.util.GroupedRecentTaskInfo.TYPE_FREEFORM; import android.annotation.TargetApi; import android.app.ActivityManager; @@ -30,6 +32,7 @@ import androidx.annotation.VisibleForTesting; import com.android.launcher3.util.LooperExecutor; import com.android.launcher3.util.SplitConfigurationOptions; +import com.android.quickstep.util.DesktopTask; import com.android.quickstep.util.GroupTask; import com.android.systemui.shared.recents.model.Task; import com.android.wm.shell.recents.IRecentTasksListener; @@ -253,8 +256,9 @@ public class RecentTasksList { }; TaskLoadResult allTasks = new TaskLoadResult(requestId, loadKeysOnly, rawTasks.size()); + for (GroupedRecentTaskInfo rawTask : rawTasks) { - if (rawTask.getType() == GroupedRecentTaskInfo.TYPE_FREEFORM) { + if (DESKTOP_MODE_SUPPORTED && rawTask.getType() == TYPE_FREEFORM) { GroupTask desktopTask = createDesktopTask(rawTask); allTasks.add(desktopTask); continue; @@ -284,14 +288,18 @@ public class RecentTasksList { return allTasks; } - private GroupTask createDesktopTask(GroupedRecentTaskInfo taskInfo) { - // TODO(b/244348395): create a subclass of GroupTask for desktop tile - // We need a single task information as the primary task. Use the first task - Task.TaskKey key = new Task.TaskKey(taskInfo.getTaskInfo1()); - Task task = new Task(key); - task.desktopTile = true; - task.topActivity = key.sourceComponent; - return new GroupTask(task, null, null); + private DesktopTask createDesktopTask(GroupedRecentTaskInfo recentTaskInfo) { + ArrayList tasks = new ArrayList<>(recentTaskInfo.getTaskInfoList().size()); + for (ActivityManager.RecentTaskInfo taskInfo : recentTaskInfo.getTaskInfoList()) { + Task.TaskKey key = new Task.TaskKey(taskInfo); + Task task = Task.from(key, taskInfo, false); + task.setLastSnapshotData(taskInfo); + task.positionInParent = taskInfo.positionInParent; + task.appBounds = taskInfo.configuration.windowConfiguration.getAppBounds(); + // TODO(b/244348395): tasks should be sorted from oldest to most recently used + tasks.add(task); + } + return new DesktopTask(tasks); } private SplitConfigurationOptions.SplitBounds convertSplitBounds( @@ -306,7 +314,7 @@ public class RecentTasksList { private ArrayList copyOf(ArrayList tasks) { ArrayList newTasks = new ArrayList<>(); for (int i = 0; i < tasks.size(); i++) { - newTasks.add(new GroupTask(tasks.get(i))); + newTasks.add(tasks.get(i).copy()); } return newTasks; } diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java index 7d3d8a2ede..df80e2f867 100644 --- a/quickstep/src/com/android/quickstep/TaskViewUtils.java +++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java @@ -302,9 +302,15 @@ public final class TaskViewUtils { // to follow the TaskViewSimulator. So the final matrix applied on the thumbnailView is: // Mt K(0)` K(t) Mt` TaskThumbnailView[] thumbnails = v.getThumbnails(); - Matrix[] mt = new Matrix[simulatorCopies.length]; - Matrix[] mti = new Matrix[simulatorCopies.length]; - for (int i = 0; i < thumbnails.length; i++) { + + // In case simulator copies and thumbnail size do no match, ensure we get the lesser. + // This ensures we do not create arrays with empty elements or attempt to references + // indexes out of array bounds. + final int matrixSize = Math.min(simulatorCopies.length, thumbnails.length); + + Matrix[] mt = new Matrix[matrixSize]; + Matrix[] mti = new Matrix[matrixSize]; + for (int i = 0; i < matrixSize; i++) { TaskThumbnailView ttv = thumbnails[i]; RectF localBounds = new RectF(0, 0, ttv.getWidth(), ttv.getHeight()); float[] tvBoundsMapped = new float[]{0, 0, ttv.getWidth(), ttv.getHeight()}; @@ -321,14 +327,14 @@ public final class TaskViewUtils { mti[i] = localMti; } - Matrix[] k0i = new Matrix[simulatorCopies.length]; - for (int i = 0; i < simulatorCopies.length; i++) { + Matrix[] k0i = new Matrix[matrixSize]; + for (int i = 0; i < matrixSize; i++) { k0i[i] = new Matrix(); simulatorCopies[i].getTaskViewSimulator().getCurrentMatrix().invert(k0i[i]); } Matrix animationMatrix = new Matrix(); out.addOnFrameCallback(() -> { - for (int i = 0; i < simulatorCopies.length; i++) { + for (int i = 0; i < matrixSize; i++) { animationMatrix.set(mt[i]); animationMatrix.postConcat(k0i[i]); animationMatrix.postConcat(simulatorCopies[i] diff --git a/quickstep/src/com/android/quickstep/util/DesktopTask.java b/quickstep/src/com/android/quickstep/util/DesktopTask.java new file mode 100644 index 0000000000..433d23fa97 --- /dev/null +++ b/quickstep/src/com/android/quickstep/util/DesktopTask.java @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2022 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 com.android.quickstep.views.TaskView; +import com.android.systemui.shared.recents.model.Task; + +import java.util.ArrayList; + +/** + * A {@link Task} container that can contain N number of tasks that are part of the desktop in + * recent tasks list. + */ +public class DesktopTask extends GroupTask { + + public ArrayList tasks; + + public DesktopTask(ArrayList tasks) { + super(tasks.get(0), null, null, TaskView.Type.DESKTOP); + this.tasks = tasks; + } + + @Override + public boolean containsTask(int taskId) { + for (Task task : tasks) { + if (task.key.id == taskId) { + return true; + } + } + return false; + } + + @Override + public boolean hasMultipleTasks() { + return true; + } + + @Override + public DesktopTask copy() { + return new DesktopTask(tasks); + } +} diff --git a/quickstep/src/com/android/quickstep/util/GroupTask.java b/quickstep/src/com/android/quickstep/util/GroupTask.java index f30d00c722..2be4f0a519 100644 --- a/quickstep/src/com/android/quickstep/util/GroupTask.java +++ b/quickstep/src/com/android/quickstep/util/GroupTask.java @@ -20,6 +20,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds; +import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.Task; /** @@ -27,24 +28,25 @@ import com.android.systemui.shared.recents.model.Task; * are represented as an app-pair in the recents task list. */ public class GroupTask { - public @NonNull Task task1; - public @Nullable Task task2; - public @Nullable - SplitBounds mSplitBounds; + @NonNull + public final Task task1; + @Nullable + public final Task task2; + @Nullable + public final SplitBounds mSplitBounds; + @TaskView.Type + public final int taskViewType; - public GroupTask(@NonNull Task t1, @Nullable Task t2, - @Nullable SplitBounds splitBounds) { + public GroupTask(@NonNull Task t1, @Nullable Task t2, @Nullable SplitBounds splitBounds) { + this(t1, t2, splitBounds, t2 != null ? TaskView.Type.GROUPED : TaskView.Type.SINGLE); + } + + protected GroupTask(@NonNull Task t1, @Nullable Task t2, @Nullable SplitBounds splitBounds, + @TaskView.Type int taskViewType) { task1 = t1; task2 = t2; mSplitBounds = splitBounds; - } - - public GroupTask(@NonNull GroupTask group) { - task1 = new Task(group.task1); - task2 = group.task2 != null - ? new Task(group.task2) - : null; - mSplitBounds = group.mSplitBounds; + this.taskViewType = taskViewType; } public boolean containsTask(int taskId) { @@ -54,4 +56,14 @@ public class GroupTask { public boolean hasMultipleTasks() { return task2 != null; } + + /** + * Create a copy of this instance + */ + public GroupTask copy() { + return new GroupTask( + new Task(task1), + task2 != null ? new Task(task2) : null, + mSplitBounds); + } } diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java new file mode 100644 index 0000000000..9874f9644a --- /dev/null +++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java @@ -0,0 +1,467 @@ +/* + * Copyright (C) 2022 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.views; + +import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT; + +import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED; + +import android.content.Context; +import android.graphics.Point; +import android.graphics.Rect; +import android.graphics.drawable.ShapeDrawable; +import android.graphics.drawable.shapes.RoundRectShape; +import android.os.SystemProperties; +import android.util.AttributeSet; +import android.util.Log; +import android.util.SparseArray; +import android.view.MotionEvent; + +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; + +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.Utilities; +import com.android.launcher3.touch.PagedOrientationHandler; +import com.android.launcher3.util.RunnableList; +import com.android.quickstep.RecentsModel; +import com.android.quickstep.SystemUiProxy; +import com.android.quickstep.TaskThumbnailCache; +import com.android.quickstep.util.CancellableTask; +import com.android.quickstep.util.RecentsOrientedState; +import com.android.systemui.shared.recents.model.Task; +import com.android.systemui.shared.recents.model.ThumbnailData; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.function.Consumer; + +/** + * TaskView that contains all tasks that are part of the desktop. + */ +// TODO(b/249371338): TaskView needs to be refactored to have better support for N tasks. +public class DesktopTaskView extends TaskView { + + /** Flag to indicate whether desktop mode is available on the device */ + public static final boolean DESKTOP_MODE_SUPPORTED = SystemProperties.getBoolean( + "persist.wm.debug.desktop_mode", false); + + private static final String TAG = DesktopTaskView.class.getSimpleName(); + + private static final boolean DEBUG = true; + + private List mTasks; + + private final ArrayList mSnapshotViews = new ArrayList<>(); + + /** Maps {@code taskIds} to corresponding {@link TaskThumbnailView}s */ + private final SparseArray mSnapshotViewMap = new SparseArray<>(); + + private final ArrayList> mPendingThumbnailRequests = new ArrayList<>(); + + public DesktopTaskView(Context context) { + this(context, null); + } + + public DesktopTaskView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public DesktopTaskView(Context context, AttributeSet attrs, int defStyleAttr) { + super(context, attrs, defStyleAttr); + } + + @Override + protected void onFinishInflate() { + super.onFinishInflate(); + float[] outerRadii = new float[8]; + Arrays.fill(outerRadii, getTaskCornerRadius()); + RoundRectShape shape = new RoundRectShape(outerRadii, null, null); + ShapeDrawable background = new ShapeDrawable(shape); + background.setTint(getResources().getColor(android.R.color.system_neutral2_300)); + // TODO(b/244348395): this should be wallpaper + setBackground(background); + + mSnapshotViews.add(mSnapshotView); + } + + @Override + public void bind(Task task, RecentsOrientedState orientedState) { + bind(Collections.singletonList(task), orientedState); + } + + /** + * Updates this desktop task to the gives task list defined in {@code tasks} + */ + public void bind(List tasks, RecentsOrientedState orientedState) { + if (DEBUG) { + StringBuilder sb = new StringBuilder(); + sb.append("bind tasks=").append(tasks.size()).append("\n"); + for (Task task : tasks) { + sb.append(" key=").append(task.key).append("\n"); + } + Log.d(TAG, sb.toString()); + } + if (tasks.isEmpty()) { + return; + } + cancelPendingLoadTasks(); + + mTasks = tasks; + mSnapshotViewMap.clear(); + + // Ensure there are equal number of snapshot views and tasks. + // More tasks than views, add views. More views than tasks, remove views. + // TODO(b/251586230): use a ViewPool for creating TaskThumbnailViews + if (mSnapshotViews.size() > mTasks.size()) { + int diff = mSnapshotViews.size() - mTasks.size(); + for (int i = 0; i < diff; i++) { + TaskThumbnailView snapshotView = mSnapshotViews.remove(0); + removeView(snapshotView); + } + } else if (mSnapshotViews.size() < mTasks.size()) { + int diff = mTasks.size() - mSnapshotViews.size(); + for (int i = 0; i < diff; i++) { + TaskThumbnailView snapshotView = new TaskThumbnailView(getContext()); + mSnapshotViews.add(snapshotView); + addView(snapshotView, new LayoutParams(WRAP_CONTENT, WRAP_CONTENT)); + } + } + + for (int i = 0; i < mTasks.size(); i++) { + Task task = mTasks.get(i); + TaskThumbnailView snapshotView = mSnapshotViews.get(i); + snapshotView.bind(task); + mSnapshotViewMap.put(task.key.id, snapshotView); + } + + updateTaskIdContainer(); + updateTaskIdAttributeContainer(); + + setOrientationState(orientedState); + } + + private void updateTaskIdContainer() { + // TODO(b/249371338): TaskView expects the array to have at least 2 elements. + // At least 2 elements in the array + mTaskIdContainer = new int[Math.max(mTasks.size(), 2)]; + for (int i = 0; i < mTasks.size(); i++) { + mTaskIdContainer[i] = mTasks.get(i).key.id; + } + } + + private void updateTaskIdAttributeContainer() { + // TODO(b/249371338): TaskView expects the array to have at least 2 elements. + // At least 2 elements in the array + mTaskIdAttributeContainer = new TaskIdAttributeContainer[Math.max(mTasks.size(), 2)]; + for (int i = 0; i < mTasks.size(); i++) { + Task task = mTasks.get(i); + TaskThumbnailView thumbnailView = mSnapshotViewMap.get(task.key.id); + mTaskIdAttributeContainer[i] = createAttributeContainer(task, thumbnailView); + } + } + + private TaskIdAttributeContainer createAttributeContainer(Task task, + TaskThumbnailView thumbnailView) { + return new TaskIdAttributeContainer(task, thumbnailView, null, STAGE_POSITION_UNDEFINED); + } + + @Nullable + @Override + public Task getTask() { + // TODO(b/249371338): returning first task. This won't work well with multiple tasks. + return mTasks.size() > 0 ? mTasks.get(0) : null; + } + + @Override + public TaskThumbnailView getThumbnail() { + // TODO(b/249371338): returning single thumbnail. This won't work well with multiple tasks. + Task task = getTask(); + if (task != null) { + return mSnapshotViewMap.get(task.key.id); + } + return null; + } + + @Override + public boolean containsTaskId(int taskId) { + // Thumbnail map contains taskId -> thumbnail map. Use the keys for contains + return mSnapshotViewMap.contains(taskId); + } + + @Override + public void onTaskListVisibilityChanged(boolean visible, int changes) { + cancelPendingLoadTasks(); + if (visible) { + RecentsModel model = RecentsModel.INSTANCE.get(getContext()); + TaskThumbnailCache thumbnailCache = model.getThumbnailCache(); + + if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) { + for (Task task : mTasks) { + CancellableTask thumbLoadRequest = + thumbnailCache.updateThumbnailInBackground(task, thumbnailData -> { + TaskThumbnailView thumbnailView = mSnapshotViewMap.get(task.key.id); + if (thumbnailView != null) { + thumbnailView.setThumbnail(task, thumbnailData); + } + }); + if (thumbLoadRequest != null) { + mPendingThumbnailRequests.add(thumbLoadRequest); + } + } + } + } else { + if (needsUpdate(changes, FLAG_UPDATE_THUMBNAIL)) { + for (Task task : mTasks) { + TaskThumbnailView thumbnailView = mSnapshotViewMap.get(task.key.id); + if (thumbnailView != null) { + thumbnailView.setThumbnail(null, null); + } + // Reset the task thumbnail ref + task.thumbnail = null; + } + } + } + } + + @Override + public void setOrientationState(RecentsOrientedState orientationState) { + // TODO(b/249371338): this copies logic from TaskView + PagedOrientationHandler orientationHandler = orientationState.getOrientationHandler(); + boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; + DeviceProfile deviceProfile = mActivity.getDeviceProfile(); + + LayoutParams iconParams = (LayoutParams) mIconView.getLayoutParams(); + + int thumbnailTopMargin = deviceProfile.overviewTaskThumbnailTopMarginPx; + int taskIconHeight = deviceProfile.overviewTaskIconSizePx; + int taskMargin = deviceProfile.overviewTaskMarginPx; + + orientationHandler.setTaskIconParams(iconParams, taskMargin, taskIconHeight, + thumbnailTopMargin, isRtl); + + LayoutParams snapshotParams = (LayoutParams) mSnapshotView.getLayoutParams(); + snapshotParams.topMargin = thumbnailTopMargin; + + for (int i = 0; i < mSnapshotViewMap.size(); i++) { + TaskThumbnailView thumbnailView = mSnapshotViewMap.valueAt(i); + thumbnailView.setLayoutParams(snapshotParams); + } + } + + @Override + protected void cancelPendingLoadTasks() { + for (CancellableTask cancellableTask : mPendingThumbnailRequests) { + cancellableTask.cancel(); + } + mPendingThumbnailRequests.clear(); + } + + @Override + public boolean offerTouchToChildren(MotionEvent event) { + return false; + } + + @Override + protected boolean showTaskMenuWithContainer(IconView iconView) { + return false; + } + + @Nullable + @Override + public RunnableList launchTaskAnimated() { + RunnableList endCallback = new RunnableList(); + SystemUiProxy.INSTANCE.get(getContext()).showDesktopApps(); + RecentsView recentsView = getRecentsView(); + recentsView.addSideTaskLaunchCallback(endCallback); + return endCallback; + } + + @Override + public void launchTask(@NonNull Consumer callback, boolean freezeTaskList) { + SystemUiProxy.INSTANCE.get(getContext()).showDesktopApps(); + callback.accept(true); + } + + @Override + void refreshThumbnails(@Nullable HashMap thumbnailDatas) { + // Sets new thumbnails based on the incoming data and refreshes the rest. + // Create a copy of the thumbnail map, so we can track thumbnails that need refreshing. + SparseArray thumbnailsToRefresh = mSnapshotViewMap.clone(); + if (thumbnailDatas != null) { + for (Task task : mTasks) { + int key = task.key.id; + TaskThumbnailView thumbnailView = thumbnailsToRefresh.get(key); + ThumbnailData thumbnailData = thumbnailDatas.get(key); + if (thumbnailView != null && thumbnailData != null) { + thumbnailView.setThumbnail(task, thumbnailData); + // Remove this thumbnail from the list that should be refreshed. + thumbnailsToRefresh.remove(key); + } + } + } + + // Refresh the rest that were not updated. + for (int i = 0; i < thumbnailsToRefresh.size(); i++) { + thumbnailsToRefresh.valueAt(i).refresh(); + } + } + + @Override + public TaskThumbnailView[] getThumbnails() { + TaskThumbnailView[] thumbnails = new TaskThumbnailView[mSnapshotViewMap.size()]; + for (int i = 0; i < thumbnails.length; i++) { + thumbnails[i] = mSnapshotViewMap.valueAt(i); + } + return thumbnails; + } + + @Override + public void onRecycle() { + resetPersistentViewTransforms(); + // Clear any references to the thumbnail (it will be re-read either from the cache or the + // system on next bind) + for (Task task : mTasks) { + TaskThumbnailView thumbnailView = mSnapshotViewMap.get(task.key.id); + if (thumbnailView != null) { + thumbnailView.setThumbnail(task, null); + } + } + setOverlayEnabled(false); + onTaskListVisibilityChanged(false); + } + + @Override + protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { + super.onMeasure(widthMeasureSpec, heightMeasureSpec); + int containerWidth = MeasureSpec.getSize(widthMeasureSpec); + int containerHeight = MeasureSpec.getSize(heightMeasureSpec); + + setMeasuredDimension(containerWidth, containerHeight); + + int thumbnails = mSnapshotViewMap.size(); + if (thumbnails == 0) { + return; + } + + int windowWidth = mActivity.getDeviceProfile().widthPx; + int windowHeight = mActivity.getDeviceProfile().heightPx; + + float scaleWidth = containerWidth / (float) windowWidth; + float scaleHeight = containerHeight / (float) windowHeight; + + if (DEBUG) { + Log.d(TAG, + "onMeasure: container=[" + containerWidth + "," + containerHeight + "] window=[" + + windowWidth + "," + windowHeight + "] scale=[" + scaleWidth + "," + + scaleHeight + "]"); + } + + // Desktop tile is a shrunk down version of launcher and freeform task thumbnails. + for (int i = 0; i < mTasks.size(); i++) { + Task task = mTasks.get(i); + Rect taskSize = task.appBounds; + if (taskSize == null) { + // Default to quarter of the desktop if we did not get app bounds. + taskSize = new Rect(0, 0, windowWidth / 4, windowHeight / 4); + } + + int thumbWidth = (int) (taskSize.width() * scaleWidth); + int thumbHeight = (int) (taskSize.height() * scaleHeight); + + TaskThumbnailView thumbnailView = mSnapshotViewMap.get(task.key.id); + if (thumbnailView != null) { + thumbnailView.measure(MeasureSpec.makeMeasureSpec(thumbWidth, MeasureSpec.EXACTLY), + MeasureSpec.makeMeasureSpec(thumbHeight, MeasureSpec.EXACTLY)); + + // Position the task to the same position as it would be on the desktop + Point positionInParent = task.positionInParent; + if (positionInParent == null) { + positionInParent = new Point(0, 0); + } + int taskX = (int) (positionInParent.x * scaleWidth); + int taskY = (int) (positionInParent.y * scaleHeight); + thumbnailView.setX(taskX); + thumbnailView.setY(taskY); + + if (DEBUG) { + Log.d(TAG, "onMeasure: task=" + task.key + " thumb=[" + thumbWidth + "," + + thumbHeight + "]" + " pos=[" + taskX + "," + taskY + "]"); + } + } + } + } + + @Override + public void setOverlayEnabled(boolean overlayEnabled) { + // Intentional no-op to prevent setting smart actions overlay on thumbnails + } + + @Override + public void setFullscreenProgress(float progress) { + // TODO(b/249371338): this copies parent implementation and makes it work for N thumbs + progress = Utilities.boundToRange(progress, 0, 1); + mFullscreenProgress = progress; + for (int i = 0; i < mSnapshotViewMap.size(); i++) { + TaskThumbnailView thumbnailView = mSnapshotViewMap.valueAt(i); + thumbnailView.getTaskOverlay().setFullscreenProgress(progress); + updateSnapshotRadius(); + } + } + + @Override + protected void updateSnapshotRadius() { + for (int i = 0; i < mSnapshotViewMap.size(); i++) { + mSnapshotViewMap.valueAt(i).setFullscreenParams(mCurrentFullscreenParams); + } + } + + @Override + protected void setIconAndDimTransitionProgress(float progress, boolean invert) { + // no-op + } + + @Override + public void setColorTint(float amount, int tintColor) { + for (int i = 0; i < mSnapshotViewMap.size(); i++) { + mSnapshotViewMap.valueAt(i).setDimAlpha(amount); + } + } + + @Override + protected void applyThumbnailSplashAlpha() { + for (int i = 0; i < mSnapshotViewMap.size(); i++) { + mSnapshotViewMap.valueAt(i).setSplashAlpha(mTaskThumbnailSplashAlpha); + } + } + + @Override + void setThumbnailVisibility(int visibility) { + for (int i = 0; i < mSnapshotViewMap.size(); i++) { + mSnapshotViewMap.valueAt(i).setVisibility(visibility); + } + } + + @Override + protected boolean confirmSecondSplitSelectApp() { + // Desktop tile can't be in split screen + return false; + } +} diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java index 3a5f606467..71b0c60971 100644 --- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java +++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java @@ -224,6 +224,12 @@ public class GroupedTaskView extends TaskView { mSnapshotView2.refresh(); } + @Override + public boolean containsTaskId(int taskId) { + return (mTask != null && mTask.key.id == taskId) + || (mSecondaryTask != null && mSecondaryTask.key.id == taskId); + } + @Override public TaskThumbnailView[] getThumbnails() { return new TaskThumbnailView[]{mSnapshotView, mSnapshotView2}; diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 0e0acf0173..eeaf23821d 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -54,6 +54,7 @@ import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITIO import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK; import static com.android.quickstep.TaskUtils.checkCurrentOrManagedUserId; import static com.android.quickstep.views.ClearAllButton.DISMISS_ALPHA; +import static com.android.quickstep.views.DesktopTaskView.DESKTOP_MODE_SUPPORTED; import static com.android.quickstep.views.OverviewActionsView.FLAG_IS_NOT_TABLET; import static com.android.quickstep.views.OverviewActionsView.FLAG_SINGLE_TASK; import static com.android.quickstep.views.OverviewActionsView.HIDDEN_NON_ZERO_ROTATION; @@ -72,6 +73,7 @@ import android.animation.PropertyValuesHolder; import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.annotation.TargetApi; +import android.app.WindowConfiguration; import android.content.Context; import android.content.LocusId; import android.content.res.Configuration; @@ -171,6 +173,7 @@ import com.android.quickstep.ViewUtils; import com.android.quickstep.util.ActiveGestureErrorDetector; import com.android.quickstep.util.ActiveGestureLog; import com.android.quickstep.util.AnimUtils; +import com.android.quickstep.util.DesktopTask; import com.android.quickstep.util.GroupTask; import com.android.quickstep.util.LayoutUtils; import com.android.quickstep.util.RecentsOrientedState; @@ -195,6 +198,7 @@ import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.wm.shell.pip.IPipAnimationListener; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Objects; @@ -477,10 +481,11 @@ public abstract class RecentsView mTaskViewPool; private final ViewPool mGroupedTaskViewPool; + private final ViewPool mDesktopTaskViewPool; private final TaskOverlayFactory mTaskOverlayFactory; @@ -737,6 +742,8 @@ public abstract class RecentsView(context, this, R.layout.task_grouped, 20 /* max size */, 10 /* initial size */); + mDesktopTaskViewPool = new ViewPool<>(context, this, R.layout.task_desktop, + 5 /* max size */, 1 /* initial size */); mIsRtl = mOrientationHandler.getRecentsRtlSetting(getResources()); setLayoutDirection(mIsRtl ? View.LAYOUT_DIRECTION_RTL : View.LAYOUT_DIRECTION_LTR); @@ -981,6 +988,8 @@ public abstract class RecentsView= 0; i--) { GroupTask groupTask = taskGroups.get(i); - boolean hasMultipleTasks = groupTask.hasMultipleTasks(); - TaskView taskView = getTaskViewFromPool(hasMultipleTasks); + TaskView taskView = getTaskViewFromPool(groupTask.taskViewType); addView(taskView); - if (hasMultipleTasks) { + if (taskView instanceof GroupedTaskView) { boolean firstTaskIsLeftTopTask = groupTask.mSplitBounds.leftTopTaskId == groupTask.task1.key.id; Task leftTopTask = firstTaskIsLeftTopTask ? groupTask.task1 : groupTask.task2; Task rightBottomTask = firstTaskIsLeftTopTask ? groupTask.task2 : groupTask.task1; ((GroupedTaskView) taskView).bind(leftTopTask, rightBottomTask, mOrientationState, groupTask.mSplitBounds); + } else if (taskView instanceof DesktopTaskView) { + ((DesktopTaskView) taskView).bind(((DesktopTask) groupTask).tasks, + mOrientationState); } else { taskView.bind(groupTask.task1, mOrientationState); } } + if (!taskGroups.isEmpty()) { addView(mClearAllButton); } @@ -2123,10 +2134,19 @@ public abstract class RecentsView T getTaskViewFromPool(boolean isGrouped) { - T taskView = isGrouped ? - (T) mGroupedTaskViewPool.getView() : - (T) mTaskViewPool.getView(); + private TaskView getTaskViewFromPool(@TaskView.Type int type) { + TaskView taskView; + switch (type) { + case TaskView.Type.GROUPED: + taskView = mGroupedTaskViewPool.getView(); + break; + case TaskView.Type.DESKTOP: + taskView = mDesktopTaskViewPool.getView(); + break; + case TaskView.Type.SINGLE: + default: + taskView = mTaskViewPool.getView(); + } taskView.setTaskViewId(mTaskViewIdCount); if (mTaskViewIdCount == Integer.MAX_VALUE) { mTaskViewIdCount = 0; @@ -2318,12 +2338,19 @@ public abstract class RecentsView 1; + boolean needDesktopTask = hasDesktopTask(runningTasks); if (shouldAddStubTaskView(runningTasks)) { boolean wasEmpty = getChildCount() == 0; // Add an empty view for now until the task plan is loaded and applied final TaskView taskView; - if (needGroupTaskView) { - taskView = getTaskViewFromPool(true); + if (needDesktopTask) { + taskView = getTaskViewFromPool(TaskView.Type.DESKTOP); + mTmpRunningTasks = Arrays.copyOf(runningTasks, runningTasks.length); + addView(taskView, 0); + ((DesktopTaskView) taskView).bind(Arrays.asList(mTmpRunningTasks), + mOrientationState); + } else if (needGroupTaskView) { + taskView = getTaskViewFromPool(TaskView.Type.GROUPED); mTmpRunningTasks = new Task[]{runningTasks[0], runningTasks[1]}; addView(taskView, 0); // When we create a placeholder task view mSplitBoundsConfig will be null, but with @@ -2332,7 +2359,7 @@ public abstract class RecentsView LauncherAtom.Task.newBuilder() + .setComponentName(component.flattenToShortString()) + .setIndex(screenId)) + .orElse(LauncherAtom.Task.newBuilder())); break; default: break; From efd41a717ecfb8243400dccdc363778e82ac81db Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Mon, 10 Oct 2022 18:45:23 -0700 Subject: [PATCH 051/429] Add ENABLE_TRANSIENT_TASKBAR feature flag. Bug: 252905206 Test: N/A Change-Id: I7995e4fc0a181aee6932e0bee041b74a4241053e --- src/com/android/launcher3/config/FeatureFlags.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 5ee5558b30..3a530affad 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -297,6 +297,9 @@ public final class FeatureFlags { "SHOW_HOME_GARDENING", false, "Show the new home gardening mode"); + public static final BooleanFlag ENABLE_TRANSIENT_TASKBAR = getDebugFlag( + "ENABLE_TRANSIENT_TASKBAR", false, "Enables transient taskbar."); + public static void initialize(Context context) { synchronized (sDebugFlags) { for (DebugFlag flag : sDebugFlags) { From 0733ebd3c1d774786183354cdc8c5e3b93c6d74e Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Fri, 7 Oct 2022 15:11:09 +0100 Subject: [PATCH 052/429] Run setCurrentPage in applyLoadPlan after scroll initialized - Also combined the 2 setCurrentPage call in applyLoadPlan into 1 - Otherwise setCurrentTask may set to page 1 unexpectedly due to page 0's scroll being invalid and out of range Bug: 246283207 Bug: 238461210 Test: Split screen with 2 apps, click back, go to overview again, should snap to focsued task Change-Id: I3b57655c810668fe244659437fbd4a745ca02d21 --- .../RecentsViewStateController.java | 4 +- .../android/quickstep/views/RecentsView.java | 44 +++++++++---------- src/com/android/launcher3/PagedView.java | 4 +- 3 files changed, 26 insertions(+), 26 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index 3fe2e59471..0e1120ba05 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -90,9 +90,9 @@ public final class RecentsViewStateController extends // While animating into recents, update the visible task data as needed builder.addOnFrameCallback(() -> mRecentsView.loadVisibleTaskData(FLAG_UPDATE_ALL)); mRecentsView.updateEmptyMessage(); - // TODO(b/238461210): Remove logging once root cause of flake detected. + // TODO(b/246283207): Remove logging once root cause of flake detected. if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { - Log.d("b/238461210", "RecentsView#setStateWithAnimationInternal getCurrentPage(): " + Log.d("b/246283207", "RecentsView#setStateWithAnimationInternal getCurrentPage(): " + mRecentsView.getCurrentPage() + ", getScrollForPage(getCurrentPage())): " + mRecentsView.getScrollForPage(mRecentsView.getCurrentPage())); diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 0e0acf0173..af577809b8 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -1500,21 +1500,6 @@ public abstract class RecentsView !settlingOnNewTask -> " - + "previousCurrentPage: " + previousCurrentPage - + ", getScrollForPage(previousCurrentPage): " - + getScrollForPage(previousCurrentPage)); - } - setCurrentPage(previousCurrentPage); - } - // Keep same previous focused task TaskView newFocusedTaskView = getTaskViewByTaskId(focusedTaskId); // If the list changed, maybe the focused task doesn't exist anymore @@ -1539,21 +1524,36 @@ public abstract class RecentsView 0) { targetPage = indexOfChild(requireTaskViewAt(0)); } - } else if (currentTaskId != -1) { - currentTaskView = getTaskViewByTaskId(currentTaskId); - if (currentTaskView != null) { - targetPage = indexOfChild(currentTaskView); - } } if (targetPage != -1 && mCurrentPage != targetPage) { - setCurrentPage(targetPage); + int finalTargetPage = targetPage; + runOnPageScrollsInitialized(() -> { + // TODO(b/246283207): Remove logging once root cause of flake detected. + if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { + Log.d("b/246283207", "RecentsView#applyLoadPlan() -> " + + "previousCurrentPage: " + previousCurrentPage + + ", targetPage: " + finalTargetPage + + ", getScrollForPage(targetPage): " + + getScrollForPage(finalTargetPage)); + } + setCurrentPage(finalTargetPage); + }); } if (mIgnoreResetTaskId != -1 && diff --git a/src/com/android/launcher3/PagedView.java b/src/com/android/launcher3/PagedView.java index 377843cb3b..eb68adb3e8 100644 --- a/src/com/android/launcher3/PagedView.java +++ b/src/com/android/launcher3/PagedView.java @@ -772,9 +772,9 @@ public abstract class PagedView extends ViewGrou } if (mScroller.isFinished() && pageScrollChanged) { - // TODO(b/238461210): Remove logging once root cause of flake detected. + // TODO(b/246283207): Remove logging once root cause of flake detected. if (Utilities.IS_RUNNING_IN_TEST_HARNESS && !(this instanceof Workspace)) { - Log.d("b/238461210", this.getClass().getSimpleName() + "#onLayout() -> " + Log.d("b/246283207", this.getClass().getSimpleName() + "#onLayout() -> " + "if(mScroller.isFinished() && pageScrollChanged) -> getNextPage(): " + getNextPage() + ", getScrollForPage(getNextPage()): " + getScrollForPage(getNextPage())); From 68fc44ffadb80bb6bb5c3432092dcc5536cd5f54 Mon Sep 17 00:00:00 2001 From: Sebastian Franco Date: Fri, 23 Sep 2022 17:50:07 -0500 Subject: [PATCH 053/429] Prevent double touch inputs in the BaseDragLayer If you hold a long press and while pressing you start another long press again with another finger, then a new onLongPress event will trigger and in some cases we are not processing that case. By ignoring the evetns with the flag ACTION_OUTSIDE we can prevent such cases. Fix: 247477725 Test: ReorderWidgets Change-Id: I31833bc54db2771809562bd1f92c8523eb2f05ab --- src/com/android/launcher3/views/BaseDragLayer.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 800b1f6ad7..1e154a2dfb 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -273,6 +273,12 @@ public abstract class BaseDragLayer @Override public boolean dispatchTouchEvent(MotionEvent ev) { + if (ev.getActionIndex() > 0) { + // This means there is multiple touch inputs, ignore it, we could also cancel the + // previous touch but the user might cancel the drag by accident. + return true; + } + switch (ev.getAction()) { case ACTION_DOWN: { if ((mTouchDispatchState & TOUCH_DISPATCHING_TO_VIEW_IN_PROGRESS) != 0) { From 517131ae1c634830bffe0e3cf4ce9ff5f03e8efe Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Thu, 6 Oct 2022 17:01:28 +0100 Subject: [PATCH 054/429] Enable taskbar in overview by default - Also changed expectation in test that taskbar is visible in overview Fix: 245320601 Test: presubmit Change-Id: If1ed44f542e5907860f7ab8182e4b45172346f3f --- .../launcher3/config/FeatureFlags.java | 2 +- .../tapl/LauncherInstrumentation.java | 27 +++++++++++-------- 2 files changed, 17 insertions(+), 12 deletions(-) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 3a530affad..030ac7efcc 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -241,7 +241,7 @@ public final class FeatureFlags { "Enables One Search box in Taskbar All Apps."); public static final BooleanFlag ENABLE_TASKBAR_IN_OVERVIEW = getDebugFlag( - "ENABLE_TASKBAR_IN_OVERVIEW", false, + "ENABLE_TASKBAR_IN_OVERVIEW", true, "Enables accessing the system Taskbar in overview."); public static final BooleanFlag ENABLE_SPLIT_FROM_WORKSPACE = getDebugFlag( diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 3545c27d24..677960df96 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -781,7 +781,7 @@ public final class LauncherInstrumentation { waitUntilLauncherObjectGone(APPS_RES_ID); waitUntilLauncherObjectGone(WORKSPACE_RES_ID); waitUntilLauncherObjectGone(WIDGETS_RES_ID); - waitUntilLauncherObjectGone(TASKBAR_RES_ID); + checkTaskbarVisibility(); waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); return waitForLauncherObject(OVERVIEW_RES_ID); @@ -790,7 +790,7 @@ public final class LauncherInstrumentation { waitUntilLauncherObjectGone(APPS_RES_ID); waitUntilLauncherObjectGone(WORKSPACE_RES_ID); waitUntilLauncherObjectGone(WIDGETS_RES_ID); - waitUntilLauncherObjectGone(TASKBAR_RES_ID); + checkTaskbarVisibility(); waitForLauncherObject(SPLIT_PLACEHOLDER_RES_ID); return waitForLauncherObject(OVERVIEW_RES_ID); @@ -799,7 +799,7 @@ public final class LauncherInstrumentation { waitUntilLauncherObjectGone(APPS_RES_ID); waitUntilLauncherObjectGone(WORKSPACE_RES_ID); waitUntilLauncherObjectGone(WIDGETS_RES_ID); - waitUntilLauncherObjectGone(TASKBAR_RES_ID); + checkTaskbarVisibility(); waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); return waitForFallbackLauncherObject(OVERVIEW_RES_ID); @@ -811,14 +811,7 @@ public final class LauncherInstrumentation { waitUntilLauncherObjectGone(WIDGETS_RES_ID); waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); - if (mIgnoreTaskbarVisibility) { - return null; - } - if (isTablet() && !isFallbackOverview()) { - waitForLauncherObject(TASKBAR_RES_ID); - } else { - waitUntilLauncherObjectGone(TASKBAR_RES_ID); - } + checkTaskbarVisibility(); return null; } default: @@ -828,6 +821,18 @@ public final class LauncherInstrumentation { } } + private void checkTaskbarVisibility() { + if (mIgnoreTaskbarVisibility) { + return; + } + + if (isTablet() && !isFallbackOverview()) { + waitForLauncherObject(TASKBAR_RES_ID); + } else { + waitUntilLauncherObjectGone(TASKBAR_RES_ID); + } + } + public void waitForLauncherInitialized() { for (int i = 0; i < 100; ++i) { if (getTestInfo( From d3755f46cc992635a7928376f748e65b5fad0aa3 Mon Sep 17 00:00:00 2001 From: Brandon Dayauon Date: Mon, 29 Aug 2022 11:48:27 -0700 Subject: [PATCH 055/429] Scale icons from search to make app icons big like AA -> workspace when dragging from search. To scale the icon during dragging (instead of long press) I created a scale variable within DragOptions so that right before dragStart gets called in DragController.java (in callOnDragStart()) the dragview scales before dragging.. * note: the scale from search is 1.687 and the scale from allApps is 1.107 - included searchResult and smallSearchResult - Added animation for scaling icon (used Interpolators.EMPHASIZED 500ms as suggested by motion designer) - Cancel animation when drag finishes bug: 222666176 test: Manual - after: https://drive.google.com/file/d/1ZZHnXlzdTxlM-RUIdJ6EOYkPPg6tCUxC/view?usp=sharing before: https://drive.google.com/file/d/1NpBz3kT_slHXtpXObr_G8K6SZYG9_bLX/view?usp=sharing Change-Id: I01309a3be928987ba00422ad947b80a3df865973 --- src/com/android/launcher3/BubbleTextView.java | 5 +++++ src/com/android/launcher3/Workspace.java | 15 ++++++++++++--- .../launcher3/dragndrop/DragController.java | 14 +++++++++++++- .../android/launcher3/dragndrop/DragOptions.java | 6 ++++++ 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index 5fb892554a..c0a00c2784 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -942,6 +942,11 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, return mIconSize; } + public boolean isDisplaySearchResult() { + return mDisplay == DISPLAY_SEARCH_RESULT || + mDisplay == DISPLAY_SEARCH_RESULT_SMALL; + } + private void updateTranslation() { super.setTranslationX(mTranslationForReorderBounce.x + mTranslationForReorderPreview.x + mTranslationForMoveFromCenterAnimation.x diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index b49d64625b..a5eb9e05b8 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -106,6 +106,7 @@ import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.RunnableList; import com.android.launcher3.util.Thunk; import com.android.launcher3.util.WallpaperOffsetInterpolator; +import com.android.launcher3.views.ActivityContext; import com.android.launcher3.widget.LauncherAppWidgetHost; import com.android.launcher3.widget.LauncherAppWidgetHost.ProviderChangedListener; import com.android.launcher3.widget.LauncherAppWidgetHostView; @@ -152,6 +153,8 @@ public class Workspace extends PagedView public static final int DEFAULT_PAGE = 0; + private final int mAllAppsIconSize; + private LayoutTransition mLayoutTransition; @Thunk final WallpaperManager mWallpaperManager; @@ -286,7 +289,7 @@ public class Workspace extends PagedView mLauncher = Launcher.getLauncher(context); mStateTransitionAnimation = new WorkspaceStateTransitionAnimation(mLauncher, this); mWallpaperManager = WallpaperManager.getInstance(context); - + mAllAppsIconSize = mLauncher.getDeviceProfile().allAppsIconSizePx; mWallpaperOffset = new WallpaperOffsetInterpolator(this); setHapticFeedbackEnabled(false); @@ -1671,8 +1674,14 @@ public class Workspace extends PagedView mDragSourceInternal = (ShortcutAndWidgetContainer) child.getParent(); } - if (child instanceof BubbleTextView && !dragOptions.isAccessibleDrag) { - dragOptions.preDragCondition = ((BubbleTextView) child).startLongPressAction(); + if (child instanceof BubbleTextView) { + BubbleTextView btv = (BubbleTextView) child; + if (!dragOptions.isAccessibleDrag) { + dragOptions.preDragCondition = btv.startLongPressAction(); + } + if (btv.isDisplaySearchResult()) { + dragOptions.preDragEndScale = (float) mAllAppsIconSize / btv.getIconSize(); + } } final DragView dv; diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java index 8616f35011..5368397c6d 100644 --- a/src/com/android/launcher3/dragndrop/DragController.java +++ b/src/com/android/launcher3/dragndrop/DragController.java @@ -31,6 +31,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.DragSource; import com.android.launcher3.DropTarget; +import com.android.launcher3.anim.Interpolators; import com.android.launcher3.logging.InstanceId; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; @@ -90,6 +91,8 @@ public abstract class DragController protected boolean mIsInPreDrag; + private final int DRAG_VIEW_SCALE_DURATION_MS = 500; + /** * Interface to receive notifications when a drag starts or stops */ @@ -214,6 +217,15 @@ public abstract class DragController mOptions.preDragCondition.onPreDragEnd(mDragObject, true /* dragStarted*/); } mIsInPreDrag = false; + if (mOptions.preDragEndScale != 0) { + mDragObject.dragView + .animate() + .scaleX(mOptions.preDragEndScale) + .scaleY(mOptions.preDragEndScale) + .setInterpolator(Interpolators.EMPHASIZED) + .setDuration(DRAG_VIEW_SCALE_DURATION_MS) + .start(); + } mDragObject.dragView.onDragStart(); for (DragListener listener : new ArrayList<>(mListeners)) { listener.onDragStart(mDragObject, mOptions); @@ -295,9 +307,9 @@ public abstract class DragController } else if (mIsInPreDrag) { animateDragViewToOriginalPosition(null, null, -1); } + mDragObject.dragView.clearAnimation(); mDragObject.dragView = null; } - // Only end the drag if we are not deferred if (!isDeferred) { callOnDragEnd(); diff --git a/src/com/android/launcher3/dragndrop/DragOptions.java b/src/com/android/launcher3/dragndrop/DragOptions.java index e8ff8da058..1ff433541e 100644 --- a/src/com/android/launcher3/dragndrop/DragOptions.java +++ b/src/com/android/launcher3/dragndrop/DragOptions.java @@ -40,6 +40,12 @@ public class DragOptions { /** Determines when a pre-drag should transition to a drag. By default, this is immediate. */ public PreDragCondition preDragCondition = null; + /** + * A drag scale that scales the original drag view size when the preDragCondition is met (or + * is ignored if preDragEndScale is 0). + */ + public float preDragEndScale; + /** Scale of the icons over the workspace icon size. */ public float intrinsicIconScaleFactor = 1f; From a0be92c830bff7303c5fa3cdb460d01d10ec03e4 Mon Sep 17 00:00:00 2001 From: Schneider Victor-tulias Date: Wed, 28 Sep 2022 13:28:44 -0700 Subject: [PATCH 056/429] Add debug logs to help identify when setRecentsAttachedToAppWindow will not animate properly. Bug: 244593270 Test: Manually checked logs Change-Id: Ie6d0395a45a025d1562a722154d3dd3b42618ccc --- .../android/quickstep/AbsSwipeUpHandler.java | 75 ++++++++++++++----- .../quickstep/BaseActivityInterface.java | 42 +++++++++-- 2 files changed, 92 insertions(+), 25 deletions(-) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index f3630c187b..cbd2afbe5f 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -273,7 +273,7 @@ public abstract class AbsSwipeUpHandler, private AnimatorControllerWithResistance mLauncherTransitionController; private boolean mHasEndedLauncherTransition; - private AnimationFactory mAnimationFactory = (t) -> { }; + private AnimationFactory mAnimationFactory = (t, s) -> { }; private boolean mWasLauncherAlreadyVisible; @@ -508,7 +508,9 @@ public abstract class AbsSwipeUpHandler, Runnable initAnimFactory = () -> { mAnimationFactory = mActivityInterface.prepareRecentsUI(mDeviceState, mWasLauncherAlreadyVisible, this::onAnimatorPlaybackControllerCreated); - maybeUpdateRecentsAttachedState(false /* animate */); + maybeUpdateRecentsAttachedState( + false /* animate */, + new ActiveGestureLog.CompoundString("on Launcher start (animate=false)")); if (mGestureState.getEndTarget() != null) { // Update the end target in case the gesture ended before we init. mAnimationFactory.setEndTarget(mGestureState.getEndTarget()); @@ -617,7 +619,8 @@ public abstract class AbsSwipeUpHandler, } private void initializeLauncherAnimationController() { - buildAnimationController(); + buildAnimationController(new ActiveGestureLog.CompoundString( + "initializing launcher animation controller")); Object traceToken = TraceHelper.INSTANCE.beginSection("logToggleRecents", TraceHelper.FLAG_IGNORE_BINDERS); @@ -636,7 +639,11 @@ public abstract class AbsSwipeUpHandler, @Override public void onMotionPauseDetected() { mHasMotionEverBeenPaused = true; - maybeUpdateRecentsAttachedState(true/* animate */, true/* moveFocusedTask */); + maybeUpdateRecentsAttachedState( + true/* animate */, + true/* moveFocusedTask */, + new ActiveGestureLog.CompoundString( + "motion pause detected (animate=true)")); performHapticFeedback(); } @@ -647,12 +654,13 @@ public abstract class AbsSwipeUpHandler, }; } - private void maybeUpdateRecentsAttachedState() { - maybeUpdateRecentsAttachedState(true /* animate */); + private void maybeUpdateRecentsAttachedState(ActiveGestureLog.CompoundString reason) { + maybeUpdateRecentsAttachedState(true /* animate */, reason.append(" (animate=true)")); } - private void maybeUpdateRecentsAttachedState(boolean animate) { - maybeUpdateRecentsAttachedState(animate, false /* moveFocusedTask */); + private void maybeUpdateRecentsAttachedState( + boolean animate, ActiveGestureLog.CompoundString reason) { + maybeUpdateRecentsAttachedState(animate, false /* moveFocusedTask */, reason); } /** @@ -664,7 +672,8 @@ public abstract class AbsSwipeUpHandler, * @param animate whether to animate when attaching RecentsView * @param moveFocusedTask whether to move focused task to front when attaching */ - private void maybeUpdateRecentsAttachedState(boolean animate, boolean moveFocusedTask) { + private void maybeUpdateRecentsAttachedState( + boolean animate, boolean moveFocusedTask, ActiveGestureLog.CompoundString reason) { if (!mDeviceState.isFullyGesturalNavMode() || mRecentsView == null) { return; } @@ -674,14 +683,25 @@ public abstract class AbsSwipeUpHandler, final boolean recentsAttachedToAppWindow; if (mGestureState.getEndTarget() != null) { recentsAttachedToAppWindow = mGestureState.getEndTarget().recentsAttachedToAppWindow; + reason.append("; gesture state end target != null (attached=") + .append(Boolean.toString(recentsAttachedToAppWindow)) + .append(")"); } else if (mContinuingLastGesture && mRecentsView.getRunningTaskIndex() != mRecentsView.getNextPage()) { recentsAttachedToAppWindow = true; + reason.append("; continuing last gesture (attached=true)"); } else if (runningTaskTarget != null && isNotInRecents(runningTaskTarget)) { // The window is going away so make sure recents is always visible in this case. recentsAttachedToAppWindow = true; + reason.append("; make sure recents is always visible (attached=true)"); } else { recentsAttachedToAppWindow = mHasMotionEverBeenPaused || mIsLikelyToStartNewTask; + reason.append(mHasMotionEverBeenPaused + ? "; motion has been paused" + : "; gesture is likely to start a new task") + .append(" (attached=") + .append(Boolean.toString(recentsAttachedToAppWindow)) + .append(")"); } if (moveFocusedTask && !mAnimationFactory.hasRecentsEverAttachedToAppWindow() && recentsAttachedToAppWindow) { @@ -689,7 +709,8 @@ public abstract class AbsSwipeUpHandler, // TaskView jumping to new position as we move the tasks. mRecentsView.moveFocusedTaskToFront(); } - mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate); + mAnimationFactory.setRecentsAttachedToAppWindow( + recentsAttachedToAppWindow, animate, reason); // Reapply window transform throughout the attach animation, as the animation affects how // much the window is bound by overscroll (vs moving freely). @@ -709,22 +730,29 @@ public abstract class AbsSwipeUpHandler, } public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { - setIsLikelyToStartNewTask(isLikelyToStartNewTask, true /* animate */); + setIsLikelyToStartNewTask( + isLikelyToStartNewTask, + true /* animate */, + new ActiveGestureLog.CompoundString( + "setting gesture likely to start (animate=true)")); } - private void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask, boolean animate) { + private void setIsLikelyToStartNewTask( + boolean isLikelyToStartNewTask, + boolean animate, + ActiveGestureLog.CompoundString reason) { if (mIsLikelyToStartNewTask != isLikelyToStartNewTask) { mIsLikelyToStartNewTask = isLikelyToStartNewTask; - maybeUpdateRecentsAttachedState(animate); + maybeUpdateRecentsAttachedState(animate, reason); } } - private void buildAnimationController() { + private void buildAnimationController(ActiveGestureLog.CompoundString reason) { if (!canCreateNewOrUpdateExistingLauncherTransitionController()) { return; } initTransitionEndpoints(mActivity.getDeviceProfile()); - mAnimationFactory.createActivityInterface(mTransitionDragLength); + mAnimationFactory.createActivityInterface(mTransitionDragLength, reason); } /** @@ -739,7 +767,7 @@ public abstract class AbsSwipeUpHandler, @Override public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) { WindowInsets result = view.onApplyWindowInsets(windowInsets); - buildAnimationController(); + buildAnimationController(new ActiveGestureLog.CompoundString("applying window insets")); // Reapply the current shift to ensure it takes new insets into account, e.g. when long // pressing to stash taskbar without moving the finger. updateFinalShift(); @@ -911,7 +939,10 @@ public abstract class AbsSwipeUpHandler, }); } notifyGestureStartedAsync(); - setIsLikelyToStartNewTask(isLikelyToStartNewTask, false /* animate */); + setIsLikelyToStartNewTask( + isLikelyToStartNewTask, + false /* animate */, + new ActiveGestureLog.CompoundString("on gesture started (animate=false)")); mStateCallback.setStateOnUiThread(STATE_GESTURE_STARTED); mGestureStarted = true; SystemUiProxy.INSTANCE.get(mContext).notifySwipeUpGestureStarted(); @@ -993,7 +1024,8 @@ public abstract class AbsSwipeUpHandler, private void onSettledOnEndTarget() { // Fast-finish the attaching animation if it's still running. - maybeUpdateRecentsAttachedState(false); + maybeUpdateRecentsAttachedState(false, new ActiveGestureLog.CompoundString( + "on settled on end target (animate=false)")); final GestureEndTarget endTarget = mGestureState.getEndTarget(); // Wait until the given View (if supplied) draws before resuming the last task. View postResumeLastTask = mActivityInterface.onSettledOnEndTarget(endTarget); @@ -1299,7 +1331,8 @@ public abstract class AbsSwipeUpHandler, @UiThread private void animateToProgressInternal(float start, float end, long duration, Interpolator interpolator, GestureEndTarget target, PointF velocityPxPerMs) { - maybeUpdateRecentsAttachedState(); + maybeUpdateRecentsAttachedState(new ActiveGestureLog.CompoundString( + "animate to progress internal")); // If we are transitioning to launcher, then listen for the activity to be restarted while // the transition is in progress @@ -1618,7 +1651,9 @@ public abstract class AbsSwipeUpHandler, mRecentsView.post(mRecentsView::resetTaskVisuals); } // Make sure recents is in its final state - maybeUpdateRecentsAttachedState(false); + maybeUpdateRecentsAttachedState( + false, new ActiveGestureLog.CompoundString( + "setting up window animation (animate=false)")); mActivityInterface.onSwipeUpToHomeComplete(mDeviceState); } }); diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java index 226b173ecd..a343c2d965 100644 --- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java +++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java @@ -57,6 +57,7 @@ import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.NavigationMode; import com.android.launcher3.views.ScrimView; +import com.android.quickstep.util.ActiveGestureLog; import com.android.quickstep.util.ActivityInitListener; import com.android.quickstep.util.AnimatorControllerWithResistance; import com.android.quickstep.views.RecentsView; @@ -393,14 +394,16 @@ public abstract class BaseActivityInterface

- * All apps has its own window and needs a window context. Some properties are delegated to the - * {@link TaskbarActivityContext} such as {@link DeviceProfile} and {@link PopupDataProvider}. - */ -class TaskbarAllAppsContext extends BaseTaskbarContext { - private final TaskbarActivityContext mTaskbarContext; - private final OnboardingPrefs mOnboardingPrefs; - - private final TaskbarAllAppsController mWindowController; - private final TaskbarAllAppsViewController mAllAppsViewController; - private final TaskbarDragController mDragController; - private final TaskbarAllAppsDragLayer mDragLayer; - private final TaskbarAllAppsContainerView mAppsView; - - // We automatically stash taskbar when all apps is opened in gesture navigation mode. - private final boolean mWillTaskbarBeVisuallyStashed; - private final int mStashedTaskbarHeight; - - TaskbarAllAppsContext( - TaskbarActivityContext taskbarContext, - TaskbarAllAppsController windowController, - TaskbarControllers taskbarControllers) { - super(taskbarContext.createWindowContext(TYPE_APPLICATION_OVERLAY, null)); - mTaskbarContext = taskbarContext; - mWindowController = windowController; - mDragController = new TaskbarDragController(this); - mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this)); - - mDragLayer = new TaskbarAllAppsDragLayer(this); - TaskbarAllAppsSlideInView slideInView = (TaskbarAllAppsSlideInView) mLayoutInflater.inflate( - R.layout.taskbar_all_apps, mDragLayer, false); - mAllAppsViewController = new TaskbarAllAppsViewController( - this, - slideInView, - windowController, - taskbarControllers); - mAppsView = slideInView.getAppsView(); - - TaskbarStashController taskbarStashController = taskbarControllers.taskbarStashController; - mWillTaskbarBeVisuallyStashed = taskbarStashController.supportsVisualStashing(); - mStashedTaskbarHeight = taskbarStashController.getStashedHeight(); - } - - TaskbarAllAppsViewController getAllAppsViewController() { - return mAllAppsViewController; - } - - @Override - public DeviceProfile getDeviceProfile() { - return mWindowController.getDeviceProfile(); - } - - @Override - public TaskbarDragController getDragController() { - return mDragController; - } - - @Override - public TaskbarAllAppsDragLayer getDragLayer() { - return mDragLayer; - } - - @Override - public TaskbarAllAppsContainerView getAppsView() { - return mAppsView; - } - - @Override - public OnboardingPrefs getOnboardingPrefs() { - return mOnboardingPrefs; - } - - @Override - public boolean isBindingItems() { - return mTaskbarContext.isBindingItems(); - } - - @Override - public View.OnClickListener getItemOnClickListener() { - return mTaskbarContext.getItemOnClickListener(); - } - - @Override - public PopupDataProvider getPopupDataProvider() { - return mTaskbarContext.getPopupDataProvider(); - } - - @Override - public DotInfo getDotInfoForItem(ItemInfo info) { - return mTaskbarContext.getDotInfoForItem(info); - } - - @Override - public void onDragStart() {} - - @Override - public void onDragEnd() { - mWindowController.maybeCloseWindow(); - } - - @Override - public void onPopupVisibilityChanged(boolean isVisible) {} - - @Override - public SearchAdapterProvider createSearchAdapterProvider( - ActivityAllAppsContainerView appsView) { - return new DefaultSearchAdapterProvider(this); - } - - /** Root drag layer for this context. */ - private static class TaskbarAllAppsDragLayer extends - BaseDragLayer implements OnComputeInternalInsetsListener { - - private TaskbarAllAppsDragLayer(Context context) { - super(context, null, 1); - setClipChildren(false); - recreateControllers(); - } - - @Override - protected void onAttachedToWindow() { - super.onAttachedToWindow(); - getViewTreeObserver().addOnComputeInternalInsetsListener(this); - } - - @Override - protected void onDetachedFromWindow() { - super.onDetachedFromWindow(); - getViewTreeObserver().removeOnComputeInternalInsetsListener(this); - } - - @Override - public void recreateControllers() { - mControllers = new TouchController[]{mActivity.mDragController}; - } - - @Override - public boolean dispatchTouchEvent(MotionEvent ev) { - TestLogging.recordMotionEvent(TestProtocol.SEQUENCE_MAIN, "Touch event", ev); - return super.dispatchTouchEvent(ev); - } - - @Override - public boolean dispatchKeyEvent(KeyEvent event) { - if (event.getAction() == ACTION_UP && event.getKeyCode() == KEYCODE_BACK) { - AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity); - if (topView != null && topView.onBackPressed()) { - return true; - } - } - return super.dispatchKeyEvent(event); - } - - @Override - public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) { - if (mActivity.mDragController.isSystemDragInProgress()) { - inoutInfo.touchableRegion.setEmpty(); - inoutInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); - } - } - - @Override - public WindowInsets onApplyWindowInsets(WindowInsets insets) { - return updateInsetsDueToStashing(insets); - } - - /** - * Taskbar automatically stashes when opening all apps, but we don't report the insets as - * changing to avoid moving the underlying app. But internally, the apps view should still - * layout according to the stashed insets rather than the unstashed insets. So this method - * does two things: - * 1) Sets navigationBars bottom inset to stashedHeight. - * 2) Sets tappableInsets bottom inset to 0. - */ - private WindowInsets updateInsetsDueToStashing(WindowInsets oldInsets) { - if (!mActivity.mWillTaskbarBeVisuallyStashed) { - return oldInsets; - } - WindowInsets.Builder updatedInsetsBuilder = new WindowInsets.Builder(oldInsets); - - Insets oldNavInsets = oldInsets.getInsets(WindowInsets.Type.navigationBars()); - Insets newNavInsets = Insets.of(oldNavInsets.left, oldNavInsets.top, oldNavInsets.right, - mActivity.mStashedTaskbarHeight); - updatedInsetsBuilder.setInsets(WindowInsets.Type.navigationBars(), newNavInsets); - - Insets oldTappableInsets = oldInsets.getInsets(WindowInsets.Type.tappableElement()); - Insets newTappableInsets = Insets.of(oldTappableInsets.left, oldTappableInsets.top, - oldTappableInsets.right, 0); - updatedInsetsBuilder.setInsets(WindowInsets.Type.tappableElement(), newTappableInsets); - - return updatedInsetsBuilder.build(); - } - } -} diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java index 1671a0f1d7..ea37944d69 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java @@ -15,34 +15,17 @@ */ package com.android.launcher3.taskbar.allapps; -import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; -import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; - -import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; -import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE; - -import android.content.Context; -import android.graphics.PixelFormat; -import android.view.Gravity; -import android.view.MotionEvent; -import android.view.WindowManager; -import android.view.WindowManager.LayoutParams; - import androidx.annotation.Nullable; -import com.android.launcher3.AbstractFloatingView; -import com.android.launcher3.DeviceProfile; +import com.android.launcher3.R; import com.android.launcher3.appprediction.PredictionRowView; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.ItemInfo; -import com.android.launcher3.taskbar.TaskbarActivityContext; import com.android.launcher3.taskbar.TaskbarControllers; -import com.android.systemui.shared.system.TaskStackChangeListener; -import com.android.systemui.shared.system.TaskStackChangeListeners; +import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; import java.util.List; -import java.util.Optional; /** * Handles the all apps overlay window initialization, updates, and its data. @@ -57,36 +40,14 @@ import java.util.Optional; */ public final class TaskbarAllAppsController { - private static final String WINDOW_TITLE = "Taskbar All Apps"; - - private final TaskbarActivityContext mTaskbarContext; - private final TaskbarAllAppsProxyView mProxyView; - private final LayoutParams mLayoutParams; - - private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() { - @Override - public void onTaskStackChanged() { - mProxyView.close(false); - } - }; - - private DeviceProfile mDeviceProfile; private TaskbarControllers mControllers; - /** Window context for all apps if it is open. */ - private @Nullable TaskbarAllAppsContext mAllAppsContext; + private @Nullable TaskbarAllAppsContainerView mAppsView; // Application data models. private AppInfo[] mApps; private int mAppsModelFlags; private List mPredictedApps; - public TaskbarAllAppsController(TaskbarActivityContext context, DeviceProfile dp) { - mDeviceProfile = dp; - mTaskbarContext = context; - mProxyView = new TaskbarAllAppsProxyView(mTaskbarContext); - mLayoutParams = createLayoutParams(); - } - /** Initialize the controller. */ public void init(TaskbarControllers controllers, boolean allAppsVisible) { if (!FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) { @@ -111,8 +72,8 @@ public final class TaskbarAllAppsController { mApps = apps; mAppsModelFlags = flags; - if (mAllAppsContext != null) { - mAllAppsContext.getAppsView().getAppsStore().setApps(mApps, mAppsModelFlags); + if (mAppsView != null) { + mAppsView.getAppsStore().setApps(mApps, mAppsModelFlags); } } @@ -123,8 +84,8 @@ public final class TaskbarAllAppsController { } mPredictedApps = predictedApps; - if (mAllAppsContext != null) { - mAllAppsContext.getAppsView().getFloatingHeaderView() + if (mAppsView != null) { + mAppsView.getFloatingHeaderView() .findFixedRowByType(PredictionRowView.class) .setPredictedApps(mPredictedApps); } @@ -136,120 +97,30 @@ public final class TaskbarAllAppsController { } private void show(boolean animate) { - if (mProxyView.isOpen()) { + if (mAppsView != null) { return; } - mProxyView.show(); // mControllers and getSharedState should never be null here. Do not handle null-pointer // to catch invalid states. mControllers.getSharedState().allAppsVisible = true; - mAllAppsContext = new TaskbarAllAppsContext(mTaskbarContext, this, mControllers); - mAllAppsContext.getDragController().init(mControllers); - TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener); - Optional.ofNullable(mAllAppsContext.getSystemService(WindowManager.class)) - .ifPresent(m -> m.addView(mAllAppsContext.getDragLayer(), mLayoutParams)); + TaskbarOverlayContext overlayContext = + mControllers.taskbarOverlayController.requestWindow(); + TaskbarAllAppsSlideInView slideInView = + (TaskbarAllAppsSlideInView) overlayContext.getLayoutInflater().inflate( + R.layout.taskbar_all_apps, overlayContext.getDragLayer(), false); + slideInView.addOnCloseListener(() -> { + mControllers.getSharedState().allAppsVisible = false; + mAppsView = null; + }); + TaskbarAllAppsViewController viewController = new TaskbarAllAppsViewController( + overlayContext, slideInView, mControllers); - mAllAppsContext.getAppsView().getAppsStore().setApps(mApps, mAppsModelFlags); - mAllAppsContext.getAppsView().getFloatingHeaderView() + viewController.show(animate); + mAppsView = overlayContext.getAppsView(); + mAppsView.getAppsStore().setApps(mApps, mAppsModelFlags); + mAppsView.getFloatingHeaderView() .findFixedRowByType(PredictionRowView.class) .setPredictedApps(mPredictedApps); - mAllAppsContext.getAllAppsViewController().show(animate); - } - - /** Closes the {@link TaskbarAllAppsContainerView}. */ - public void hide() { - mProxyView.close(true); - } - - /** - * Removes the all apps window from the hierarchy, if all floating views are closed and there is - * no system drag operation in progress. - *

- * This method should be called after an exit animation finishes, if applicable. - */ - void maybeCloseWindow() { - if (mAllAppsContext != null && (AbstractFloatingView.hasOpenView(mAllAppsContext, TYPE_ALL) - || mAllAppsContext.getDragController().isSystemDragInProgress())) { - return; - } - mProxyView.close(false); - // mControllers and getSharedState should never be null here. Do not handle null-pointer - // to catch invalid states. - mControllers.getSharedState().allAppsVisible = false; - onDestroy(); - } - - /** Destroys the controller and any All Apps window if present. */ - public void onDestroy() { - TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener); - Optional.ofNullable(mAllAppsContext) - .map(c -> c.getSystemService(WindowManager.class)) - .ifPresent(m -> m.removeViewImmediate(mAllAppsContext.getDragLayer())); - mAllAppsContext = null; - } - - /** Updates {@link DeviceProfile} instance for Taskbar's All Apps window. */ - public void updateDeviceProfile(DeviceProfile dp) { - mDeviceProfile = dp; - Optional.ofNullable(mAllAppsContext).ifPresent(c -> { - AbstractFloatingView.closeAllOpenViewsExcept(c, false, TYPE_REBIND_SAFE); - c.dispatchDeviceProfileChanged(); - }); - } - - DeviceProfile getDeviceProfile() { - return mDeviceProfile; - } - - private LayoutParams createLayoutParams() { - LayoutParams layoutParams = new LayoutParams( - TYPE_APPLICATION_OVERLAY, - WindowManager.LayoutParams.FLAG_SPLIT_TOUCH, - PixelFormat.TRANSLUCENT); - layoutParams.setTitle(WINDOW_TITLE); - layoutParams.gravity = Gravity.BOTTOM; - layoutParams.packageName = mTaskbarContext.getPackageName(); - layoutParams.setFitInsetsTypes(0); // Handled by container view. - layoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; - layoutParams.setSystemApplicationOverlay(true); - return layoutParams; - } - - /** - * Proxy view connecting taskbar drag layer to the all apps window. - *

- * The all apps view is in a separate window and has its own drag layer, but this proxy lets it - * behave as though its in the taskbar drag layer. For instance, when the taskbar closes all - * {@link AbstractFloatingView} instances, the all apps window will also close. - */ - private class TaskbarAllAppsProxyView extends AbstractFloatingView { - - private TaskbarAllAppsProxyView(Context context) { - super(context, null); - } - - private void show() { - mIsOpen = true; - mTaskbarContext.getDragLayer().addView(this); - } - - @Override - protected void handleClose(boolean animate) { - mTaskbarContext.getDragLayer().removeView(this); - Optional.ofNullable(mAllAppsContext) - .map(TaskbarAllAppsContext::getAllAppsViewController) - .ifPresent(v -> v.close(animate)); - } - - @Override - protected boolean isOfType(int type) { - return (type & TYPE_TASKBAR_ALL_APPS) != 0; - } - - @Override - public boolean onControllerInterceptTouchEvent(MotionEvent ev) { - return false; - } } } diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java index 9d48c8de89..c8bfc2aed0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java @@ -28,10 +28,11 @@ import android.view.animation.Interpolator; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Insettable; import com.android.launcher3.R; +import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; import com.android.launcher3.views.AbstractSlideInView; /** Wrapper for taskbar all apps with slide-in behavior. */ -public class TaskbarAllAppsSlideInView extends AbstractSlideInView +public class TaskbarAllAppsSlideInView extends AbstractSlideInView implements Insettable, DeviceProfile.OnDeviceProfileChangeListener { private TaskbarAllAppsContainerView mAppsView; private float mShiftRange; diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java index 128fa5e81e..54392b21c0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsViewController.java @@ -25,6 +25,7 @@ import com.android.launcher3.appprediction.PredictionRowView; import com.android.launcher3.taskbar.NavbarButtonsViewController; import com.android.launcher3.taskbar.TaskbarControllers; import com.android.launcher3.taskbar.TaskbarStashController; +import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; /** * Handles the {@link TaskbarAllAppsContainerView} behavior and synchronizes its transitions with @@ -32,16 +33,15 @@ import com.android.launcher3.taskbar.TaskbarStashController; */ final class TaskbarAllAppsViewController { - private final TaskbarAllAppsContext mContext; + private final TaskbarOverlayContext mContext; private final TaskbarAllAppsSlideInView mSlideInView; private final TaskbarAllAppsContainerView mAppsView; private final TaskbarStashController mTaskbarStashController; private final NavbarButtonsViewController mNavbarButtonsViewController; TaskbarAllAppsViewController( - TaskbarAllAppsContext context, + TaskbarOverlayContext context, TaskbarAllAppsSlideInView slideInView, - TaskbarAllAppsController windowController, TaskbarControllers taskbarControllers) { mContext = context; @@ -53,7 +53,6 @@ final class TaskbarAllAppsViewController { setUpIconLongClick(); setUpAppDivider(); setUpTaskbarStashing(); - mSlideInView.addOnCloseListener(windowController::maybeCloseWindow); } /** Starts the {@link TaskbarAllAppsSlideInView} enter transition. */ diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java new file mode 100644 index 0000000000..5701de0e9c --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java @@ -0,0 +1,146 @@ +/* + * Copyright (C) 2022 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.launcher3.taskbar.overlay; + +import android.content.Context; +import android.view.View; + +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.R; +import com.android.launcher3.Utilities; +import com.android.launcher3.allapps.ActivityAllAppsContainerView; +import com.android.launcher3.allapps.search.DefaultSearchAdapterProvider; +import com.android.launcher3.allapps.search.SearchAdapterProvider; +import com.android.launcher3.dot.DotInfo; +import com.android.launcher3.model.data.ItemInfo; +import com.android.launcher3.popup.PopupDataProvider; +import com.android.launcher3.taskbar.BaseTaskbarContext; +import com.android.launcher3.taskbar.TaskbarActivityContext; +import com.android.launcher3.taskbar.TaskbarControllers; +import com.android.launcher3.taskbar.TaskbarDragController; +import com.android.launcher3.taskbar.TaskbarStashController; +import com.android.launcher3.taskbar.allapps.TaskbarAllAppsContainerView; +import com.android.launcher3.util.OnboardingPrefs; + +/** + * Window context for the taskbar overlays such as All Apps and EDU. + *

+ * Overlays have their own window and need a window context. Some properties are delegated to the + * {@link TaskbarActivityContext} such as {@link PopupDataProvider}. + */ +public class TaskbarOverlayContext extends BaseTaskbarContext { + private final TaskbarActivityContext mTaskbarContext; + private final OnboardingPrefs mOnboardingPrefs; + + private final TaskbarOverlayController mOverlayController; + private final TaskbarDragController mDragController; + private final TaskbarOverlayDragLayer mDragLayer; + + // We automatically stash taskbar when All Apps is opened in gesture navigation mode. + private final boolean mWillTaskbarBeVisuallyStashed; + private final int mStashedTaskbarHeight; + + public TaskbarOverlayContext( + Context windowContext, + TaskbarActivityContext taskbarContext, + TaskbarControllers controllers) { + super(windowContext); + mTaskbarContext = taskbarContext; + mOverlayController = controllers.taskbarOverlayController; + mDragController = new TaskbarDragController(this); + mDragController.init(controllers); + mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this)); + mDragLayer = new TaskbarOverlayDragLayer(this); + + TaskbarStashController taskbarStashController = controllers.taskbarStashController; + mWillTaskbarBeVisuallyStashed = taskbarStashController.supportsVisualStashing(); + mStashedTaskbarHeight = taskbarStashController.getStashedHeight(); + } + + boolean willTaskbarBeVisuallyStashed() { + return mWillTaskbarBeVisuallyStashed; + } + + int getStashedTaskbarHeight() { + return mStashedTaskbarHeight; + } + + public TaskbarOverlayController getOverlayController() { + return mOverlayController; + } + + @Override + public DeviceProfile getDeviceProfile() { + return mOverlayController.getDeviceProfile(); + } + + @Override + public TaskbarDragController getDragController() { + return mDragController; + } + + @Override + public TaskbarOverlayDragLayer getDragLayer() { + return mDragLayer; + } + + @Override + public TaskbarAllAppsContainerView getAppsView() { + return mDragLayer.findViewById(R.id.apps_view); + } + + @Override + public OnboardingPrefs getOnboardingPrefs() { + return mOnboardingPrefs; + } + + @Override + public boolean isBindingItems() { + return mTaskbarContext.isBindingItems(); + } + + @Override + public View.OnClickListener getItemOnClickListener() { + return mTaskbarContext.getItemOnClickListener(); + } + + @Override + public PopupDataProvider getPopupDataProvider() { + return mTaskbarContext.getPopupDataProvider(); + } + + @Override + public DotInfo getDotInfoForItem(ItemInfo info) { + return mTaskbarContext.getDotInfoForItem(info); + } + + @Override + public void onDragStart() {} + + @Override + public void onDragEnd() { + mOverlayController.maybeCloseWindow(); + } + + @Override + public void onPopupVisibilityChanged(boolean isVisible) {} + + @Override + public SearchAdapterProvider createSearchAdapterProvider( + ActivityAllAppsContainerView appsView) { + return new DefaultSearchAdapterProvider(this); + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java new file mode 100644 index 0000000000..0574058dcc --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2022 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.launcher3.taskbar.overlay; + +import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; +import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; + +import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; +import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE; + +import android.annotation.SuppressLint; +import android.content.Context; +import android.graphics.PixelFormat; +import android.view.Gravity; +import android.view.MotionEvent; +import android.view.WindowManager; +import android.view.WindowManager.LayoutParams; + +import androidx.annotation.Nullable; + +import com.android.launcher3.AbstractFloatingView; +import com.android.launcher3.DeviceProfile; +import com.android.launcher3.taskbar.TaskbarActivityContext; +import com.android.launcher3.taskbar.TaskbarControllers; +import com.android.systemui.shared.system.TaskStackChangeListener; +import com.android.systemui.shared.system.TaskStackChangeListeners; + +import java.util.Optional; + +/** + * Handles the Taskbar overlay window lifecycle. + *

+ * Overlays need to be inflated in a separate window so that have the correct hierarchy. For + * instance, they need to be below the notification tray. If there are multiple overlays open, the + * same window is used. + */ +public final class TaskbarOverlayController { + + private static final String WINDOW_TITLE = "Taskbar Overlay"; + + private final TaskbarActivityContext mTaskbarContext; + private final Context mWindowContext; + private final TaskbarOverlayProxyView mProxyView; + private final LayoutParams mLayoutParams; + + private final TaskStackChangeListener mTaskStackListener = new TaskStackChangeListener() { + @Override + public void onTaskStackChanged() { + mProxyView.close(false); + } + }; + + private DeviceProfile mDeviceProfile; + private @Nullable TaskbarOverlayContext mOverlayContext; + private TaskbarControllers mControllers; // Initialized in init. + + public TaskbarOverlayController( + TaskbarActivityContext taskbarContext, DeviceProfile deviceProfile) { + mTaskbarContext = taskbarContext; + mWindowContext = mTaskbarContext.createWindowContext(TYPE_APPLICATION_OVERLAY, null); + mProxyView = new TaskbarOverlayProxyView(); + mLayoutParams = createLayoutParams(); + mDeviceProfile = deviceProfile; + } + + /** Initialize the controller. */ + public void init(TaskbarControllers controllers) { + mControllers = controllers; + } + + /** + * Creates a window for Taskbar overlays, if it does not already exist. Returns the window + * context for the current overlay window. + */ + public TaskbarOverlayContext requestWindow() { + if (mOverlayContext == null) { + mOverlayContext = new TaskbarOverlayContext( + mWindowContext, mTaskbarContext, mControllers); + } + + if (!mProxyView.isOpen()) { + mProxyView.show(); + Optional.ofNullable(mOverlayContext.getSystemService(WindowManager.class)) + .ifPresent(m -> m.addView(mOverlayContext.getDragLayer(), mLayoutParams)); + TaskStackChangeListeners.getInstance().registerTaskStackListener(mTaskStackListener); + } + + return mOverlayContext; + } + + /** Hides the current overlay window with animation. */ + public void hideWindow() { + mProxyView.close(true); + } + + /** + * Removes the overlay window from the hierarchy, if all floating views are closed and there is + * no system drag operation in progress. + *

+ * This method should be called after an exit animation finishes, if applicable. + */ + @SuppressLint("WrongConstant") + void maybeCloseWindow() { + if (mOverlayContext != null && (AbstractFloatingView.hasOpenView(mOverlayContext, TYPE_ALL) + || mOverlayContext.getDragController().isSystemDragInProgress())) { + return; + } + mProxyView.close(false); + onDestroy(); + } + + /** Destroys the controller and any overlay window if present. */ + public void onDestroy() { + TaskStackChangeListeners.getInstance().unregisterTaskStackListener(mTaskStackListener); + Optional.ofNullable(mOverlayContext) + .map(c -> c.getSystemService(WindowManager.class)) + .ifPresent(m -> m.removeViewImmediate(mOverlayContext.getDragLayer())); + mOverlayContext = null; + } + + /** The current device profile for the overlay window. */ + public DeviceProfile getDeviceProfile() { + return mDeviceProfile; + } + + /** Updates {@link DeviceProfile} instance for Taskbar's overlay window. */ + public void updateDeviceProfile(DeviceProfile dp) { + mDeviceProfile = dp; + Optional.ofNullable(mOverlayContext).ifPresent(c -> { + AbstractFloatingView.closeAllOpenViewsExcept(c, false, TYPE_REBIND_SAFE); + c.dispatchDeviceProfileChanged(); + }); + } + + @SuppressLint("WrongConstant") + private LayoutParams createLayoutParams() { + LayoutParams layoutParams = new LayoutParams( + TYPE_APPLICATION_OVERLAY, + LayoutParams.FLAG_SPLIT_TOUCH, + PixelFormat.TRANSLUCENT); + layoutParams.setTitle(WINDOW_TITLE); + layoutParams.gravity = Gravity.BOTTOM; + layoutParams.packageName = mTaskbarContext.getPackageName(); + layoutParams.setFitInsetsTypes(0); // Handled by container view. + layoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; + layoutParams.setSystemApplicationOverlay(true); + return layoutParams; + } + + /** + * Proxy view connecting taskbar drag layer to the overlay window. + * + * Overlays are in a separate window and has its own drag layer, but this proxy lets its views + * behave as though they are in the taskbar drag layer. For instance, when the taskbar closes + * all {@link AbstractFloatingView} instances, the overlay window will also close. + */ + private class TaskbarOverlayProxyView extends AbstractFloatingView { + + private TaskbarOverlayProxyView() { + super(mTaskbarContext, null); + } + + private void show() { + mIsOpen = true; + mTaskbarContext.getDragLayer().addView(this); + } + + @Override + protected void handleClose(boolean animate) { + mTaskbarContext.getDragLayer().removeView(this); + Optional.ofNullable(mOverlayContext).ifPresent(c -> closeAllOpenViews(c, animate)); + } + + @Override + protected boolean isOfType(int type) { + return (type & TYPE_TASKBAR_OVERLAY_PROXY) != 0; + } + + @Override + public boolean onControllerInterceptTouchEvent(MotionEvent ev) { + return false; + } + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java new file mode 100644 index 0000000000..044afd6725 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayDragLayer.java @@ -0,0 +1,126 @@ +/* + * Copyright (C) 2022 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.launcher3.taskbar.overlay; + +import static android.view.KeyEvent.ACTION_UP; +import static android.view.KeyEvent.KEYCODE_BACK; +import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION; + +import android.content.Context; +import android.graphics.Insets; +import android.view.KeyEvent; +import android.view.MotionEvent; +import android.view.View; +import android.view.ViewTreeObserver; +import android.view.WindowInsets; + +import com.android.launcher3.AbstractFloatingView; +import com.android.launcher3.testing.TestLogging; +import com.android.launcher3.testing.shared.TestProtocol; +import com.android.launcher3.util.TouchController; +import com.android.launcher3.views.BaseDragLayer; + +/** Root drag layer for the Taskbar overlay window. */ +public class TaskbarOverlayDragLayer extends + BaseDragLayer implements + ViewTreeObserver.OnComputeInternalInsetsListener { + + TaskbarOverlayDragLayer(Context context) { + super(context, null, 1); + setClipChildren(false); + recreateControllers(); + } + + @Override + protected void onAttachedToWindow() { + super.onAttachedToWindow(); + getViewTreeObserver().addOnComputeInternalInsetsListener(this); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + getViewTreeObserver().removeOnComputeInternalInsetsListener(this); + } + + @Override + public void recreateControllers() { + mControllers = new TouchController[]{mActivity.getDragController()}; + } + + @Override + public boolean dispatchTouchEvent(MotionEvent ev) { + TestLogging.recordMotionEvent(TestProtocol.SEQUENCE_MAIN, "Touch event", ev); + return super.dispatchTouchEvent(ev); + } + + @Override + public boolean dispatchKeyEvent(KeyEvent event) { + if (event.getAction() == ACTION_UP && event.getKeyCode() == KEYCODE_BACK) { + AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(mActivity); + if (topView != null && topView.onBackPressed()) { + return true; + } + } + return super.dispatchKeyEvent(event); + } + + @Override + public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) { + if (mActivity.getDragController().isSystemDragInProgress()) { + inoutInfo.touchableRegion.setEmpty(); + inoutInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION); + } + } + + @Override + public WindowInsets onApplyWindowInsets(WindowInsets insets) { + return updateInsetsDueToStashing(insets); + } + + @Override + public void onViewRemoved(View child) { + super.onViewRemoved(child); + mActivity.getOverlayController().maybeCloseWindow(); + } + + /** + * Taskbar automatically stashes when opening all apps, but we don't report the insets as + * changing to avoid moving the underlying app. But internally, the apps view should still + * layout according to the stashed insets rather than the unstashed insets. So this method + * does two things: + * 1) Sets navigationBars bottom inset to stashedHeight. + * 2) Sets tappableInsets bottom inset to 0. + */ + private WindowInsets updateInsetsDueToStashing(WindowInsets oldInsets) { + if (!mActivity.willTaskbarBeVisuallyStashed()) { + return oldInsets; + } + WindowInsets.Builder updatedInsetsBuilder = new WindowInsets.Builder(oldInsets); + + Insets oldNavInsets = oldInsets.getInsets(WindowInsets.Type.navigationBars()); + Insets newNavInsets = Insets.of(oldNavInsets.left, oldNavInsets.top, oldNavInsets.right, + mActivity.getStashedTaskbarHeight()); + updatedInsetsBuilder.setInsets(WindowInsets.Type.navigationBars(), newNavInsets); + + Insets oldTappableInsets = oldInsets.getInsets(WindowInsets.Type.tappableElement()); + Insets newTappableInsets = Insets.of(oldTappableInsets.left, oldTappableInsets.top, + oldTappableInsets.right, 0); + updatedInsetsBuilder.setInsets(WindowInsets.Type.tappableElement(), newTappableInsets); + + return updatedInsetsBuilder.build(); + } +} diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java index a343c2d965..d4320043b0 100644 --- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java +++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java @@ -188,7 +188,8 @@ public abstract class BaseActivityInterface thumbnailDatas, diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java index 1cb17cb815..93be8d214e 100644 --- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java +++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java @@ -289,10 +289,6 @@ public final class LauncherActivityInterface extends } else { om.hideOverlay(150); } - LauncherTaskbarUIController taskbarController = getTaskbarController(); - if (taskbarController != null) { - taskbarController.hideEdu(); - } } @Override diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java index 5ee6fce1f7..73acd878c7 100644 --- a/src/com/android/launcher3/AbstractFloatingView.java +++ b/src/com/android/launcher3/AbstractFloatingView.java @@ -94,6 +94,7 @@ public abstract class AbstractFloatingView extends LinearLayout implements Touch public static final int TYPE_TASKBAR_EDUCATION_DIALOG = 1 << 16; public static final int TYPE_TASKBAR_ALL_APPS = 1 << 17; public static final int TYPE_ADD_TO_HOME_CONFIRMATION = 1 << 18; + public static final int TYPE_TASKBAR_OVERLAY_PROXY = 1 << 19; public static final int TYPE_ALL = TYPE_FOLDER | TYPE_ACTION_POPUP | TYPE_WIDGETS_BOTTOM_SHEET | TYPE_WIDGET_RESIZE_FRAME | TYPE_WIDGETS_FULL_SHEET From 587fe3fa49a670aed3e0ffbf7e0f0b3ec2b844b6 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 15 Oct 2022 09:48:50 -0700 Subject: [PATCH 070/429] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ie26e4bfb684515d47461f2e13f19f551ace639cc --- quickstep/res/values-am/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml index 6ea7d8af54..1789c2b8dd 100644 --- a/quickstep/res/values-am/strings.xml +++ b/quickstep/res/values-am/strings.xml @@ -20,7 +20,7 @@ "ሰካ" - "ነጻ ቅጽ" + "ነፃ ቅጽ" "ምንም የቅርብ ጊዜ ንጥሎች የሉም" "የመተግበሪያ አጠቃቀም ቅንብሮች" "ሁሉንም አጽዳ" From b3fef31ab7e5640d176b64d7a4d6a3de322a0c1b Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 15 Oct 2022 09:49:34 -0700 Subject: [PATCH 071/429] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I6664251e87a9ab69de224ebec5b6f183afe2ed2b --- go/quickstep/res/values-my/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/go/quickstep/res/values-my/strings.xml b/go/quickstep/res/values-my/strings.xml index 0ca0e9c0bf..cbb485a6d2 100644 --- a/go/quickstep/res/values-my/strings.xml +++ b/go/quickstep/res/values-my/strings.xml @@ -5,7 +5,7 @@ "နားထောင်ရန်" "ဘာသာပြန်ရန်" "Lens" - "ရပြီ" + "နားလည်ပြီ" "မလုပ်တော့" "ဆက်တင်များ" "ဖန်သားပြင်ပေါ်ရှိ စာသားကို ဘာသာပြန်ပါ (သို့) နားထောင်ပါ" From 2ed0e9c2fd97470381362ab2144198ff190e9e25 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Sat, 15 Oct 2022 09:50:34 -0700 Subject: [PATCH 072/429] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I335fffb5175d179a2c91de5f5771e8e97462e442 --- res/values-as/strings.xml | 10 +++++----- res/values-my/strings.xml | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/res/values-as/strings.xml b/res/values-as/strings.xml index 0a4943ecf7..67998d53a4 100644 --- a/res/values-as/strings.xml +++ b/res/values-as/strings.xml @@ -21,9 +21,9 @@ xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2"> "Launcher3" "কৰ্মস্থান" - "এপটো ইনষ্টল কৰা নহ\'ল।" - "এপটো নাই" - "ডাউনল’ড কৰা এপটোক সুৰক্ষিত ম\'ডত অক্ষম কৰা হ’ল" + "এপ্‌টো ইনষ্টল কৰা নহ\'ল।" + "এপ্‌টো নাই" + "ডাউনল’ড কৰা এপ্‌টোক সুৰক্ষিত ম\'ডত অক্ষম কৰা হ’ল" "ৱিজেটবোৰক সুৰক্ষিত ম\'ডত অক্ষম কৰা হ’ল" "শ্বৰ্টকাট নাই" "গৃহ স্ক্ৰীন" @@ -119,8 +119,8 @@ "অজ্ঞাত" "আঁতৰাওক" "সন্ধান কৰক" - "এই এপটো ইনষ্টল কৰা হোৱা নাই" - "এই আইকনৰ এপটো ইনষ্টল কৰা হোৱা নাই। আপুনি এইটো আঁতৰাব পাৰে অথবা এপটো বিচাৰি মেনুৱেলভাৱে ইনষ্টল কৰিব পাৰে।" + "এই এপ্‌টো ইনষ্টল কৰা হোৱা নাই" + "এই আইকনৰ এপ্‌টো ইনষ্টল কৰা হোৱা নাই। আপুনি এইটো আঁতৰাব পাৰে অথবা এপ্‌টো বিচাৰি মেনুৱেলভাৱে ইনষ্টল কৰিব পাৰে।" "%1$s ইনষ্টল কৰি থকা হৈছে, %2$s সম্পূৰ্ণ হৈছে" "%1$s ডাউনল’ড কৰি থকা হৈছে, %2$s সম্পূৰ্ণ হ’ল" "%1$s ইনষ্টল হোৱালৈ অপেক্ষা কৰি থকা হৈছে" diff --git a/res/values-my/strings.xml b/res/values-my/strings.xml index 3cec97d170..69157bc330 100644 --- a/res/values-my/strings.xml +++ b/res/values-my/strings.xml @@ -54,7 +54,7 @@ "အသုံးဝင်သော အချက်အလက်များကို အလွယ်တကူ ရယူလိုက်ပါ" "အက်ပ်မဖွင့်ဘဲ အချက်အလက်များရယူရန် ပင်မစာမျက်နှာတွင် ဝိဂျက်များ ထည့်နိုင်သည်" "ဝိဂျက် ဆက်တင်များကို ပြောင်းရန် တို့ပါ" - "ရပြီ" + "နားလည်ပြီ" "ဝိဂျက် ဆက်တင်များကို ပြောင်းပါ" "ရှာဖွေမှု အက်ပ်များ" "အက်ပ်များကို ဖွင့်နေသည်…" @@ -166,7 +166,7 @@ "သင်၏ အလုပ်သုံးအက်ပ်များက အကြောင်းကြားချက်များ ပို့ခြင်း၊ သင့်ဘက်ထရီ သုံးခြင်း (သို့) သင့်တည်နေရာ သုံးခြင်းတို့ မပြုလုပ်နိုင်ပါ" "အလုပ်သုံးအက်ပ်များ ပိတ်ထားသည်။ သင်၏ အလုပ်သုံးအက်ပ်များက အကြောင်းကြားချက်များ ပို့ခြင်း၊ သင့်ဘက်ထရီ သုံးခြင်း (သို့) သင့်တည်နေရာ သုံးခြင်းတို့ မပြုလုပ်နိုင်ပါ" "အလုပ်သုံးအက်ပ်များကို တံဆိပ်တပ်ထားပြီး သင်၏ IT စီမံခန့်ခွဲသူက မြင်နိုင်ပါသည်" - "ရပြီ" + "နားလည်ပြီ" "အလုပ်သုံးအက်ပ်များကို ခဏရပ်ရန်" "အလုပ်သုံးအက်ပ်များ ဖွင့်ရန်" "စစ်ထုတ်ရန်" From 5889bc37298f882cb963df9d3f7702a87f80b608 Mon Sep 17 00:00:00 2001 From: Pat Manning Date: Mon, 22 Aug 2022 17:58:18 +0100 Subject: [PATCH 073/429] Add launcher metrics for tracking kids nav mode change events. Fix: 241762670 Test: wwdebug && wwlogcat Change-Id: I24432f2cd0dddbcc5991645b60a1a8e91dc431e5 --- protos/launcher_atom.proto | 3 +++ .../android/quickstep/logging/StatsLogCompatManager.java | 2 +- src/com/android/launcher3/model/data/ItemInfo.java | 9 +++++++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/protos/launcher_atom.proto b/protos/launcher_atom.proto index 10eedc8578..151ec5a93c 100644 --- a/protos/launcher_atom.proto +++ b/protos/launcher_atom.proto @@ -45,6 +45,9 @@ message ItemInfo { // Stores the origin of the Item repeated Attribute item_attributes = 12; + + // Stores whether the navigation bar is in kids mode. + optional bool is_kids_mode = 13; } message LauncherAttributes{ diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java index a9ff0fb07f..0c422a0595 100644 --- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java +++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java @@ -191,7 +191,7 @@ public class StatsLogCompatManager extends StatsLogManager { info.getWidget().getSpanX(), // span_x = 17 [default = 1]; info.getWidget().getSpanY(), // span_y = 18 [default = 1]; getAttributes(info) /* attributes = 19 [(log_mode) = MODE_BYTES] */, - false /* is_kids_mode = 20 */ + info.getIsKidsMode() /* is_kids_mode = 20 */ ); } diff --git a/src/com/android/launcher3/model/data/ItemInfo.java b/src/com/android/launcher3/model/data/ItemInfo.java index a8e9eb5162..159af60a0f 100644 --- a/src/com/android/launcher3/model/data/ItemInfo.java +++ b/src/com/android/launcher3/model/data/ItemInfo.java @@ -39,8 +39,10 @@ import static com.android.launcher3.shortcuts.ShortcutKey.EXTRA_SHORTCUT_ID; import android.content.ComponentName; import android.content.ContentValues; import android.content.Intent; +import android.net.Uri; import android.os.Process; import android.os.UserHandle; +import android.provider.Settings; import androidx.annotation.NonNull; import androidx.annotation.Nullable; @@ -61,6 +63,7 @@ import com.android.launcher3.logger.LauncherAtom.WallpapersContainer; import com.android.launcher3.logger.LauncherAtomExtensions.ExtendedContainers; import com.android.launcher3.model.ModelWriter; import com.android.launcher3.util.ContentWriter; +import com.android.launcher3.util.SettingsCache; import java.util.Optional; @@ -74,6 +77,9 @@ public class ItemInfo { // An id that doesn't match any item, including predicted apps with have an id=NO_ID public static final int NO_MATCHING_ID = Integer.MIN_VALUE; + /** Hidden field Settings.Secure.NAV_BAR_KIDS_MODE */ + private static final Uri NAV_BAR_KIDS_MODE = Settings.Secure.getUriFor("nav_bar_kids_mode"); + /** * The id in the settings database for this item */ @@ -390,6 +396,9 @@ public class ItemInfo { protected LauncherAtom.ItemInfo.Builder getDefaultItemInfoBuilder() { LauncherAtom.ItemInfo.Builder itemBuilder = LauncherAtom.ItemInfo.newBuilder(); itemBuilder.setIsWork(!Process.myUserHandle().equals(user)); + SettingsCache settingsCache = SettingsCache.INSTANCE.getNoCreate(); + boolean isKidsMode = settingsCache != null && settingsCache.getValue(NAV_BAR_KIDS_MODE, 0); + itemBuilder.setIsKidsMode(isKidsMode); itemBuilder.setRank(rank); return itemBuilder; } From 6f0b0fe742663759216ddec52d6a35445d30662c Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Mon, 17 Oct 2022 14:38:09 +0000 Subject: [PATCH 074/429] Revert "Enable taskbar in overview by default" This reverts commit 517131ae1c634830bffe0e3cf4ce9ff5f03e8efe. Reason for revert: Reverting until b/251747761 is addressed Bug: 245320601 Change-Id: Ic5ebc071f092c8f91ff879a59d89c3be4326c90e --- .../launcher3/config/FeatureFlags.java | 2 +- .../tapl/LauncherInstrumentation.java | 27 ++++++++----------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 030ac7efcc..3a530affad 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -241,7 +241,7 @@ public final class FeatureFlags { "Enables One Search box in Taskbar All Apps."); public static final BooleanFlag ENABLE_TASKBAR_IN_OVERVIEW = getDebugFlag( - "ENABLE_TASKBAR_IN_OVERVIEW", true, + "ENABLE_TASKBAR_IN_OVERVIEW", false, "Enables accessing the system Taskbar in overview."); public static final BooleanFlag ENABLE_SPLIT_FROM_WORKSPACE = getDebugFlag( diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 677960df96..3545c27d24 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -781,7 +781,7 @@ public final class LauncherInstrumentation { waitUntilLauncherObjectGone(APPS_RES_ID); waitUntilLauncherObjectGone(WORKSPACE_RES_ID); waitUntilLauncherObjectGone(WIDGETS_RES_ID); - checkTaskbarVisibility(); + waitUntilLauncherObjectGone(TASKBAR_RES_ID); waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); return waitForLauncherObject(OVERVIEW_RES_ID); @@ -790,7 +790,7 @@ public final class LauncherInstrumentation { waitUntilLauncherObjectGone(APPS_RES_ID); waitUntilLauncherObjectGone(WORKSPACE_RES_ID); waitUntilLauncherObjectGone(WIDGETS_RES_ID); - checkTaskbarVisibility(); + waitUntilLauncherObjectGone(TASKBAR_RES_ID); waitForLauncherObject(SPLIT_PLACEHOLDER_RES_ID); return waitForLauncherObject(OVERVIEW_RES_ID); @@ -799,7 +799,7 @@ public final class LauncherInstrumentation { waitUntilLauncherObjectGone(APPS_RES_ID); waitUntilLauncherObjectGone(WORKSPACE_RES_ID); waitUntilLauncherObjectGone(WIDGETS_RES_ID); - checkTaskbarVisibility(); + waitUntilLauncherObjectGone(TASKBAR_RES_ID); waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); return waitForFallbackLauncherObject(OVERVIEW_RES_ID); @@ -811,7 +811,14 @@ public final class LauncherInstrumentation { waitUntilLauncherObjectGone(WIDGETS_RES_ID); waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); - checkTaskbarVisibility(); + if (mIgnoreTaskbarVisibility) { + return null; + } + if (isTablet() && !isFallbackOverview()) { + waitForLauncherObject(TASKBAR_RES_ID); + } else { + waitUntilLauncherObjectGone(TASKBAR_RES_ID); + } return null; } default: @@ -821,18 +828,6 @@ public final class LauncherInstrumentation { } } - private void checkTaskbarVisibility() { - if (mIgnoreTaskbarVisibility) { - return; - } - - if (isTablet() && !isFallbackOverview()) { - waitForLauncherObject(TASKBAR_RES_ID); - } else { - waitUntilLauncherObjectGone(TASKBAR_RES_ID); - } - } - public void waitForLauncherInitialized() { for (int i = 0; i < 100; ++i) { if (getTestInfo( From e73833600193b5db18e484c76ae46fcc09d7c099 Mon Sep 17 00:00:00 2001 From: Schneider Victor-tulias Date: Fri, 14 Oct 2022 12:58:21 -0700 Subject: [PATCH 075/429] Fix missing screenshots on rotate from recents view select state Rotating while in the recents view select state causes all taskview screenshots to disappear. Removing the transition to overview also fixes this, but leaves launcher in an incorrect state. - Updated API to allow transitioning states without animation. - Removed the animation to update the state correctly while keeping the ui working. Fixes: 251067808 Test: rotated back and forth on large and small devices, before and after entering select mode Change-Id: I5bf89ceb1f6b27cde9f7638f32fee3a78ad85ff6 --- .../android/quickstep/fallback/FallbackRecentsView.java | 7 +++---- .../com/android/quickstep/views/LauncherRecentsView.java | 7 +++---- .../src/com/android/quickstep/views/RecentsView.java | 9 +++------ 3 files changed, 9 insertions(+), 14 deletions(-) diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java index e32aaee532..89def5f126 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -200,13 +200,12 @@ public class FallbackRecentsView extends RecentsView Date: Thu, 13 Oct 2022 14:25:55 -0700 Subject: [PATCH 076/429] Making Launcher TAPL check orientation only when the expected orientation is set by the test This makes life simpler for tests that don't care about orientation Bug: 245576832 Test: presubmit Change-Id: I3c247826c6cac0e20c93a2fad9b81775fd2ebaa8 Merged-In: I3c247826c6cac0e20c93a2fad9b81775fd2ebaa8 --- .../tapl/LauncherInstrumentation.java | 27 ++++++++++++------- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 677960df96..d765c2fb91 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -48,7 +48,6 @@ import android.text.TextUtils; import android.util.Log; import android.view.InputDevice; import android.view.MotionEvent; -import android.view.Surface; import android.view.ViewConfiguration; import android.view.WindowManager; import android.view.accessibility.AccessibilityEvent; @@ -180,7 +179,7 @@ public final class LauncherInstrumentation { private final UiDevice mDevice; private final Instrumentation mInstrumentation; - private int mExpectedRotation = Surface.ROTATION_0; + private Integer mExpectedRotation = null; private final Uri mTestProviderUri; private final Deque mDiagnosticContext = new LinkedList<>(); private Function mSystemHealthSupplier; @@ -193,6 +192,7 @@ public final class LauncherInstrumentation { private boolean mCheckEventsForSuccessfulGestures = false; private Runnable mOnLauncherCrashed; + private static Pattern getTouchEventPattern(String prefix, String action) { // The pattern includes checks that we don't get a multi-touch events or other surprises. return Pattern.compile( @@ -297,8 +297,8 @@ public final class LauncherInstrumentation { final String testSuffix = ".test"; return testPackage.endsWith(testSuffix) && testPackage.length() > testSuffix.length() - && testPackage.substring(0, testPackage.length() - testSuffix.length()) - .equals(targetPackage); + && testPackage.substring(0, testPackage.length() - testSuffix.length()) + .equals(targetPackage); } public void enableCheckEventsForSuccessfulGestures() { @@ -685,15 +685,20 @@ public final class LauncherInstrumentation { * Whether to ignore verifying the task bar visibility during instrumenting. * * @param ignoreTaskbarVisibility {@code true} will ignore the instrumentation implicitly - * verifying the task bar visibility with - * {@link VisibleContainer#verifyActiveContainer}. - * {@code false} otherwise. + * verifying the task bar visibility with + * {@link VisibleContainer#verifyActiveContainer}. + * {@code false} otherwise. */ public void setIgnoreTaskbarVisibility(boolean ignoreTaskbarVisibility) { mIgnoreTaskbarVisibility = ignoreTaskbarVisibility; } - public void setExpectedRotation(int expectedRotation) { + /** + * Sets expected rotation. + * TAPL periodically checks that Launcher didn't suddenly change the rotation to unexpected one. + * Null parameter disables checks. The initial state is "no checks". + */ + public void setExpectedRotation(Integer expectedRotation) { mExpectedRotation = expectedRotation; } @@ -730,8 +735,10 @@ public final class LauncherInstrumentation { private UiObject2 verifyContainerType(ContainerType containerType) { waitForLauncherInitialized(); - assertEquals("Unexpected display rotation", - mExpectedRotation, mDevice.getDisplayRotation()); + if (mExpectedRotation != null) { + assertEquals("Unexpected display rotation", + mExpectedRotation, mDevice.getDisplayRotation()); + } final String error = getNavigationModeMismatchError(true); assertTrue(error, error == null); From cee6ddf3deaed339e6d6df7f1682c725a00197b9 Mon Sep 17 00:00:00 2001 From: Hui Kang Date: Mon, 17 Oct 2022 18:27:18 +0000 Subject: [PATCH 077/429] Revert "Updating the scroll calculation from recyclerView to avoid view inflation" This reverts commit 20bbe95ddbe0d93a50e18aba4623cc844ecfb9e5. Reason for revert: Causing flake in Ironwood test: b/248295569 Test: ABTD Before: Flaky, 14/50 PASSED https://android-build.googleplex.com/builds/abtd/run/L33900000956890639 Revert: 50/50 PASSED https://android-build.googleplex.com/builds/abtd/run/L49200000956887317 Change-Id: I41f4428c74e581323f90c716a7852b5e553ae27d --- .../launcher3/FastScrollRecyclerView.java | 56 +++++- src/com/android/launcher3/Launcher.java | 2 +- .../launcher3/allapps/AllAppsGridAdapter.java | 15 +- .../allapps/AllAppsRecyclerView.java | 99 +++++++++- .../allapps/BaseAllAppsContainerView.java | 3 +- .../launcher3/allapps/FloatingHeaderView.java | 2 +- .../testing/TestInformationHandler.java | 4 +- .../util/ScrollableLayoutManager.java | 183 ------------------ .../views/RecyclerViewFastScroller.java | 6 + .../widget/picker/WidgetsRecyclerView.java | 49 ++++- .../launcher3/ui/AbstractLauncherUiTest.java | 2 +- .../launcher3/ui/TaplTestsLauncher3.java | 2 +- 12 files changed, 211 insertions(+), 212 deletions(-) delete mode 100644 src/com/android/launcher3/util/ScrollableLayoutManager.java diff --git a/src/com/android/launcher3/FastScrollRecyclerView.java b/src/com/android/launcher3/FastScrollRecyclerView.java index 2f927d3142..747b755263 100644 --- a/src/com/android/launcher3/FastScrollRecyclerView.java +++ b/src/com/android/launcher3/FastScrollRecyclerView.java @@ -24,6 +24,7 @@ import android.view.ViewGroup; import android.view.accessibility.AccessibilityNodeInfo; import androidx.annotation.Nullable; +import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.android.launcher3.compat.AccessibilityManagerCompat; @@ -91,7 +92,8 @@ public abstract class FastScrollRecyclerView extends RecyclerView { protected int getAvailableScrollHeight() { // AvailableScrollHeight = Total height of the all items - first page height int firstPageHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom(); - int availableScrollHeight = computeVerticalScrollRange() - firstPageHeight; + int totalHeightOfAllItems = getItemsHeight(/* untilIndex= */ getAdapter().getItemCount()); + int availableScrollHeight = totalHeightOfAllItems - firstPageHeight; return Math.max(0, availableScrollHeight); } @@ -144,7 +146,10 @@ public abstract class FastScrollRecyclerView extends RecyclerView { // IF scroller is at the very top OR there is no scroll bar because there is probably not // enough items to scroll, THEN it's okay for the container to be pulled down. - return computeVerticalScrollOffset() == 0; + if (getCurrentScrollY() == 0) { + return true; + } + return getAdapter() == null || getAdapter().getItemCount() == 0; } /** @@ -154,6 +159,53 @@ public abstract class FastScrollRecyclerView extends RecyclerView { return true; } + /** + * @return the scroll top of this recycler view. + */ + public int getCurrentScrollY() { + Adapter adapter = getAdapter(); + if (adapter == null) { + return -1; + } + if (adapter.getItemCount() == 0 || getChildCount() == 0) { + return -1; + } + + int itemPosition = NO_POSITION; + View child = null; + + LayoutManager layoutManager = getLayoutManager(); + if (layoutManager instanceof LinearLayoutManager) { + // Use the LayoutManager as the source of truth for visible positions. During + // animations, the view group child may not correspond to the visible views that appear + // at the top. + itemPosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition(); + child = layoutManager.findViewByPosition(itemPosition); + } + + if (child == null) { + // If the layout manager returns null for any reason, which can happen before layout + // has occurred for the position, then look at the child of this view as a ViewGroup. + child = getChildAt(0); + itemPosition = getChildAdapterPosition(child); + } + if (itemPosition == NO_POSITION) { + return -1; + } + return getPaddingTop() + getItemsHeight(itemPosition) + - layoutManager.getDecoratedTop(child); + } + + /** + * Returns the sum of the height, in pixels, of this list adapter's items from index + * 0 (inclusive) until {@code untilIndex} (exclusive). If untilIndex is same as the itemCount, + * it returns the full height of all the items. + * + *

If the untilIndex is larger than the total number of items in this adapter, returns the + * sum of all items' height. + */ + protected abstract int getItemsHeight(int untilIndex); + /** * Maps the touch (from 0..1) to the adapter position that should be visible. *

Override in each subclass of this base class. diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index c85924e439..6bdfa1c8b0 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -2779,7 +2779,7 @@ public class Launcher extends StatefulActivity View v = getFirstMatch(Collections.singletonList(activeRecyclerView), preferredItem, packageAndUserAndApp); - if (v != null && activeRecyclerView.computeVerticalScrollOffset() > 0) { + if (v != null && activeRecyclerView.getCurrentScrollY() > 0) { RectF locationBounds = new RectF(); FloatingIconView.getLocationBoundsForView(this, v, false, locationBounds, new Rect()); diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java index e0b4951caf..33d2f2b1df 100644 --- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java +++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java @@ -26,9 +26,7 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.core.view.accessibility.AccessibilityRecordCompat; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; -import androidx.recyclerview.widget.RecyclerView.Adapter; -import com.android.launcher3.util.ScrollableLayoutManager; import com.android.launcher3.views.ActivityContext; import java.util.List; @@ -64,10 +62,10 @@ public class AllAppsGridAdapter extends /** * A subclass of GridLayoutManager that overrides accessibility values during app search. */ - public class AppsGridLayoutManager extends ScrollableLayoutManager { + public class AppsGridLayoutManager extends GridLayoutManager { public AppsGridLayoutManager(Context context) { - super(context); + super(context, 1, GridLayoutManager.VERTICAL, false); } @Override @@ -127,15 +125,6 @@ public class AllAppsGridAdapter extends } return extraRows; } - - @Override - protected int incrementTotalHeight(Adapter adapter, int position, int heightUntilLastPos) { - AllAppsGridAdapter.AdapterItem item = mApps.getAdapterItems().get(position); - // only account for the first icon in the row since they are the same size within a row - return (isIconViewType(item.viewType) && item.rowAppIndex != 0) - ? heightUntilLastPos - : (heightUntilLastPos + mCachedSizes.get(item.viewType)); - } } @Override diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index 3d06fb5d41..21a7dfbb41 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -15,6 +15,8 @@ */ package com.android.launcher3.allapps; +import static android.view.View.MeasureSpec.UNSPECIFIED; + import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_SCROLLED; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_VERTICAL_SWIPE_BEGIN; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_VERTICAL_SWIPE_END; @@ -24,6 +26,7 @@ import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.util.Log; +import android.util.SparseIntArray; import androidx.recyclerview.widget.RecyclerView; @@ -46,10 +49,40 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { private static final boolean DEBUG = false; private static final boolean DEBUG_LATENCY = Utilities.isPropertyEnabled(SEARCH_LOGGING); + protected AlphabeticalAppsList mApps; protected final int mNumAppsPerRow; + + // The specific view heights that we use to calculate scroll + private final SparseIntArray mViewHeights = new SparseIntArray(); + private final SparseIntArray mCachedScrollPositions = new SparseIntArray(); private final AllAppsFastScrollHelper mFastScrollHelper; - protected AlphabeticalAppsList mApps; + + private final AdapterDataObserver mObserver = new RecyclerView.AdapterDataObserver() { + public void onChanged() { + mCachedScrollPositions.clear(); + } + + @Override + public void onItemRangeChanged(int positionStart, int itemCount) { + onChanged(); + } + + @Override + public void onItemRangeInserted(int positionStart, int itemCount) { + onChanged(); + } + + @Override + public void onItemRangeRemoved(int positionStart, int itemCount) { + onChanged(); + } + + @Override + public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { + onChanged(); + } + }; public AllAppsRecyclerView(Context context) { this(context, null); @@ -89,8 +122,12 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_ALL_APPS_DIVIDER, 1); pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_ICON, approxRows * (mNumAppsPerRow + 1)); + + mViewHeights.clear(); + mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_ICON, grid.allAppsCellHeightPx); } + @Override public void onDraw(Canvas c) { if (DEBUG) { @@ -162,6 +199,17 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { mFastScrollHelper.onFastScrollCompleted(); } + @Override + public void setAdapter(Adapter adapter) { + if (getAdapter() != null) { + getAdapter().unregisterAdapterDataObserver(mObserver); + } + super.setAdapter(adapter); + if (adapter != null) { + adapter.registerAdapterDataObserver(mObserver); + } + } + @Override protected boolean isPaddingOffsetRequired() { return true; @@ -183,13 +231,13 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { List items = mApps.getAdapterItems(); // Skip early if there are no items or we haven't been measured - if (items.isEmpty() || mNumAppsPerRow == 0 || getChildCount() == 0) { + if (items.isEmpty() || mNumAppsPerRow == 0) { mScrollbar.setThumbOffsetY(-1); return; } // Skip early if, there no child laid out in the container. - int scrollY = computeVerticalScrollOffset(); + int scrollY = getCurrentScrollY(); if (scrollY < 0) { mScrollbar.setThumbOffsetY(-1); return; @@ -244,6 +292,51 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { } } + @Override + protected int getItemsHeight(int position) { + List items = mApps.getAdapterItems(); + AllAppsGridAdapter.AdapterItem posItem = position < items.size() + ? items.get(position) : null; + int y = mCachedScrollPositions.get(position, -1); + if (y < 0) { + y = 0; + for (int i = 0; i < position; i++) { + AllAppsGridAdapter.AdapterItem item = items.get(i); + if (AllAppsGridAdapter.isIconViewType(item.viewType)) { + // Break once we reach the desired row + if (posItem != null && posItem.viewType == item.viewType && + posItem.rowIndex == item.rowIndex) { + break; + } + // Otherwise, only account for the first icon in the row since they are the same + // size within a row + if (item.rowAppIndex == 0) { + y += mViewHeights.get(item.viewType, 0); + } + } else { + // Rest of the views span the full width + int elHeight = mViewHeights.get(item.viewType); + if (elHeight == 0) { + ViewHolder holder = findViewHolderForAdapterPosition(i); + if (holder == null) { + holder = getAdapter().createViewHolder(this, item.viewType); + getAdapter().onBindViewHolder(holder, i); + holder.itemView.measure(UNSPECIFIED, UNSPECIFIED); + elHeight = holder.itemView.getMeasuredHeight(); + + getRecycledViewPool().putRecycledView(holder); + } else { + elHeight = holder.itemView.getMeasuredHeight(); + } + } + y += elHeight; + } + } + mCachedScrollPositions.put(position, y); + } + return y; + } + public int getScrollBarTop() { return getResources().getDimensionPixelOffset(R.dimen.all_apps_header_top_padding); } diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java index 7660e16a4c..879a159987 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java @@ -103,8 +103,7 @@ public abstract class BaseAllAppsContainerView l.getAppsView().getActiveRecyclerView().computeVerticalScrollOffset()); + l -> l.getAppsView().getActiveRecyclerView().getCurrentScrollY()); } case TestProtocol.REQUEST_WIDGETS_SCROLL_Y: { return getLauncherUIProperty(Bundle::putInt, - l -> WidgetsFullSheet.getWidgetsView(l).computeVerticalScrollOffset()); + l -> WidgetsFullSheet.getWidgetsView(l).getCurrentScrollY()); } case TestProtocol.REQUEST_TARGET_INSETS: { diff --git a/src/com/android/launcher3/util/ScrollableLayoutManager.java b/src/com/android/launcher3/util/ScrollableLayoutManager.java deleted file mode 100644 index 17eaefda18..0000000000 --- a/src/com/android/launcher3/util/ScrollableLayoutManager.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * Copyright (C) 2022 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.launcher3.util; - -import android.content.Context; -import android.util.SparseIntArray; -import android.view.View; - -import androidx.annotation.NonNull; -import androidx.recyclerview.widget.GridLayoutManager; -import androidx.recyclerview.widget.RecyclerView; -import androidx.recyclerview.widget.RecyclerView.Adapter; -import androidx.recyclerview.widget.RecyclerView.State; -import androidx.recyclerview.widget.RecyclerView.ViewHolder; - -/** - * Extension of {@link GridLayoutManager} with support for smooth scrolling - */ -public class ScrollableLayoutManager extends GridLayoutManager { - - // keyed on item type - protected final SparseIntArray mCachedSizes = new SparseIntArray(); - - private RecyclerView mRv; - - /** - * Precalculated total height keyed on the item position. This is always incremental. - * Subclass can override {@link #incrementTotalHeight} to incorporate the layout logic. - * For example all-apps should have same values for items in same row, - * sample values: 0, 10, 10, 10, 10, 20, 20, 20, 20 - * whereas widgets will have strictly increasing values - * sample values: 0, 10, 50, 60, 110 - */ - - // - private int[] mTotalHeightCache = new int[1]; - private int mLastValidHeightIndex = 0; - - public ScrollableLayoutManager(Context context) { - super(context, 1, GridLayoutManager.VERTICAL, false); - } - - @Override - public void onAttachedToWindow(RecyclerView view) { - super.onAttachedToWindow(view); - mRv = view; - } - - @Override - public void layoutDecorated(@NonNull View child, int left, int top, int right, int bottom) { - super.layoutDecorated(child, left, top, right, bottom); - mCachedSizes.put( - mRv.getChildViewHolder(child).getItemViewType(), child.getMeasuredHeight()); - } - - @Override - public void layoutDecoratedWithMargins(@NonNull View child, int left, int top, int right, - int bottom) { - super.layoutDecoratedWithMargins(child, left, top, right, bottom); - mCachedSizes.put( - mRv.getChildViewHolder(child).getItemViewType(), child.getMeasuredHeight()); - } - - @Override - public int computeVerticalScrollExtent(State state) { - return mRv == null ? 0 : mRv.getHeight(); - } - - @Override - public int computeVerticalScrollOffset(State state) { - Adapter adapter = mRv == null ? null : mRv.getAdapter(); - if (adapter == null) { - return 0; - } - if (adapter.getItemCount() == 0 || getChildCount() == 0) { - return 0; - } - View child = getChildAt(0); - ViewHolder holder = mRv.findContainingViewHolder(child); - if (holder == null) { - return 0; - } - int itemPosition = holder.getLayoutPosition(); - if (itemPosition < 0) { - return 0; - } - return getPaddingTop() + getItemsHeight(adapter, itemPosition) - getDecoratedTop(child); - } - - @Override - public int computeVerticalScrollRange(State state) { - Adapter adapter = mRv == null ? null : mRv.getAdapter(); - return adapter == null ? 0 : getItemsHeight(adapter, adapter.getItemCount()); - } - - /** - * Returns the sum of the height, in pixels, of this list adapter's items from index - * 0 (inclusive) until {@code untilIndex} (exclusive). If untilIndex is same as the itemCount, - * it returns the full height of all the items. - * - *

If the untilIndex is larger than the total number of items in this adapter, returns the - * sum of all items' height. - */ - private int getItemsHeight(Adapter adapter, int untilIndex) { - final int totalItems = adapter.getItemCount(); - if (mTotalHeightCache.length < (totalItems + 1)) { - mTotalHeightCache = new int[totalItems + 1]; - mLastValidHeightIndex = 0; - } - if (untilIndex > totalItems) { - untilIndex = totalItems; - } else if (untilIndex < 0) { - untilIndex = 0; - } - if (untilIndex <= mLastValidHeightIndex) { - return mTotalHeightCache[untilIndex]; - } - - int totalItemsHeight = mTotalHeightCache[mLastValidHeightIndex]; - for (int i = mLastValidHeightIndex; i < untilIndex; i++) { - totalItemsHeight = incrementTotalHeight(adapter, i, totalItemsHeight); - mTotalHeightCache[i + 1] = totalItemsHeight; - } - mLastValidHeightIndex = untilIndex; - return totalItemsHeight; - } - - /** - * The current implementation assumes a linear list with every item taking up the whole row. - * Subclasses should override this method to account for any spanning logic - */ - protected int incrementTotalHeight(Adapter adapter, int position, int heightUntilLastPos) { - return heightUntilLastPos + mCachedSizes.get(adapter.getItemViewType(position)); - } - - private void invalidateScrollCache() { - mLastValidHeightIndex = 0; - } - - @Override - public void onItemsAdded(RecyclerView recyclerView, int positionStart, int itemCount) { - super.onItemsAdded(recyclerView, positionStart, itemCount); - invalidateScrollCache(); - } - - @Override - public void onItemsChanged(RecyclerView recyclerView) { - super.onItemsChanged(recyclerView); - invalidateScrollCache(); - } - - @Override - public void onItemsRemoved(RecyclerView recyclerView, int positionStart, int itemCount) { - super.onItemsRemoved(recyclerView, positionStart, itemCount); - invalidateScrollCache(); - } - - @Override - public void onItemsMoved(RecyclerView recyclerView, int from, int to, int itemCount) { - super.onItemsMoved(recyclerView, from, to, itemCount); - invalidateScrollCache(); - } - - @Override - public void onItemsUpdated(RecyclerView recyclerView, int positionStart, int itemCount, - Object payload) { - super.onItemsUpdated(recyclerView, positionStart, itemCount, payload); - invalidateScrollCache(); - } -} diff --git a/src/com/android/launcher3/views/RecyclerViewFastScroller.java b/src/com/android/launcher3/views/RecyclerViewFastScroller.java index 3af2e3c9dc..40e4ce1c04 100644 --- a/src/com/android/launcher3/views/RecyclerViewFastScroller.java +++ b/src/com/android/launcher3/views/RecyclerViewFastScroller.java @@ -119,6 +119,7 @@ public class RecyclerViewFastScroller extends View { // prevent jumping, this offset is applied as the user scrolls. protected int mTouchOffsetY; protected int mThumbOffsetY; + protected int mRvOffsetY; // Fast scroller popup private TextView mPopupView; @@ -206,11 +207,16 @@ public class RecyclerViewFastScroller extends View { public void setThumbOffsetY(int y) { if (mThumbOffsetY == y) { + int rvCurrentOffsetY = mRv.getCurrentScrollY(); + if (mRvOffsetY != rvCurrentOffsetY) { + mRvOffsetY = mRv.getCurrentScrollY(); + } return; } updatePopupY(y); mThumbOffsetY = y; invalidate(); + mRvOffsetY = mRv.getCurrentScrollY(); } public int getThumbOffsetY() { diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java index 5969e3e154..35fa7a42cc 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java +++ b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java @@ -19,6 +19,7 @@ package com.android.launcher3.widget.picker; import android.content.Context; import android.graphics.Point; import android.util.AttributeSet; +import android.util.SparseIntArray; import android.view.MotionEvent; import androidx.recyclerview.widget.LinearLayoutManager; @@ -27,7 +28,6 @@ import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener; import com.android.launcher3.FastScrollRecyclerView; import com.android.launcher3.R; -import com.android.launcher3.util.ScrollableLayoutManager; /** * The widgets recycler view. @@ -42,6 +42,14 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte private boolean mTouchDownOnScroller; private HeaderViewDimensionsProvider mHeaderViewDimensionsProvider; + /** + * There is always 1 or 0 item of VIEW_TYPE_WIDGETS_LIST. Other types have fixes sizes, so the + * the size can be used for all other items of same type. Caching the last know size for + * VIEW_TYPE_WIDGETS_LIST allows us to use it to estimate full size even when + * VIEW_TYPE_WIDGETS_LIST is not visible on the screen. + */ + private final SparseIntArray mCachedSizes = new SparseIntArray(); + public WidgetsRecyclerView(Context context) { this(context, null); } @@ -60,7 +68,9 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte @Override protected void onFinishInflate() { super.onFinishInflate(); - setLayoutManager(new ScrollableLayoutManager(getContext())); + // create a layout manager with Launcher's context so that scroll position + // can be preserved during screen rotation. + setLayoutManager(new LinearLayoutManager(getContext())); } @Override @@ -104,7 +114,7 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte } // Skip early if, there no child laid out in the container. - int scrollY = computeVerticalScrollOffset(); + int scrollY = getCurrentScrollY(); if (scrollY < 0) { mScrollbar.setThumbOffsetY(-1); return; @@ -153,6 +163,39 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte mHeaderViewDimensionsProvider = headerViewDimensionsProvider; } + /** + * Returns the sum of the height, in pixels, of this list adapter's items from index 0 until + * {@code untilIndex}. + * + *

If the untilIndex is larger than the total number of items in this adapter, returns the + * sum of all items' height. + */ + @Override + protected int getItemsHeight(int untilIndex) { + // Initialize cache + int childCount = getChildCount(); + int startPosition; + if (childCount > 0 + && ((startPosition = getChildAdapterPosition(getChildAt(0))) != NO_POSITION)) { + int loopCount = Math.min(getChildCount(), getAdapter().getItemCount() - startPosition); + for (int i = 0; i < loopCount; i++) { + mCachedSizes.put( + mAdapter.getItemViewType(startPosition + i), + getChildAt(i).getMeasuredHeight()); + } + } + + if (untilIndex > mAdapter.getItems().size()) { + untilIndex = mAdapter.getItems().size(); + } + int totalItemsHeight = 0; + for (int i = 0; i < untilIndex; i++) { + int type = mAdapter.getItemViewType(i); + totalItemsHeight += mCachedSizes.get(type); + } + return totalItemsHeight; + } + /** * Provides dimensions of the header view that is shown at the top of a * {@link WidgetsRecyclerView}. diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index df3cbff7e0..a66b09a87d 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -525,7 +525,7 @@ public abstract class AbstractLauncherUiTest { } protected int getAllAppsScroll(Launcher launcher) { - return launcher.getAppsView().getActiveRecyclerView().computeVerticalScrollOffset(); + return launcher.getAppsView().getActiveRecyclerView().getCurrentScrollY(); } private void checkLauncherIntegrity( diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java index 07bfe4c971..be49974574 100644 --- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java +++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java @@ -303,7 +303,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { } private int getWidgetsScroll(Launcher launcher) { - return getWidgetsView(launcher).computeVerticalScrollOffset(); + return getWidgetsView(launcher).getCurrentScrollY(); } private boolean isOptionsPopupVisible(Launcher launcher) { From d6c514752411cb61c784a9c869197b4512dcebbe Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Thu, 11 Aug 2022 17:33:35 -0700 Subject: [PATCH 078/429] Landscape 3 button nav on taskbar phone supported * TODO: Seascape bar positioning, add tests Change-Id: I542be2f2f682d8c8a9cdd9bb6c667c44ca167f3e Merged-In: I542be2f2f682d8c8a9cdd9bb6c667c44ca167f3e --- .../taskbar/NavbarButtonsViewController.java | 225 ++++++++---------- .../taskbar/StashedHandleViewController.java | 4 +- .../taskbar/TaskbarActivityContext.java | 17 +- .../taskbar/TaskbarDragLayerController.java | 11 +- .../taskbar/TaskbarInsetsController.kt | 23 +- .../taskbar/TaskbarStashController.java | 10 +- .../navbutton/AbstractNavButtonLayoutter.kt | 49 ++++ .../taskbar/navbutton/KidsNavLayoutter.kt | 109 +++++++++ .../navbutton/LayoutResourceHelper.java | 68 ++++++ .../navbutton/NavButtonLayoutFactory.kt | 105 ++++++++ .../navbutton/PhoneLandscapeNavLayoutter.kt | 89 +++++++ .../navbutton/PhonePortraitNavLayoutter.kt | 83 +++++++ .../taskbar/navbutton/SetupNavLayoutter.kt | 49 ++++ .../taskbar/navbutton/TaskbarNavLayoutter.kt | 83 +++++++ .../navbutton/NavButtonLayoutFactoryTest.kt | 148 ++++++++++++ res/values/dimens.xml | 1 + .../android/launcher3/util/DimensionUtils.kt | 60 +++++ 17 files changed, 1000 insertions(+), 134 deletions(-) create mode 100644 quickstep/src/com/android/launcher3/taskbar/navbutton/AbstractNavButtonLayoutter.kt create mode 100644 quickstep/src/com/android/launcher3/taskbar/navbutton/KidsNavLayoutter.kt create mode 100644 quickstep/src/com/android/launcher3/taskbar/navbutton/LayoutResourceHelper.java create mode 100644 quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt create mode 100644 quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt create mode 100644 quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt create mode 100644 quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt create mode 100644 quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt create mode 100644 quickstep/tests/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactoryTest.kt create mode 100644 src/com/android/launcher3/util/DimensionUtils.kt diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index 339f3a9174..af422cb4c0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -23,7 +23,6 @@ import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X; import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor; import static com.android.launcher3.taskbar.LauncherTaskbarUIController.SYSUI_SURFACE_PROGRESS_INDEX; import static com.android.launcher3.taskbar.TaskbarManager.isPhoneButtonNavMode; -import static com.android.launcher3.taskbar.TaskbarManager.isPhoneMode; import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_A11Y; import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BACK; import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_HOME; @@ -54,6 +53,7 @@ import android.content.res.ColorStateList; import android.content.res.Configuration; import android.content.res.Resources; import android.graphics.Color; +import android.graphics.Point; import android.graphics.Rect; import android.graphics.Region; import android.graphics.Region.Op; @@ -81,6 +81,9 @@ import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AlphaUpdateListener; import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarButton; +import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory; +import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter; +import com.android.launcher3.util.DimensionUtils; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.TouchController; import com.android.launcher3.views.BaseDragLayer; @@ -181,6 +184,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT private final ViewTreeObserver.OnComputeInternalInsetsListener mSeparateWindowInsetsComputer = this::onComputeInsetsForSeparateWindow; private final RecentsHitboxExtender mHitboxExtender = new RecentsHitboxExtender(); + private View mRecentsButton; public NavbarButtonsViewController(TaskbarActivityContext context, FrameLayout navButtonsView) { mContext = context; @@ -203,11 +207,11 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT boolean isThreeButtonNav = mContext.isThreeButtonNav(); DeviceProfile deviceProfile = mContext.getDeviceProfile(); Resources resources = mContext.getResources(); - mNavButtonsView.getLayoutParams().height = !isPhoneMode(deviceProfile) ? - mContext.isUserSetupComplete() - ? deviceProfile.taskbarSize - : resources.getDimensionPixelSize(R.dimen.taskbar_suw_frame) - : resources.getDimensionPixelSize(R.dimen.taskbar_size); + Point p = !mContext.isUserSetupComplete() + ? new Point(0, resources.getDimensionPixelSize(R.dimen.taskbar_suw_frame)) + : DimensionUtils.getTaskbarPhoneDimensions(deviceProfile, resources, + TaskbarManager.isPhoneMode(deviceProfile)); + mNavButtonsView.getLayoutParams().height = p.y; mIsImeRenderingNavButtons = InputMethodService.canImeRenderGesturalNavButtons() && mContext.imeDrawsImeNavBar(); @@ -268,81 +272,6 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT mControllers.navButtonController); updateButtonLayoutSpacing(); updateStateForFlag(FLAG_SMALL_SCREEN, isPhoneButtonNavMode(mContext)); - if (isInSetup) { - handleSetupUi(); - - // Hide back button in SUW if keyboard is showing (IME draws its own back). - mPropertyHolders.add(new StatePropertyHolder( - mBackButtonAlpha.getProperty(ALPHA_INDEX_SUW), - flags -> (flags & FLAG_IME_VISIBLE) == 0)); - - // TODO(b/210906568) Dark intensity is currently not propagated during setup, so set - // it based on dark theme for now. - int mode = resources.getConfiguration().uiMode - & Configuration.UI_MODE_NIGHT_MASK; - boolean isDarkTheme = mode == Configuration.UI_MODE_NIGHT_YES; - mTaskbarNavButtonDarkIntensity.updateValue(isDarkTheme ? 0 : 1); - } else if (isInKidsMode) { - int iconSize = resources.getDimensionPixelSize( - R.dimen.taskbar_icon_size_kids); - int buttonWidth = resources.getDimensionPixelSize( - R.dimen.taskbar_nav_buttons_width_kids); - int buttonHeight = resources.getDimensionPixelSize( - R.dimen.taskbar_nav_buttons_height_kids); - int buttonRadius = resources.getDimensionPixelSize( - R.dimen.taskbar_nav_buttons_corner_radius_kids); - int paddingleft = (buttonWidth - iconSize) / 2; - int paddingRight = paddingleft; - int paddingTop = (buttonHeight - iconSize) / 2; - int paddingBottom = paddingTop; - - // Update icons - ((ImageView) mBackButton).setImageDrawable( - mBackButton.getContext().getDrawable(R.drawable.ic_sysbar_back_kids)); - ((ImageView) mBackButton).setScaleType(ImageView.ScaleType.FIT_CENTER); - mBackButton.setPadding(paddingleft, paddingTop, paddingRight, paddingBottom); - ((ImageView) mHomeButton).setImageDrawable( - mHomeButton.getContext().getDrawable(R.drawable.ic_sysbar_home_kids)); - ((ImageView) mHomeButton).setScaleType(ImageView.ScaleType.FIT_CENTER); - mHomeButton.setPadding(paddingleft, paddingTop, paddingRight, paddingBottom); - - // Home button layout - LinearLayout.LayoutParams homeLayoutparams = new LinearLayout.LayoutParams( - buttonWidth, - buttonHeight - ); - int homeButtonLeftMargin = resources.getDimensionPixelSize( - R.dimen.taskbar_home_button_left_margin_kids); - homeLayoutparams.setMargins(homeButtonLeftMargin, 0, 0, 0); - mHomeButton.setLayoutParams(homeLayoutparams); - - // Back button layout - LinearLayout.LayoutParams backLayoutParams = new LinearLayout.LayoutParams( - buttonWidth, - buttonHeight - ); - int backButtonLeftMargin = resources.getDimensionPixelSize( - R.dimen.taskbar_back_button_left_margin_kids); - backLayoutParams.setMargins(backButtonLeftMargin, 0, 0, 0); - mBackButton.setLayoutParams(backLayoutParams); - - // Button backgrounds - int whiteWith10PctAlpha = Color.argb(0.1f, 1, 1, 1); - PaintDrawable buttonBackground = new PaintDrawable(whiteWith10PctAlpha); - buttonBackground.setCornerRadius(buttonRadius); - mHomeButton.setBackground(buttonBackground); - mBackButton.setBackground(buttonBackground); - - // Update alignment within taskbar - FrameLayout.LayoutParams navButtonsLayoutParams = (FrameLayout.LayoutParams) - mNavButtonContainer.getLayoutParams(); - navButtonsLayoutParams.setMarginStart(navButtonsLayoutParams.getMarginEnd() / 2); - navButtonsLayoutParams.setMarginEnd(navButtonsLayoutParams.getMarginStart()); - navButtonsLayoutParams.gravity = Gravity.CENTER; - mNavButtonContainer.requestLayout(); - - mHomeButton.setOnLongClickListener(null); - } // Animate taskbar background when either.. // notification shade expanded AND not on keyguard @@ -445,20 +374,20 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT (flags & FLAG_DISABLE_HOME) == 0)); // Recents button - View recentsButton = addButton(R.drawable.ic_sysbar_recent, BUTTON_RECENTS, + mRecentsButton = addButton(R.drawable.ic_sysbar_recent, BUTTON_RECENTS, navContainer, navButtonController, R.id.recent_apps); - mHitboxExtender.init(recentsButton, mNavButtonsView, mContext.getDeviceProfile(), + mHitboxExtender.init(mRecentsButton, mNavButtonsView, mContext.getDeviceProfile(), () -> { float[] recentsCoords = new float[2]; - getDescendantCoordRelativeToAncestor(recentsButton, mNavButtonsView, + getDescendantCoordRelativeToAncestor(mRecentsButton, mNavButtonsView, recentsCoords, false); return recentsCoords; }, new Handler()); - recentsButton.setOnClickListener(v -> { + mRecentsButton.setOnClickListener(v -> { navButtonController.onButtonClick(BUTTON_RECENTS, v); mHitboxExtender.onRecentsButtonClicked(); }); - mPropertyHolders.add(new StatePropertyHolder(recentsButton, + mPropertyHolders.add(new StatePropertyHolder(mRecentsButton, flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0 && (flags & FLAG_DISABLE_RECENTS) == 0 && !mContext.isNavBarKidsModeActive())); @@ -773,14 +702,22 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT || !mContext.isUserSetupComplete()) { return; } - - if (isPhoneButtonNavMode(mContext)) { - updatePhoneButtonSpacing(); - return; - } - DeviceProfile dp = mContext.getDeviceProfile(); Resources res = mContext.getResources(); + boolean isInSetup = !mContext.isUserSetupComplete(); + // TODO(b/244231596) we're getting the incorrect kidsMode value in small-screen + boolean isInKidsMode = mContext.isNavBarKidsModeActive(); + + if (TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW) { + boolean isThreeButtonNav = mContext.isThreeButtonNav(); + + NavButtonLayoutter navButtonLayoutter = + NavButtonLayoutFactory.Companion.getUiLayoutter( + dp, mNavButtonsView, res, isInKidsMode, isInSetup, isThreeButtonNav, + TaskbarManager.isPhoneMode(dp)); + navButtonLayoutter.layoutButtons(dp, isContextualButtonShowing()); + return; + } // Add spacing after the end of the last nav button FrameLayout.LayoutParams navButtonParams = @@ -816,38 +753,84 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT buttonLayoutParams.setMarginEnd(spaceInBetween / 2); } } - } - /** Uniformly spaces out the 3 button nav for smaller phone screens */ - private void updatePhoneButtonSpacing() { - DeviceProfile dp = mContext.getDeviceProfile(); - Resources res = mContext.getResources(); + if (isInSetup) { + handleSetupUi(); - // TODO: Polish pending, this is just to make it usable - FrameLayout.LayoutParams navContainerParams = - (FrameLayout.LayoutParams) mNavButtonContainer.getLayoutParams(); - int endStartMargins = res.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size); - navContainerParams.gravity = Gravity.CENTER; - navContainerParams.setMarginEnd(endStartMargins); - navContainerParams.setMarginStart(endStartMargins); - mNavButtonContainer.setLayoutParams(navContainerParams); + // Hide back button in SUW if keyboard is showing (IME draws its own back). + mPropertyHolders.add(new StatePropertyHolder( + mBackButtonAlpha.getProperty(ALPHA_INDEX_SUW), + flags -> (flags & FLAG_IME_VISIBLE) == 0)); - // Add the spaces in between the nav buttons - int spaceInBetween = res.getDimensionPixelSize(R.dimen.taskbar_button_space_inbetween_phone); - for (int i = 0; i < mNavButtonContainer.getChildCount(); i++) { - View navButton = mNavButtonContainer.getChildAt(i); - LinearLayout.LayoutParams buttonLayoutParams = - (LinearLayout.LayoutParams) navButton.getLayoutParams(); - buttonLayoutParams.weight = 1; - if (i == 0) { - buttonLayoutParams.setMarginEnd(spaceInBetween / 2); - } else if (i == mNavButtonContainer.getChildCount() - 1) { - buttonLayoutParams.setMarginStart(spaceInBetween / 2); - } else { - buttonLayoutParams.setMarginStart(spaceInBetween / 2); - buttonLayoutParams.setMarginEnd(spaceInBetween / 2); - } + // TODO(b/210906568) Dark intensity is currently not propagated during setup, so set + // it based on dark theme for now. + int mode = res.getConfiguration().uiMode + & Configuration.UI_MODE_NIGHT_MASK; + boolean isDarkTheme = mode == Configuration.UI_MODE_NIGHT_YES; + mTaskbarNavButtonDarkIntensity.updateValue(isDarkTheme ? 0 : 1); + } else if (isInKidsMode) { + int iconSize = res.getDimensionPixelSize( + R.dimen.taskbar_icon_size_kids); + int buttonWidth = res.getDimensionPixelSize( + R.dimen.taskbar_nav_buttons_width_kids); + int buttonHeight = res.getDimensionPixelSize( + R.dimen.taskbar_nav_buttons_height_kids); + int buttonRadius = res.getDimensionPixelSize( + R.dimen.taskbar_nav_buttons_corner_radius_kids); + int paddingleft = (buttonWidth - iconSize) / 2; + int paddingRight = paddingleft; + int paddingTop = (buttonHeight - iconSize) / 2; + int paddingBottom = paddingTop; + + // Update icons + ((ImageView) mBackButton).setImageDrawable( + mBackButton.getContext().getDrawable(R.drawable.ic_sysbar_back_kids)); + ((ImageView) mBackButton).setScaleType(ImageView.ScaleType.FIT_CENTER); + mBackButton.setPadding(paddingleft, paddingTop, paddingRight, paddingBottom); + ((ImageView) mHomeButton).setImageDrawable( + mHomeButton.getContext().getDrawable(R.drawable.ic_sysbar_home_kids)); + ((ImageView) mHomeButton).setScaleType(ImageView.ScaleType.FIT_CENTER); + mHomeButton.setPadding(paddingleft, paddingTop, paddingRight, paddingBottom); + + // Home button layout + LinearLayout.LayoutParams homeLayoutparams = new LinearLayout.LayoutParams( + buttonWidth, + buttonHeight + ); + int homeButtonLeftMargin = res.getDimensionPixelSize( + R.dimen.taskbar_home_button_left_margin_kids); + homeLayoutparams.setMargins(homeButtonLeftMargin, 0, 0, 0); + mHomeButton.setLayoutParams(homeLayoutparams); + + // Back button layout + LinearLayout.LayoutParams backLayoutParams = new LinearLayout.LayoutParams( + buttonWidth, + buttonHeight + ); + int backButtonLeftMargin = res.getDimensionPixelSize( + R.dimen.taskbar_back_button_left_margin_kids); + backLayoutParams.setMargins(backButtonLeftMargin, 0, 0, 0); + mBackButton.setLayoutParams(backLayoutParams); + + // Button backgrounds + int whiteWith10PctAlpha = Color.argb(0.1f, 1, 1, 1); + PaintDrawable buttonBackground = new PaintDrawable(whiteWith10PctAlpha); + buttonBackground.setCornerRadius(buttonRadius); + mHomeButton.setBackground(buttonBackground); + mBackButton.setBackground(buttonBackground); + + // Update alignment within taskbar + FrameLayout.LayoutParams navButtonsLayoutParams = (FrameLayout.LayoutParams) + mNavButtonContainer.getLayoutParams(); + navButtonsLayoutParams.setMarginStart( + navButtonsLayoutParams.getMarginEnd() / 2); + navButtonsLayoutParams.setMarginEnd(navButtonsLayoutParams.getMarginStart()); + navButtonsLayoutParams.gravity = Gravity.CENTER; + mNavButtonContainer.requestLayout(); + + mHomeButton.setOnLongClickListener(null); } + } public void onDestroy() { @@ -859,6 +842,8 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT moveNavButtonsBackToTaskbarWindow(); mNavButtonContainer.removeAllViews(); + mEndContextualContainer.removeAllViews(); + mStartContextualContainer.removeAllViews(); mAllButtons.clear(); } diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java index 6b67b50fd8..e23e27ed0f 100644 --- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java @@ -101,8 +101,8 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT resources.getDimensionPixelSize(R.dimen.taskbar_stashed_small_screen); } else { mStashedHandleView.getLayoutParams().height = deviceProfile.taskbarSize; - mStashedHandleWidth = - resources.getDimensionPixelSize(R.dimen.taskbar_stashed_handle_width); + mStashedHandleWidth = resources + .getDimensionPixelSize(R.dimen.taskbar_stashed_handle_width); } mTaskbarStashedHandleAlpha.getProperty(ALPHA_INDEX_STASHED).setValue( diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 72c163ebc3..0c488cb4b1 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -154,6 +154,8 @@ public class TaskbarActivityContext extends BaseTaskbarContext { Settings.Secure.getUriFor(Settings.Secure.USER_SETUP_COMPLETE), 0); mIsNavBarForceVisible = settingsCache.getValue( Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_KIDS_MODE), 0); + // TODO(b/244231596) For shared Taskbar window, update this value in init() instead so + // to get correct value when recreating the taskbar mIsNavBarKidsMode = settingsCache.getValue( Settings.Secure.getUriFor(Settings.Secure.NAV_BAR_KIDS_MODE), 0); @@ -276,9 +278,13 @@ public class TaskbarActivityContext extends BaseTaskbarContext { * @param type The window type to pass to the created WindowManager.LayoutParams. */ public WindowManager.LayoutParams createDefaultWindowLayoutParams(int type) { + DeviceProfile deviceProfile = getDeviceProfile(); + // Taskbar is on the logical bottom of the screen + boolean isVerticalBarLayout = TaskbarManager.isPhoneMode(deviceProfile) && + deviceProfile.isLandscape; WindowManager.LayoutParams windowLayoutParams = new WindowManager.LayoutParams( - MATCH_PARENT, - mLastRequestedNonFullscreenHeight, + isVerticalBarLayout ? mLastRequestedNonFullscreenHeight : MATCH_PARENT, + isVerticalBarLayout ? MATCH_PARENT : mLastRequestedNonFullscreenHeight, type, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_SLIPPERY @@ -286,7 +292,10 @@ public class TaskbarActivityContext extends BaseTaskbarContext { PixelFormat.TRANSLUCENT); windowLayoutParams.setTitle(WINDOW_TITLE); windowLayoutParams.packageName = getPackageName(); - windowLayoutParams.gravity = Gravity.BOTTOM; + windowLayoutParams.gravity = !isVerticalBarLayout ? + Gravity.BOTTOM : + Gravity.END; // TODO(b/230394142): seascape + windowLayoutParams.setFitInsetsTypes(0); windowLayoutParams.receiveInsetsIgnoringZOrder = true; windowLayoutParams.softInputMode = WindowManager.LayoutParams.SOFT_INPUT_ADJUST_NOTHING; @@ -803,7 +812,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { return mIsUserSetupComplete; } - protected boolean isNavBarKidsModeActive() { + public boolean isNavBarKidsModeActive() { return mIsNavBarKidsMode && isThreeButtonNav(); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java index 025fe7a017..353f1e03cb 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java @@ -16,11 +16,13 @@ package com.android.launcher3.taskbar; import android.content.res.Resources; +import android.graphics.Point; import android.graphics.Rect; import android.view.ViewTreeObserver; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; +import com.android.launcher3.util.DimensionUtils; import com.android.launcher3.util.TouchController; import com.android.quickstep.AnimatedFloat; @@ -177,9 +179,12 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa DeviceProfile deviceProfile = mActivity.getDeviceProfile(); if (TaskbarManager.isPhoneMode(deviceProfile)) { Resources resources = mActivity.getResources(); - return mActivity.isThreeButtonNav() ? - resources.getDimensionPixelSize(R.dimen.taskbar_size) : - resources.getDimensionPixelSize(R.dimen.taskbar_stashed_size); + Point taskbarDimensions = + DimensionUtils.getTaskbarPhoneDimensions(deviceProfile, resources, + TaskbarManager.isPhoneMode(deviceProfile)); + return taskbarDimensions.y == -1 ? + deviceProfile.getDisplayInfo().currentSize.y : + taskbarDimensions.y; } else { return deviceProfile.taskbarSize; } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt index 079e8a1f2d..bbbc1e6b80 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt @@ -84,16 +84,16 @@ class TaskbarInsetsController(val context: TaskbarActivityContext): LoggableTask val tappableHeight = controllers.taskbarStashController.tappableHeightToReportToApps for (provider in windowLayoutParams.providedInsets) { if (provider.type == ITYPE_EXTRA_NAVIGATION_BAR) { - provider.insetsSize = Insets.of(0, 0, 0, contentHeight) + provider.insetsSize = getInsetsByNavMode(contentHeight) } else if (provider.type == ITYPE_BOTTOM_TAPPABLE_ELEMENT || provider.type == ITYPE_BOTTOM_MANDATORY_GESTURES) { - provider.insetsSize = Insets.of(0, 0, 0, tappableHeight) + provider.insetsSize = getInsetsByNavMode(tappableHeight) } } - val imeInsetsSize = Insets.of(0, 0, 0, taskbarHeightForIme) + val imeInsetsSize = getInsetsByNavMode(taskbarHeightForIme) // Use 0 insets for the VoiceInteractionWindow (assistant) when gesture nav is enabled. - val visInsetsSize = Insets.of(0, 0, 0, if (context.isGestureNav) 0 else tappableHeight) + val visInsetsSize = getInsetsByNavMode(if (context.isGestureNav) 0 else tappableHeight) val insetsSizeOverride = arrayOf( InsetsFrameProvider.InsetsSizeOverride( TYPE_INPUT_METHOD, @@ -109,6 +109,21 @@ class TaskbarInsetsController(val context: TaskbarActivityContext): LoggableTask } } + /** + * @return [Insets] where the [bottomInset] is either used as a bottom inset or + * right/left inset if using 3 button nav + */ + private fun getInsetsByNavMode(bottomInset: Int) : Insets { + val devicePortrait = !context.deviceProfile.isLandscape + if (!TaskbarManager.isPhoneButtonNavMode(context) || devicePortrait) { + // Taskbar or portrait phone mode + return Insets.of(0, 0, 0, bottomInset) + } + + // TODO(b/230394142): seascape + return Insets.of(0, 0, bottomInset, 0) + } + /** * Sets {@param providesInsetsTypes} as the inset types provided by {@param params}. * @param params The window layout params. diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 9fd2bf90b3..c5e1b8fdcd 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -715,8 +715,16 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba applyState(skipAnim ? 0 : animDuration, skipAnim ? 0 : startDelay); } + /** + * We stash when IME or IME switcher is showing AND NOT + * * in small screen AND + * * 3 button nav AND + * * landscape (or seascape) + */ private boolean shouldStashForIme() { - return mIsImeShowing || mIsImeSwitcherShowing; + return (mIsImeShowing || mIsImeSwitcherShowing) && + !(isPhoneMode() && mActivity.isThreeButtonNav() + && mActivity.getDeviceProfile().isLandscape); } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/AbstractNavButtonLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/AbstractNavButtonLayoutter.kt new file mode 100644 index 0000000000..68ea27a8ec --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/AbstractNavButtonLayoutter.kt @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2022 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.launcher3.taskbar.navbutton + +import android.content.res.Resources +import android.view.ViewGroup +import android.widget.ImageView +import android.widget.LinearLayout +import com.android.launcher3.R +import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter + +/** + * Meant to be a simple container for data subclasses will need + * + * Assumes that the 3 navigation buttons (back/home/recents) have already been added to + * [navButtonContainer] + * + * @property navButtonContainer ViewGroup that holds the 3 navigation buttons. + * @property endContextualContainer ViewGroup that holds the end contextual button (ex, IME dismiss). + * @property startContextualContainer ViewGroup that holds the start contextual button (ex, A11y). + */ +abstract class AbstractNavButtonLayoutter( + val resources: Resources, + val navButtonContainer: LinearLayout, + protected val endContextualContainer: ViewGroup, + protected val startContextualContainer: ViewGroup +) : NavButtonLayoutter { + protected val homeButton: ImageView = navButtonContainer + .findViewById(R.id.home) + protected val recentsButton: ImageView = navButtonContainer + .findViewById(R.id.recent_apps) + protected val backButton: ImageView = navButtonContainer + .findViewById(R.id.back) +} + diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/KidsNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/KidsNavLayoutter.kt new file mode 100644 index 0000000000..c67ab7964e --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/KidsNavLayoutter.kt @@ -0,0 +1,109 @@ +/* + * Copyright (C) 2022 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.launcher3.taskbar.navbutton + +import android.content.res.Resources +import android.graphics.Color +import android.graphics.drawable.PaintDrawable +import android.view.Gravity +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.ImageView +import android.widget.LinearLayout +import com.android.launcher3.DeviceProfile +import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.DIMEN_TASKBAR_BACK_BUTTON_LEFT_MARGIN_KIDS +import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.DIMEN_TASKBAR_HOME_BUTTON_LEFT_MARGIN_KIDS +import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.DIMEN_TASKBAR_ICON_SIZE_KIDS +import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.DIMEN_TASKBAR_NAV_BUTTONS_CORNER_RADIUS_KIDS +import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.DIMEN_TASKBAR_NAV_BUTTONS_HEIGHT_KIDS +import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.DIMEN_TASKBAR_NAV_BUTTONS_WIDTH_KIDS +import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.DRAWABLE_SYSBAR_BACK_KIDS +import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.DRAWABLE_SYSBAR_HOME_KIDS + +class KidsNavLayoutter( + resources: Resources, + navBarContainer: LinearLayout, + endContextualContainer: ViewGroup, + startContextualContainer: ViewGroup +) : AbstractNavButtonLayoutter( + resources, + navBarContainer, + endContextualContainer, + startContextualContainer +) { + + override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) { + val iconSize: Int = resources.getDimensionPixelSize( + DIMEN_TASKBAR_ICON_SIZE_KIDS) + val buttonWidth: Int = resources.getDimensionPixelSize( + DIMEN_TASKBAR_NAV_BUTTONS_WIDTH_KIDS) + val buttonHeight: Int = resources.getDimensionPixelSize( + DIMEN_TASKBAR_NAV_BUTTONS_HEIGHT_KIDS) + val buttonRadius: Int = resources.getDimensionPixelSize( + DIMEN_TASKBAR_NAV_BUTTONS_CORNER_RADIUS_KIDS) + val paddingLeft = (buttonWidth - iconSize) / 2 + val paddingTop = (buttonHeight - iconSize) / 2 + + // Update icons + backButton.setImageDrawable( + backButton.context.getDrawable(DRAWABLE_SYSBAR_BACK_KIDS)) + backButton.scaleType = ImageView.ScaleType.FIT_CENTER + backButton.setPadding(paddingLeft, paddingTop, paddingLeft, paddingTop) + homeButton.setImageDrawable( + homeButton.getContext().getDrawable(DRAWABLE_SYSBAR_HOME_KIDS)) + homeButton.scaleType = ImageView.ScaleType.FIT_CENTER + homeButton.setPadding(paddingLeft, paddingTop, paddingLeft, paddingTop) + + // Home button layout + val homeLayoutparams = LinearLayout.LayoutParams( + buttonWidth, + buttonHeight + ) + val homeButtonLeftMargin: Int = resources.getDimensionPixelSize( + DIMEN_TASKBAR_HOME_BUTTON_LEFT_MARGIN_KIDS) + homeLayoutparams.setMargins(homeButtonLeftMargin, 0, 0, 0) + homeButton.layoutParams = homeLayoutparams + + // Back button layout + val backLayoutParams = LinearLayout.LayoutParams( + buttonWidth, + buttonHeight + ) + val backButtonLeftMargin: Int = resources.getDimensionPixelSize( + DIMEN_TASKBAR_BACK_BUTTON_LEFT_MARGIN_KIDS) + backLayoutParams.setMargins(backButtonLeftMargin, 0, 0, 0) + backButton.layoutParams = backLayoutParams + + // Button backgrounds + val whiteWith10PctAlpha = Color.argb(0.1f, 1f, 1f, 1f) + val buttonBackground = PaintDrawable(whiteWith10PctAlpha) + buttonBackground.setCornerRadius(buttonRadius.toFloat()) + homeButton.background = buttonBackground + backButton.background = buttonBackground + + // Update alignment within taskbar + val navButtonsLayoutParams = navButtonContainer.layoutParams as FrameLayout.LayoutParams + navButtonsLayoutParams.apply { + marginStart = navButtonsLayoutParams.marginEnd / 2 + marginEnd = navButtonsLayoutParams.marginStart + gravity = Gravity.CENTER + } + navButtonContainer.requestLayout() + + homeButton.onLongClickListener = null + } +} \ No newline at end of file diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/LayoutResourceHelper.java b/quickstep/src/com/android/launcher3/taskbar/navbutton/LayoutResourceHelper.java new file mode 100644 index 0000000000..0d9b855c91 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/LayoutResourceHelper.java @@ -0,0 +1,68 @@ +/* + * Copyright (C) 2022 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.launcher3.taskbar.navbutton; + +import android.annotation.DimenRes; +import android.annotation.DrawableRes; +import android.annotation.IdRes; + +import com.android.launcher3.R; + +/** + * A class for retrieving resources in Kotlin. + * + * This class should be removed once the build system supports resources loading in Kotlin. + */ +public final class LayoutResourceHelper { + + // -------------------------- + // Kids Nav Layout + @DimenRes + public static final int DIMEN_TASKBAR_ICON_SIZE_KIDS = R.dimen.taskbar_icon_size_kids; + @DrawableRes + public static final int DRAWABLE_SYSBAR_BACK_KIDS = R.drawable.ic_sysbar_back_kids; + @DrawableRes + public static final int DRAWABLE_SYSBAR_HOME_KIDS = R.drawable.ic_sysbar_home_kids; + @DimenRes + public static final int DIMEN_TASKBAR_HOME_BUTTON_LEFT_MARGIN_KIDS = + R.dimen.taskbar_home_button_left_margin_kids; + @DimenRes + public static final int DIMEN_TASKBAR_BACK_BUTTON_LEFT_MARGIN_KIDS = + R.dimen.taskbar_back_button_left_margin_kids; + @DimenRes + public static final int DIMEN_TASKBAR_NAV_BUTTONS_WIDTH_KIDS = + R.dimen.taskbar_nav_buttons_width_kids; + @DimenRes + public static final int DIMEN_TASKBAR_NAV_BUTTONS_HEIGHT_KIDS = + R.dimen.taskbar_nav_buttons_height_kids; + @DimenRes + public static final int DIMEN_TASKBAR_NAV_BUTTONS_CORNER_RADIUS_KIDS = + R.dimen.taskbar_nav_buttons_corner_radius_kids; + + // -------------------------- + // Nav Layout Factory + @IdRes + public static final int ID_START_CONTEXTUAL_BUTTONS = R.id.start_contextual_buttons; + @IdRes + public static final int ID_END_CONTEXTUAL_BUTTONS = R.id.end_contextual_buttons; + @IdRes + public static final int ID_END_NAV_BUTTONS = R.id.end_nav_buttons; + + private LayoutResourceHelper() { + + } +} diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt new file mode 100644 index 0000000000..db0a2d8d44 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt @@ -0,0 +1,105 @@ +/* + * Copyright (C) 2022 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.launcher3.taskbar.navbutton + +import android.content.res.Resources +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.LinearLayout +import com.android.launcher3.DeviceProfile +import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.ID_END_CONTEXTUAL_BUTTONS +import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.ID_END_NAV_BUTTONS +import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.ID_START_CONTEXTUAL_BUTTONS +import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.Companion +import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter + +/** + * Select the correct layout for nav buttons + * + * Since layouts are done dynamically for the nav buttons on Taskbar, this + * class returns a corresponding [NavButtonLayoutter] via + * [Companion.getUiLayoutter] + * that can help position the buttons based on the current [DeviceProfile] + */ +class NavButtonLayoutFactory { + companion object { + /** + * Get the correct instance of [NavButtonLayoutter] + * + * No layouts supported for configurations where: + * * taskbar isn't showing AND + * * the device is not in [phoneMode] + * OR + * * phone is showing + * * device is using gesture navigation + * + * @param navButtonsView ViewGroup that contains start, end, nav button ViewGroups + * @param isKidsMode no-op when taskbar is hidden/not showing + * @param isInSetup no-op when taskbar is hidden/not showing + * @param phoneMode refers to the device using the taskbar window on phones + * @param isThreeButtonNav are no-ops when taskbar is present/showing + */ + fun getUiLayoutter(deviceProfile: DeviceProfile, + navButtonsView: FrameLayout, + resources: Resources, + isKidsMode: Boolean, + isInSetup: Boolean, + isThreeButtonNav: Boolean, + phoneMode: Boolean): + NavButtonLayoutter { + val navButtonContainer = + navButtonsView.findViewById(ID_END_NAV_BUTTONS) + val endContextualContainer = + navButtonsView.findViewById(ID_END_CONTEXTUAL_BUTTONS) + val startContextualContainer = + navButtonsView.findViewById(ID_START_CONTEXTUAL_BUTTONS) + val isPhoneNavMode = phoneMode && isThreeButtonNav + return when { + isPhoneNavMode -> { + if (!deviceProfile.isLandscape) { + PhonePortraitNavLayoutter(resources, navButtonContainer, + endContextualContainer, startContextualContainer) + } else { + PhoneLandscapeNavLayoutter(resources, navButtonContainer, + endContextualContainer, startContextualContainer) + } + } + deviceProfile.isTaskbarPresent -> { + return when { + isInSetup -> { + SetupNavLayoutter(resources, navButtonContainer, endContextualContainer, + startContextualContainer) + } + isKidsMode -> { + KidsNavLayoutter(resources, navButtonContainer, endContextualContainer, + startContextualContainer) + } + else -> + TaskbarNavLayoutter(resources, navButtonContainer, endContextualContainer, + startContextualContainer) + } + } + else -> error("No layoutter found") + } + } + } + + /** Lays out and provides access to the home, recents, and back buttons for various mischief */ + interface NavButtonLayoutter { + fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) + } +} \ No newline at end of file diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt new file mode 100644 index 0000000000..a89476e15a --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt @@ -0,0 +1,89 @@ +/* + * Copyright (C) 2022 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.launcher3.taskbar.navbutton + +import android.content.res.Resources +import android.view.Gravity +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.LinearLayout +import androidx.core.view.children +import com.android.launcher3.DeviceProfile +import com.android.launcher3.R +import com.android.launcher3.taskbar.TaskbarManager +import com.android.launcher3.util.DimensionUtils + +class PhoneLandscapeNavLayoutter( + resources: Resources, + navBarContainer: LinearLayout, + endContextualContainer: ViewGroup, + startContextualContainer: ViewGroup +) : AbstractNavButtonLayoutter( + resources, + navBarContainer, + endContextualContainer, + startContextualContainer +) { + + override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) { + // TODO(b/230395757): Polish pending, this is just to make it usable + val navContainerParams = navButtonContainer.layoutParams as FrameLayout.LayoutParams + val endStartMargins = + resources.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size) + val taskbarDimensions = DimensionUtils.getTaskbarPhoneDimensions(dp, resources, + TaskbarManager.isPhoneMode(dp)) + navButtonContainer.removeAllViews() + navButtonContainer.orientation = LinearLayout.VERTICAL + + navContainerParams.apply { + width = taskbarDimensions.x + height = ViewGroup.LayoutParams.MATCH_PARENT + gravity = Gravity.CENTER + topMargin = endStartMargins + bottomMargin = endStartMargins + marginEnd = 0 + marginStart = 0 + } + + // Swap recents and back button + navButtonContainer.addView(recentsButton) + navButtonContainer.addView(homeButton) + navButtonContainer.addView(backButton) + + navButtonContainer.layoutParams = navContainerParams + + // Add the spaces in between the nav buttons + val spaceInBetween: Int = + resources.getDimensionPixelSize(R.dimen.taskbar_button_space_inbetween_phone) + navButtonContainer.children.forEachIndexed { i, navButton -> + val buttonLayoutParams = navButton.layoutParams as LinearLayout.LayoutParams + buttonLayoutParams.weight = 1f + when (i) { + 0 -> { + buttonLayoutParams.bottomMargin = spaceInBetween / 2 + } + navButtonContainer.childCount - 1 -> { + buttonLayoutParams.topMargin = spaceInBetween / 2 + } + else -> { + buttonLayoutParams.bottomMargin = spaceInBetween / 2 + buttonLayoutParams.topMargin = spaceInBetween / 2 + } + } + } + } +} \ No newline at end of file diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt new file mode 100644 index 0000000000..275f59faef --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2022 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.launcher3.taskbar.navbutton + +import android.content.res.Resources +import android.view.Gravity +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.LinearLayout +import com.android.launcher3.DeviceProfile +import com.android.launcher3.R +import com.android.launcher3.taskbar.TaskbarManager +import com.android.launcher3.util.DimensionUtils + +class PhonePortraitNavLayoutter(resources: Resources, navBarContainer: LinearLayout, + endContextualContainer: ViewGroup, + startContextualContainer: ViewGroup) : + AbstractNavButtonLayoutter(resources, navBarContainer, endContextualContainer, + startContextualContainer) { + + override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) { + // TODO(b/230395757): Polish pending, this is just to make it usable + val navContainerParams = navButtonContainer.layoutParams as FrameLayout.LayoutParams + val taskbarDimensions = DimensionUtils.getTaskbarPhoneDimensions(dp, resources, + TaskbarManager.isPhoneMode(dp)) + val endStartMargins = resources.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size) + navContainerParams.width = taskbarDimensions.x + navContainerParams.height = ViewGroup.LayoutParams.MATCH_PARENT + navContainerParams.gravity = Gravity.CENTER_VERTICAL + + // Ensure order of buttons is correct + navButtonContainer.removeAllViews() + navButtonContainer.orientation = LinearLayout.HORIZONTAL + navContainerParams.topMargin = 0 + navContainerParams.bottomMargin = 0 + navContainerParams.marginEnd = endStartMargins + navContainerParams.marginStart = endStartMargins + // Swap recents and back button in case we were landscape prior to this + navButtonContainer.addView(backButton) + navButtonContainer.addView(homeButton) + navButtonContainer.addView(recentsButton) + + navButtonContainer.layoutParams = navContainerParams + + // Add the spaces in between the nav buttons + val spaceInBetween = + resources.getDimensionPixelSize(R.dimen.taskbar_button_space_inbetween_phone) + for (i in 0 until navButtonContainer.childCount) { + val navButton = navButtonContainer.getChildAt(i) + val buttonLayoutParams = navButton.layoutParams as LinearLayout.LayoutParams + buttonLayoutParams.weight = 1f + when (i) { + 0 -> { + // First button + buttonLayoutParams.marginEnd = spaceInBetween / 2 + } + navButtonContainer.childCount - 1 -> { + // Last button + buttonLayoutParams.marginStart = spaceInBetween / 2 + } + else -> { + // other buttons + buttonLayoutParams.marginStart = spaceInBetween / 2 + buttonLayoutParams.marginEnd = spaceInBetween / 2 + } + } + } + } +} \ No newline at end of file diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt new file mode 100644 index 0000000000..afe70d6c21 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt @@ -0,0 +1,49 @@ +/* + * Copyright (C) 2022 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.launcher3.taskbar.navbutton + +import android.content.res.Resources +import android.view.Gravity +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.LinearLayout +import com.android.launcher3.DeviceProfile + +class SetupNavLayoutter( + resources: Resources, + navButtonContainer: LinearLayout, + endContextualContainer: ViewGroup, + startContextualContainer: ViewGroup +) : AbstractNavButtonLayoutter( + resources, + navButtonContainer, + endContextualContainer, + startContextualContainer +) { + + override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) { + // Since setup wizard only has back button enabled, it looks strange to be + // end-aligned, so start-align instead. + val navButtonsLayoutParams = navButtonContainer.layoutParams as FrameLayout.LayoutParams + navButtonsLayoutParams.apply { + marginStart = navButtonsLayoutParams.marginEnd + marginEnd = 0 + gravity = Gravity.START + } + navButtonContainer.requestLayout() + } +} \ No newline at end of file diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt new file mode 100644 index 0000000000..b2ca2afa04 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2022 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.launcher3.taskbar.navbutton + +import android.content.res.Resources +import android.view.Gravity +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.LinearLayout +import com.android.launcher3.DeviceProfile +import com.android.launcher3.R + +/** + * Layoutter for showing 3 button navigation on large screen + */ +class TaskbarNavLayoutter( + resources: Resources, + navBarContainer: LinearLayout, + endContextualContainer: ViewGroup, + startContextualContainer: ViewGroup +) : AbstractNavButtonLayoutter( + resources, + navBarContainer, + endContextualContainer, + startContextualContainer +) { + + override fun layoutButtons(dp: DeviceProfile, isContextualButtonShowing: Boolean) { + // Add spacing after the end of the last nav button + val navButtonParams = navButtonContainer.layoutParams as FrameLayout.LayoutParams + var navMarginEnd = resources.getDimension(dp.inv.inlineNavButtonsEndSpacing).toInt() + val contextualWidth = endContextualContainer.width + // If contextual buttons are showing, we check if the end margin is enough for the + // contextual button to be showing - if not, move the nav buttons over a smidge + if (isContextualButtonShowing && navMarginEnd < contextualWidth) { + // Additional spacing, eat up half of space between last icon and nav button + navMarginEnd += resources.getDimensionPixelSize(R.dimen.taskbar_hotseat_nav_spacing) / 2 + } + + navButtonParams.apply { + gravity = Gravity.END + width = FrameLayout.LayoutParams.WRAP_CONTENT + height = ViewGroup.LayoutParams.MATCH_PARENT + marginEnd = navMarginEnd + } + navButtonContainer.orientation = LinearLayout.HORIZONTAL + navButtonContainer.layoutParams = navButtonParams + + // Add the spaces in between the nav buttons + val spaceInBetween = resources.getDimensionPixelSize(R.dimen.taskbar_button_space_inbetween) + for (i in 0 until navButtonContainer.childCount) { + val navButton = navButtonContainer.getChildAt(i) + val buttonLayoutParams = navButton.layoutParams as LinearLayout.LayoutParams + buttonLayoutParams.weight = 0f + when (i) { + 0 -> { + buttonLayoutParams.marginEnd = spaceInBetween / 2 + } + navButtonContainer.childCount - 1 -> { + buttonLayoutParams.marginStart = spaceInBetween / 2 + } + else -> { + buttonLayoutParams.marginStart = spaceInBetween / 2 + buttonLayoutParams.marginEnd = spaceInBetween / 2 + } + } + } + } +} \ No newline at end of file diff --git a/quickstep/tests/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactoryTest.kt b/quickstep/tests/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactoryTest.kt new file mode 100644 index 0000000000..58f0949213 --- /dev/null +++ b/quickstep/tests/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactoryTest.kt @@ -0,0 +1,148 @@ +package com.android.launcher3.taskbar.navbutton + +import android.content.res.Resources +import android.view.View +import android.view.ViewGroup +import android.widget.FrameLayout +import android.widget.ImageView +import android.widget.LinearLayout +import androidx.test.runner.AndroidJUnit4 +import com.android.launcher3.DeviceProfile +import com.android.launcher3.taskbar.TaskbarManager +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import com.android.launcher3.R +import org.junit.Assume.assumeTrue +import org.mockito.Mockito.`when` as whenever +import org.mockito.MockitoAnnotations +import java.lang.IllegalStateException + +@RunWith(AndroidJUnit4::class) +class NavButtonLayoutFactoryTest { + + @Mock + lateinit var mockDeviceProfile: DeviceProfile + @Mock + lateinit var mockParentButtonContainer: FrameLayout + @Mock + lateinit var mockNavLayout: LinearLayout + @Mock + lateinit var mockStartContextualLayout: ViewGroup + @Mock + lateinit var mockEndContextualLayout: ViewGroup + @Mock + lateinit var mockResources: Resources + @Mock + lateinit var mockBackButton: ImageView + @Mock + lateinit var mockRecentsButton: ImageView + @Mock + lateinit var mockHomeButton: ImageView + + @Before + fun setup() { + MockitoAnnotations.initMocks(this) + + // Init end nav buttons + whenever(mockNavLayout.childCount).thenReturn(3) + whenever(mockNavLayout.findViewById(R.id.back)).thenReturn(mockBackButton) + whenever(mockNavLayout.findViewById(R.id.home)).thenReturn(mockHomeButton) + whenever(mockNavLayout.findViewById(R.id.recent_apps)).thenReturn(mockRecentsButton) + + // Init top level layout + whenever(mockParentButtonContainer.findViewById(R.id.end_nav_buttons)) + .thenReturn(mockNavLayout) + whenever(mockParentButtonContainer.findViewById(R.id.end_contextual_buttons)) + .thenReturn(mockEndContextualLayout) + whenever(mockParentButtonContainer.findViewById(R.id.start_contextual_buttons)) + .thenReturn(mockStartContextualLayout) + } + + @Test + fun getKidsLayoutter() { + assumeTrue(TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW) + mockDeviceProfile.isTaskbarPresent = true + val layoutter: NavButtonLayoutFactory.NavButtonLayoutter = + getLayoutter(isKidsMode = true, isInSetup = false, isThreeButtonNav = false, + phoneMode = false) + assert(layoutter is KidsNavLayoutter) + } + + @Test + fun getSetupLayoutter() { + assumeTrue(TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW) + mockDeviceProfile.isTaskbarPresent = true + val layoutter: NavButtonLayoutFactory.NavButtonLayoutter = + getLayoutter(isKidsMode = false, isInSetup = true, isThreeButtonNav = false, + phoneMode = false) + assert(layoutter is SetupNavLayoutter) + } + + @Test + fun getTaskbarNavLayoutter() { + assumeTrue(TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW) + mockDeviceProfile.isTaskbarPresent = true + val layoutter: NavButtonLayoutFactory.NavButtonLayoutter = + getLayoutter(isKidsMode = false, isInSetup = false, isThreeButtonNav = false, + phoneMode = false) + assert(layoutter is TaskbarNavLayoutter) + } + + @Test(expected = IllegalStateException::class) + fun noValidLayoutForLargeScreenTaskbarNotPresent() { + assumeTrue(TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW) + mockDeviceProfile.isTaskbarPresent = false + getLayoutter(isKidsMode = false, isInSetup = false, isThreeButtonNav = false, + phoneMode = false) + } + + @Test + fun getTaskbarPortraitLayoutter() { + assumeTrue(TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW) + mockDeviceProfile.isTaskbarPresent = false + val layoutter: NavButtonLayoutFactory.NavButtonLayoutter = + getLayoutter(isKidsMode = false, isInSetup = false, isThreeButtonNav = true, + phoneMode = true) + assert(layoutter is PhonePortraitNavLayoutter) + } + + @Test + fun getTaskbarLandscapeLayoutter() { + assumeTrue(TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW) + mockDeviceProfile.isTaskbarPresent = false + setDeviceProfileLandscape() + val layoutter: NavButtonLayoutFactory.NavButtonLayoutter = + getLayoutter(isKidsMode = false, isInSetup = false, isThreeButtonNav = true, + phoneMode = true) + assert(layoutter is PhoneLandscapeNavLayoutter) + } + + @Test(expected = IllegalStateException::class) + fun noValidLayoutForPhoneGestureNav() { + assumeTrue(TaskbarManager.FLAG_HIDE_NAVBAR_WINDOW) + mockDeviceProfile.isTaskbarPresent = false + getLayoutter(isKidsMode = false, isInSetup = false, isThreeButtonNav = false, + phoneMode = true) + } + + private fun setDeviceProfileLandscape() { + // Use reflection to modify landscape field + val landscapeField = mockDeviceProfile.javaClass.getDeclaredField("isLandscape") + landscapeField.isAccessible = true + landscapeField.set(mockDeviceProfile, true) + } + + private fun getLayoutter(isKidsMode: Boolean, isInSetup: Boolean, + isThreeButtonNav: Boolean, phoneMode: Boolean): + NavButtonLayoutFactory.NavButtonLayoutter { + return NavButtonLayoutFactory.getUiLayoutter( + deviceProfile = mockDeviceProfile, + navButtonsView = mockParentButtonContainer, + resources = mockResources, + isKidsMode = isKidsMode, isInSetup = isInSetup, + isThreeButtonNav = isThreeButtonNav, phoneMode = phoneMode + ) + } +} \ No newline at end of file diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 47584e2baf..a9ba07d2b1 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -368,6 +368,7 @@ 0dp 0dp 0dp + 0dp 0dp 0dp 0dp diff --git a/src/com/android/launcher3/util/DimensionUtils.kt b/src/com/android/launcher3/util/DimensionUtils.kt new file mode 100644 index 0000000000..758b3a962f --- /dev/null +++ b/src/com/android/launcher3/util/DimensionUtils.kt @@ -0,0 +1,60 @@ +/* + * Copyright (C) 2022 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.launcher3.util + +import android.content.res.Resources +import android.graphics.Point +import android.view.ViewGroup +import com.android.launcher3.DeviceProfile +import com.android.launcher3.R + +object DimensionUtils { + /** + * Point where x is width, and y is height of taskbar based on provided [deviceProfile] + * x or y could also be -1 to indicate there is no dimension specified + */ + @JvmStatic + fun getTaskbarPhoneDimensions(deviceProfile: DeviceProfile, res: Resources, + isPhoneMode: Boolean): Point { + val p = Point() + // Taskbar for large screen + if (!isPhoneMode) { + p.x = ViewGroup.LayoutParams.MATCH_PARENT + p.y = deviceProfile.taskbarSize + return p + } + + // Taskbar on phone using gesture nav, it will always be stashed + if (deviceProfile.isGestureMode) { + p.x = ViewGroup.LayoutParams.MATCH_PARENT + p.y = res.getDimensionPixelSize(R.dimen.taskbar_stashed_size) + return p + } + + // Taskbar on phone, portrait + if (!deviceProfile.isLandscape) { + p.x = ViewGroup.LayoutParams.MATCH_PARENT + p.y = res.getDimensionPixelSize(R.dimen.taskbar_size) + return p + } + + // Taskbar on phone, landscape + p.x = res.getDimensionPixelSize(R.dimen.taskbar_size) + p.y = ViewGroup.LayoutParams.MATCH_PARENT + return p + } +} \ No newline at end of file From c17c3171c5977fd4da814d3e7e2e03855ae8b91b Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Mon, 3 Oct 2022 20:49:32 -0700 Subject: [PATCH 079/429] More robust fix to BubbleTextViews appearing on multiple rows. This is the more comprehensive version of ag/20119299. Improvements compared to that change: - Icons on the same row animate together (as opposed to the first icon on the row animating separately) - Multiple rows of predicted apps are supported (any beyond the first row are animated like everything else) --- Original description --- Example BubbleTextView: WhatsApp/Gmail conversation shortcuts. The issue was we were treating these the same as the top app row, but we were assuming there would only be 1 such row, which messed up the measurement logic. At the same time, the logic specific to that app row was redundant with the new logic for rows containing mulitple items. This solution does 2 things: - Removes special logic for app row (it now uses the same logic as other rows with multiple items, i.e. uses the span index to determine the height of the row) - Keeps the scale/alpha at 1 for the first row of app icons. This currently only applies to predicted apps, but if there were multiple app rows in the future, the additional rows would animate the same way as other rows (see demo videos for an example with double predicted apps in 0 state). In the conversation case, the other icons are deep shortcuts. The result is the app row still does what it did before (stays fixed at full size/opacity), and deep shortcuts like the ones used for WhatsApp and Gmail animate like other rows of items, such as screenshots. Demo videos: https://drive.google.com/drive/folders/1GPQNIwMfuj9ZdAbRrh-K75C5xJYT4Gzo?resourcekey=0-ojO6VGetEBy5YTq4roFmlw&usp=sharing Test: Manual with and without inject_web_top (which moves app row) for WhatsApp and Gmail with AiAi fishfood. Bug: 239927522 Change-Id: Ib2ca97b93798cb57eb55545eeba8be9322484f7d --- .../allapps/SearchTransitionController.java | 105 ++++++++++-------- 1 file changed, 58 insertions(+), 47 deletions(-) diff --git a/src/com/android/launcher3/allapps/SearchTransitionController.java b/src/com/android/launcher3/allapps/SearchTransitionController.java index bde4fa6e37..9c3dab4ec3 100644 --- a/src/com/android/launcher3/allapps/SearchTransitionController.java +++ b/src/com/android/launcher3/allapps/SearchTransitionController.java @@ -170,12 +170,13 @@ public class SearchTransitionController { /** * Updates the children views of SearchRecyclerView based on the current animation progress. * - * @return the total height of animating views (excluding any app icons). + * @return the total height of animating views (excluding at most one row of app icons). */ private int updateSearchRecyclerViewProgress() { int numSearchResultsAnimated = 0; int totalHeight = 0; int appRowHeight = 0; + boolean appRowComplete = false; Integer top = null; SearchRecyclerView searchRecyclerView = getSearchRecyclerView(); @@ -189,67 +190,72 @@ public class SearchTransitionController { top = searchResultView.getTop(); } - if (searchResultView instanceof BubbleTextView - && searchResultView.getTag() instanceof ItemInfo - && ((ItemInfo) searchResultView.getTag()).itemType == ITEM_TYPE_APPLICATION) { - // The first app icon will set appRowHeight, which will also contribute to - // totalHeight. Additional app icons should remove the appRowHeight to remain in - // the same row as the first app. - searchResultView.setY(top + totalHeight - appRowHeight); - if (appRowHeight == 0) { - appRowHeight = searchResultView.getHeight(); - totalHeight += appRowHeight; - } - // Don't scale/fade app row. - searchResultView.setScaleY(1); - searchResultView.setAlpha(1); - continue; - } - - // Adjust content alpha based on start progress and stagger. - float startContentFadeProgress = Math.max(0, - TOP_CONTENT_FADE_PROGRESS_START - CONTENT_STAGGER * numSearchResultsAnimated); - float endContentFadeProgress = Math.min(1, - startContentFadeProgress + CONTENT_FADE_PROGRESS_DURATION); - searchResultView.setAlpha(1 - clampToProgress(mSearchToAzProgress, - startContentFadeProgress, endContentFadeProgress)); - - // Adjust background (or decorator) alpha based on start progress and stagger. - float startBackgroundFadeProgress = Math.max(0, - TOP_BACKGROUND_FADE_PROGRESS_START - - CONTENT_STAGGER * numSearchResultsAnimated); - float endBackgroundFadeProgress = Math.min(1, - startBackgroundFadeProgress + BACKGROUND_FADE_PROGRESS_DURATION); - float backgroundAlpha = 1 - clampToProgress(mSearchToAzProgress, - startBackgroundFadeProgress, endBackgroundFadeProgress); int adapterPosition = searchRecyclerView.getChildAdapterPosition(searchResultView); - boolean decoratorFilled = - adapterPosition != NO_POSITION - && searchRecyclerView.getApps().getAdapterItems().get(adapterPosition) - .setDecorationFillAlpha((int) (255 * backgroundAlpha)); - if (!decoratorFilled) { - // Try to adjust background alpha instead (e.g. for Search Edu card). - Drawable background = searchResultView.getBackground(); - if (background != null) { - background.setAlpha((int) (255 * backgroundAlpha)); + int spanIndex = getSpanIndex(searchRecyclerView, adapterPosition); + appRowComplete |= appRowHeight > 0 && spanIndex == 0; + // We don't animate the first (currently only) app row we see, as that is assumed to be + // predicted/prefix-matched apps. + boolean shouldAnimate = !isAppIcon(searchResultView) || appRowComplete; + + float contentAlpha = 1f; + float backgroundAlpha = 1f; + if (shouldAnimate) { + if (spanIndex > 0) { + // Animate this item with the previous item on the same row. + numSearchResultsAnimated--; } + + // Adjust content alpha based on start progress and stagger. + float startContentFadeProgress = Math.max(0, + TOP_CONTENT_FADE_PROGRESS_START + - CONTENT_STAGGER * numSearchResultsAnimated); + float endContentFadeProgress = Math.min(1, + startContentFadeProgress + CONTENT_FADE_PROGRESS_DURATION); + contentAlpha = 1 - clampToProgress(mSearchToAzProgress, + startContentFadeProgress, endContentFadeProgress); + + // Adjust background (or decorator) alpha based on start progress and stagger. + float startBackgroundFadeProgress = Math.max(0, + TOP_BACKGROUND_FADE_PROGRESS_START + - CONTENT_STAGGER * numSearchResultsAnimated); + float endBackgroundFadeProgress = Math.min(1, + startBackgroundFadeProgress + BACKGROUND_FADE_PROGRESS_DURATION); + backgroundAlpha = 1 - clampToProgress(mSearchToAzProgress, + startBackgroundFadeProgress, endBackgroundFadeProgress); + + numSearchResultsAnimated++; + } + searchResultView.setAlpha(contentAlpha); + // Apply background alpha to decorator if possible. + if (adapterPosition != NO_POSITION) { + searchRecyclerView.getApps().getAdapterItems() + .get(adapterPosition).setDecorationFillAlpha((int) (255 * backgroundAlpha)); + } + // Apply background alpha to view's background (e.g. for Search Edu card). + Drawable background = searchResultView.getBackground(); + if (background != null) { + background.setAlpha((int) (255 * backgroundAlpha)); } - float scaleY = 1 - mSearchToAzProgress; + float scaleY = 1; + if (shouldAnimate) { + scaleY = 1 - mSearchToAzProgress; + } int scaledHeight = (int) (searchResultView.getHeight() * scaleY); searchResultView.setScaleY(scaleY); // For rows with multiple elements, only count the height once and translate elements to // the same y position. int y = top + totalHeight; - int spanIndex = getSpanIndex(searchRecyclerView, adapterPosition); if (spanIndex > 0) { // Continuation of an existing row; move this item into the row. y -= scaledHeight; } else { - // Start of a new row contributes to total height and animation stagger. - numSearchResultsAnimated++; + // Start of a new row contributes to total height. totalHeight += scaledHeight; + if (!shouldAnimate) { + appRowHeight = scaledHeight; + } } searchResultView.setY(y); } @@ -275,6 +281,11 @@ public class SearchTransitionController { return adapter.getSpanIndex(adapterPosition); } + private boolean isAppIcon(View item) { + return item instanceof BubbleTextView && item.getTag() instanceof ItemInfo + && ((ItemInfo) item.getTag()).itemType == ITEM_TYPE_APPLICATION; + } + /** Called just before a child is attached to the SearchRecyclerView. */ private void onSearchChildAttached(View child) { // Avoid allocating hardware layers for alpha changes. From 9345681737bb7c71eefc748f1377492f34562c5a Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Wed, 5 Oct 2022 17:58:45 -0700 Subject: [PATCH 080/429] Fixes ITEM_TYPE_SEARCH_ACTION to have a unique value. It previously was the same as ITEM_TYPE_TASK. Test: N/A Bug: 254138853 Bug: 254140269 Change-Id: I6f09818e3c5c05cbcbb451147cf310d59c7064e0 --- src/com/android/launcher3/LauncherSettings.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/com/android/launcher3/LauncherSettings.java b/src/com/android/launcher3/LauncherSettings.java index 66195f3a1d..4c8f2d9378 100644 --- a/src/com/android/launcher3/LauncherSettings.java +++ b/src/com/android/launcher3/LauncherSettings.java @@ -94,15 +94,11 @@ public class LauncherSettings { */ public static final int ITEM_TYPE_DEEP_SHORTCUT = 6; - /** - * The favroite is a search action - */ - public static final int ITEM_TYPE_SEARCH_ACTION = 7; + // *** Below enum values are used for metrics purpose but not used in Favorites DB *** /** * Type of the item is recents task. - * TODO(hyunyoungs): move constants not related to Favorites DB to a better location. */ public static final int ITEM_TYPE_TASK = 7; @@ -111,6 +107,11 @@ public class LauncherSettings { */ public static final int ITEM_TYPE_QSB = 8; + /** + * The favorite is a search action + */ + public static final int ITEM_TYPE_SEARCH_ACTION = 9; + /** * The icon package name in Intent.ShortcutIconResource *

Type: TEXT

From 392f8878cd1c6cdc042a0cc2546579dbd7b4e160 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Mon, 17 Oct 2022 17:52:16 -0700 Subject: [PATCH 081/429] Prevent restoring split selection state for fallback overview * Add flag to explicitly not restore OVERVIEW_SPLIT_SELECT * FallbackRecentsView then resets state in RecentsView if our endState is ever not split selection Fixes: 253178217 Test: Used launcher developer option to force use separate recents activity. Tested w/ 3 button nav + gesture. Change-Id: I26c9994bf853e9a005300a02aa143991958fc461 --- .../com/android/quickstep/fallback/FallbackRecentsView.java | 3 +++ quickstep/src/com/android/quickstep/fallback/RecentsState.java | 3 ++- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java index e32aaee532..67e0bea522 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsView.java @@ -243,6 +243,9 @@ public class FallbackRecentsView extends RecentsView diff --git a/quickstep/src/com/android/quickstep/fallback/RecentsState.java b/quickstep/src/com/android/quickstep/fallback/RecentsState.java index 223eba5b95..8b5f091e11 100644 --- a/quickstep/src/com/android/quickstep/fallback/RecentsState.java +++ b/quickstep/src/com/android/quickstep/fallback/RecentsState.java @@ -55,7 +55,8 @@ public class RecentsState implements BaseState { public static final RecentsState HOME = new RecentsState(3, 0); public static final RecentsState BG_LAUNCHER = new LauncherState(4, 0); public static final RecentsState OVERVIEW_SPLIT_SELECT = new RecentsState(5, - FLAG_SHOW_AS_GRID | FLAG_SCRIM | FLAG_OVERVIEW_UI | FLAG_CLOSE_POPUPS); + FLAG_SHOW_AS_GRID | FLAG_SCRIM | FLAG_OVERVIEW_UI | FLAG_CLOSE_POPUPS + | FLAG_DISABLE_RESTORE); public final int ordinal; private final int mFlags; From 2c54bbfdfc1d4a4f9aa6e02e16fb11865934c451 Mon Sep 17 00:00:00 2001 From: Thales Lima Date: Tue, 12 Jul 2022 15:45:10 +0000 Subject: [PATCH 082/429] Convert make to bp Fix: 229946262 Test: build all launchers and run atest Change-Id: Ie9b66ba0d83aa0c3c476dd30853ef52279c9619e (cherry picked from commit 42f15f9b814e0cc32ba19aa675d0dfc0219e32d2) Merged-In: Ie9b66ba0d83aa0c3c476dd30853ef52279c9619e --- Android.bp | 132 +++++++++++++++++++++---------------------- quickstep/Android.bp | 5 ++ 2 files changed, 68 insertions(+), 69 deletions(-) diff --git a/Android.bp b/Android.bp index 330c32ec89..6267e9fa27 100644 --- a/Android.bp +++ b/Android.bp @@ -19,6 +19,54 @@ package { min_launcher3_sdk_version = "26" +// Common source files used to build launcher (java and kotlin) +// All sources are split so they can be reused in many other libraries/apps in other folders +filegroup { + name: "launcher-src", + srcs: [ "src/**/*.java", "src/**/*.kt" ], +} + +filegroup { + name: "launcher-quickstep-src", + srcs: [ "quickstep/src/**/*.java", "quickstep/src/**/*.kt" ], +} + +filegroup { + name: "launcher-go-src", + srcs: [ "go/src/**/*.java", "go/src/**/*.kt" ], +} + +filegroup { + name: "launcher-go-quickstep-src", + srcs: [ "go/quickstep/src/**/*.java", "go/quickstep/src/**/*.kt" ], +} + +filegroup { + name: "launcher-src_shortcuts_overrides", + srcs: [ "src_shortcuts_overrides/**/*.java", "src_shortcuts_overrides/**/*.kt" ], +} + +filegroup { + name: "launcher-src_ui_overrides", + srcs: [ "src_ui_overrides/**/*.java", "src_ui_overrides/**/*.kt" ], +} + +filegroup { + name: "launcher-ext_tests", + srcs: [ "ext_tests/**/*.java", "ext_tests/**/*.kt" ], +} + +filegroup { + name: "launcher-quickstep-ext_tests", + srcs: [ "quickstep/ext_tests/**/*.java", "quickstep/ext_tests/**/*.kt" ], +} + +// Proguard files for Launcher3 +filegroup { + name: "launcher-proguard-rules", + srcs: ["proguard.flags"], +} + android_library { name: "launcher-aosp-tapl", libs: [ @@ -139,14 +187,10 @@ android_app { "Launcher3CommonDepsLib", ], srcs: [ - "src/**/*.java", - "src/**/*.kt", - "src_shortcuts_overrides/**/*.java", - "src_shortcuts_overrides/**/*.kt", - "src_ui_overrides/**/*.java", - "src_ui_overrides/**/*.kt", - "ext_tests/src/**/*.java", - "ext_tests/src/**/*.kt", + ":launcher-src", + ":launcher-src_shortcuts_overrides", + ":launcher-src_ui_overrides", + ":launcher-ext_tests", ], resource_dirs: [ "ext_tests/res", @@ -202,61 +246,14 @@ android_library { } -// Source code used for test helpers -filegroup { - name: "launcher-src-ext-tests", - srcs: [ - "ext_tests/src/**/*.java", - "ext_tests/src/**/*.kt", - "quickstep/ext_tests/src/**/*.java", - "quickstep/ext_tests/src/**/*.kt", - ], -} - -// Common source files used to build launcher -filegroup { - name: "launcher-src-no-build-config", - srcs: [ - "src/**/*.java", - "src/**/*.kt", - "src_shortcuts_overrides/**/*.java", - "src_shortcuts_overrides/**/*.kt", - "quickstep/src/**/*.java", - "quickstep/src/**/*.kt", - ], -} - -// Common source files used to build go launcher except go/src files -filegroup { - name: "launcher-go-src-no-build-config", - srcs: [ - "src/**/*.java", - "src/**/*.kt", - "quickstep/src/**/*.java", - "quickstep/src/**/*.kt", - "go/quickstep/src/**/*.java", - "go/quickstep/src/**/*.kt", - ], -} - -// Proguard files for Launcher3 -filegroup { - name: "launcher-proguard-rules", - srcs: ["proguard.flags"], -} - // Library with all the dependencies for building Launcher Go android_library { name: "LauncherGoResLib", srcs: [ - "src/**/*.java", - "src/**/*.kt", - "quickstep/src/**/*.java", - "quickstep/src/**/*.kt", - "go/src/**/*.java", - "go/src/**/*.kt", - "go/quickstep/src/**/*.java", - "go/quickstep/src/**/*.kt", + ":launcher-src", + ":launcher-quickstep-src", + ":launcher-go-src", + ":launcher-go-quickstep-src", ], resource_dirs: [ "go/res", @@ -287,7 +284,9 @@ android_library { android_library { name: "Launcher3QuickStepLib", srcs: [ - ":launcher-src-no-build-config", + ":launcher-src", + ":launcher-quickstep-src", + ":launcher-src_shortcuts_overrides", ], resource_dirs: [], libs: [ @@ -319,9 +318,9 @@ android_app { static_libs: ["Launcher3CommonDepsLib"], srcs: [ - "src/**/*.java", - "src_ui_overrides/**/*.java", - "go/src/**/*.java", + ":launcher-src", + ":launcher-go-src", + ":launcher-src_ui_overrides", ], resource_dirs: ["go/res"], @@ -405,12 +404,7 @@ android_app { min_sdk_version: "current", target_sdk_version: "current", - srcs: [ - "src/**/*.java", - "quickstep/src/**/*.java", - "go/src/**/*.java", - "go/quickstep/src/**/*.java", - ], + srcs: [ ], resource_dirs: [ "go/quickstep/res", diff --git a/quickstep/Android.bp b/quickstep/Android.bp index f739f8140c..7292c4495b 100644 --- a/quickstep/Android.bp +++ b/quickstep/Android.bp @@ -17,6 +17,11 @@ package { default_applicable_licenses: ["Android-Apache-2.0"], } +filegroup { + name: "launcher3-quickstep-manifest", + srcs: ["AndroidManifest.xml"], +} + filegroup { name: "launcher3-quickstep-robolectric-src", path: "robolectric_tests", From e9d4044483a7f13b49c46be7855ad4819001c18e Mon Sep 17 00:00:00 2001 From: Thales Lima Date: Fri, 7 Oct 2022 11:29:16 +0000 Subject: [PATCH 083/429] Remove KtR workaround Bug: 229947409 Test: m -j128 Launcher3QuickStep Launcher3QuickStepGo Launcher3 Launcher3Go NexusLauncherRelease NexusLauncherDebug SearchLauncherQuickStep SearchLauncher LauncherGoGoogle Change-Id: I5792cc6b30dfa856747a1576ef3cb195952c25c7 (cherry picked from commit 51e164688ec6b9b6375fe03fb1f09ae59f817776) Merged-In: I5792cc6b30dfa856747a1576ef3cb195952c25c7 --- .../taskbar/TaskbarInsetsController.kt | 5 +-- quickstep/src/com/android/quickstep/KtR.java | 41 ------------------- .../quickstep/views/TaskMenuViewWithArrow.kt | 15 ++++--- 3 files changed, 9 insertions(+), 52 deletions(-) delete mode 100644 quickstep/src/com/android/quickstep/KtR.java diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt index bbbc1e6b80..45e2b77f76 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt @@ -31,9 +31,9 @@ import android.view.WindowManager.LayoutParams.TYPE_VOICE_INTERACTION import com.android.launcher3.AbstractFloatingView import com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_ALL_APPS import com.android.launcher3.DeviceProfile +import com.android.launcher3.R import com.android.launcher3.anim.AlphaUpdateListener import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController -import com.android.quickstep.KtR import java.io.PrintWriter /** @@ -42,8 +42,7 @@ import java.io.PrintWriter class TaskbarInsetsController(val context: TaskbarActivityContext): LoggableTaskbarController { /** The bottom insets taskbar provides to the IME when IME is visible. */ - val taskbarHeightForIme: Int = context.resources.getDimensionPixelSize( - KtR.dimen.taskbar_ime_size) + val taskbarHeightForIme: Int = context.resources.getDimensionPixelSize(R.dimen.taskbar_ime_size) private val touchableRegion: Region = Region() private val deviceProfileChangeListener = { _: DeviceProfile -> onTaskbarWindowHeightOrInsetsChanged() diff --git a/quickstep/src/com/android/quickstep/KtR.java b/quickstep/src/com/android/quickstep/KtR.java deleted file mode 100644 index 758c6e08ef..0000000000 --- a/quickstep/src/com/android/quickstep/KtR.java +++ /dev/null @@ -1,41 +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; - -import com.android.launcher3.R; - -/** - * Bridge class to allow using resources in Kotlin. - *
- * TODO(b/204069723) Can't use resources directly in Kotlin - */ -public class KtR { - public static final class id { - public static int menu_option_layout = R.id.menu_option_layout; - } - - public static final class dimen { - public static int task_menu_spacing = R.dimen.task_menu_spacing; - public static int task_menu_horizontal_padding = R.dimen.task_menu_horizontal_padding; - public static int taskbar_ime_size = R.dimen.taskbar_ime_size; - } - - public static final class layout { - public static int task_menu_with_arrow = R.layout.task_menu_with_arrow; - public static int task_view_menu_option = R.layout.task_view_menu_option; - } -} diff --git a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt index b586ac37b0..bdc0585f83 100644 --- a/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt +++ b/quickstep/src/com/android/quickstep/views/TaskMenuViewWithArrow.kt @@ -37,7 +37,6 @@ import com.android.launcher3.popup.ArrowPopup import com.android.launcher3.popup.RoundedArrowDrawable import com.android.launcher3.popup.SystemShortcut import com.android.launcher3.util.Themes -import com.android.quickstep.KtR import com.android.quickstep.TaskOverlayFactory import com.android.quickstep.views.TaskView.TaskIdAttributeContainer @@ -53,9 +52,9 @@ class TaskMenuViewWithArrow : ArrowPopup { .fromContext(taskContainer.taskView.context) val taskMenuViewWithArrow = activity.layoutInflater .inflate( - KtR.layout.task_menu_with_arrow, - activity.dragLayer, - false + R.layout.task_menu_with_arrow, + activity.dragLayer, + false ) as TaskMenuViewWithArrow<*> return taskMenuViewWithArrow.populateAndShowForTask(taskContainer, alignSecondRow) @@ -93,7 +92,7 @@ class TaskMenuViewWithArrow : ArrowPopup { private var optionMeasuredHeight = 0 private val arrowHorizontalPadding: Int get() = if (taskView.isFocusedTask) - resources.getDimensionPixelSize(KtR.dimen.task_menu_horizontal_padding) + resources.getDimensionPixelSize(R.dimen.task_menu_horizontal_padding) else 0 @@ -119,7 +118,7 @@ class TaskMenuViewWithArrow : ArrowPopup { override fun onFinishInflate() { super.onFinishInflate() - optionLayout = findViewById(KtR.id.menu_option_layout) + optionLayout = findViewById(R.id.menu_option_layout) } private fun populateAndShowForTask( @@ -170,7 +169,7 @@ class TaskMenuViewWithArrow : ArrowPopup { // Add the spaces between items val divider = ShapeDrawable(RectShape()) divider.paint.color = resources.getColor(android.R.color.transparent) - val dividerSpacing = resources.getDimension(KtR.dimen.task_menu_spacing).toInt() + val dividerSpacing = resources.getDimension(R.dimen.task_menu_spacing).toInt() optionLayout.showDividers = SHOW_DIVIDER_MIDDLE // Set the orientation, which makes the menu show @@ -187,7 +186,7 @@ class TaskMenuViewWithArrow : ArrowPopup { private fun addMenuOption(menuOption: SystemShortcut<*>) { val menuOptionView = mActivityContext.layoutInflater.inflate( - KtR.layout.task_view_menu_option, this, false + R.layout.task_view_menu_option, this, false ) as LinearLayout menuOption.setIconAndLabelFor( menuOptionView.findViewById(R.id.icon), From 950a10738b801f7ce6463027fdde9000e6aab49a Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Fri, 16 Sep 2022 14:53:11 +0800 Subject: [PATCH 084/429] Fix STATE_DEPTH stuck at 1 after setting wallpaper - Made BaseDepthController.setDepth/mDepth private, all get/set should be done through STATE_DEPTH or WIDGET_DEPTH - Generified ClampedDepthProperty into Utilities.ClampedProperty to apply on STATE_DEPTH Bug: 240580498 Test: Go to walppaper&style, set new wallpaper, then go to widget picker, wallpaper depth should transition smoothly Change-Id: I53cdedf970fd7ffba6a952c4edf4b34251b01f07 --- .../statehandlers/DepthController.java | 50 ++----------------- .../uioverrides/QuickstepLauncher.java | 9 ++-- .../quickstep/LauncherActivityInterface.java | 5 +- .../quickstep/util/BaseDepthController.java | 4 +- .../android/launcher3/LauncherAnimUtils.java | 28 +++++++++++ .../launcher3/util/MultiPropertyFactory.java | 9 ++-- 6 files changed, 47 insertions(+), 58 deletions(-) diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java index e3fd3f9a06..2a78bdf197 100644 --- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java +++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java @@ -23,7 +23,6 @@ import static com.android.launcher3.states.StateAnimationConfig.SKIP_DEPTH_CONTR import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.animation.ObjectAnimator; -import android.util.FloatProperty; import android.view.CrossWindowBlurListeners; import android.view.View; import android.view.ViewRootImpl; @@ -32,7 +31,6 @@ import android.view.ViewTreeObserver; import com.android.launcher3.BaseActivity; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; -import com.android.launcher3.Utilities; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.states.StateAnimationConfig; @@ -47,43 +45,12 @@ import java.util.function.Consumer; public class DepthController extends BaseDepthController implements StateHandler, BaseActivity.MultiWindowModeChangedListener { - /** - * A property that updates the background blur within a given range of values (ie. even if the - * animator goes beyond 0..1, the interpolated value will still be bounded). - */ - public static class ClampedDepthProperty extends FloatProperty { - private final float mMinValue; - private final float mMaxValue; - - public ClampedDepthProperty(float minValue, float maxValue) { - super("depthClamped"); - mMinValue = minValue; - mMaxValue = maxValue; - } - - @Override - public void setValue(DepthController depthController, float depth) { - depthController.setDepth(Utilities.boundToRange(depth, mMinValue, mMaxValue)); - } - - @Override - public Float get(DepthController depthController) { - return depthController.mDepth; - } - } - private final ViewTreeObserver.OnDrawListener mOnDrawListener = this::onLauncherDraw; private final Consumer mCrossWindowBlurListener = this::setCrossWindowBlursEnabled; private final Runnable mOpaquenessListener = this::applyDepthAndBlur; - /** - * If we're launching and app and should not be blurring the screen for performance reasons. - */ - private boolean mBlurDisabledForAppLaunch; - - // Workaround for animating the depth when multiwindow mode changes. private boolean mIgnoreStateChangesDuringMultiWindowAnimation = false; @@ -145,12 +112,8 @@ public class DepthController extends BaseDepthController implements StateHandler return; } - float toDepth = toState.getDepth(mLauncher); - if (Float.compare(mDepth, toDepth) != 0) { - setDepth(toDepth); - } else if (toState == LauncherState.OVERVIEW) { - applyDepthAndBlur(); - } else if (toState == LauncherState.BACKGROUND_APP) { + STATE_DEPTH.set(this, toState.getDepth(mLauncher)); + if (toState == LauncherState.BACKGROUND_APP) { mLauncher.getDragLayer().getViewTreeObserver().addOnDrawListener(mOnDrawListener); } } @@ -164,10 +127,7 @@ public class DepthController extends BaseDepthController implements StateHandler } float toDepth = toState.getDepth(mLauncher); - if (Float.compare(mDepth, toDepth) != 0) { - animation.setFloat(this, STATE_DEPTH, toDepth, - config.getInterpolator(ANIM_DEPTH, LINEAR)); - } + animation.setFloat(this, STATE_DEPTH, toDepth, config.getInterpolator(ANIM_DEPTH, LINEAR)); } @Override @@ -198,9 +158,9 @@ public class DepthController extends BaseDepthController implements StateHandler writer.println(prefix + "\tmMaxBlurRadius=" + mMaxBlurRadius); writer.println(prefix + "\tmCrossWindowBlursEnabled=" + mCrossWindowBlursEnabled); writer.println(prefix + "\tmSurface=" + mSurface); - writer.println(prefix + "\tmDepth=" + mDepth); + writer.println(prefix + "\tmStateDepth=" + STATE_DEPTH.get(this)); + writer.println(prefix + "\tmWidgetDepth=" + WIDGET_DEPTH.get(this)); writer.println(prefix + "\tmCurrentBlur=" + mCurrentBlur); - writer.println(prefix + "\tmBlurDisabledForAppLaunch=" + mBlurDisabledForAppLaunch); writer.println(prefix + "\tmInEarlyWakeUp=" + mInEarlyWakeUp); writer.println(prefix + "\tmIgnoreStateChangesDuringMultiWindowAnimation=" + mIgnoreStateChangesDuringMultiWindowAnimation); diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index ee9845ba78..3203f44ce2 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -186,6 +186,8 @@ public class QuickstepLauncher extends Launcher { private SafeCloseable mViewCapture; + private boolean mEnableWidgetDepth; + @Override protected void setupViews() { super.setupViews(); @@ -206,6 +208,9 @@ public class QuickstepLauncher extends Launcher { mTISBindHelper = new TISBindHelper(this, this::onTISConnected); mDepthController = new DepthController(this); mHotseatPredictionController = new HotseatPredictionController(this); + + mEnableWidgetDepth = ENABLE_WIDGET_PICKER_DEPTH.get() + && SystemProperties.getBoolean("ro.launcher.depth.widget", true); } @Override @@ -587,9 +592,7 @@ public class QuickstepLauncher extends Launcher { public void onWidgetsTransition(float progress) { super.onWidgetsTransition(progress); onTaskbarInAppDisplayProgressUpdate(progress, WIDGETS_PAGE_PROGRESS_INDEX); - // Change of wallpaper depth in widget picker is disabled for tests as it causes flakiness - // on very slow cuttlefish devices. - if (ENABLE_WIDGET_PICKER_DEPTH.get() && !Utilities.IS_RUNNING_IN_TEST_HARNESS) { + if (mEnableWidgetDepth) { WIDGET_DEPTH.set(getDepthController(), Utilities.mapToRange(progress, 0f, 1f, 0f, getDeviceProfile().bottomSheetDepth, EMPHASIZED)); diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java index 1cb17cb815..e9588d60fb 100644 --- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java +++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java @@ -34,11 +34,11 @@ import androidx.annotation.UiThread; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherAnimUtils; import com.android.launcher3.LauncherInitListener; import com.android.launcher3.LauncherState; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.statehandlers.DepthController; -import com.android.launcher3.statehandlers.DepthController.ClampedDepthProperty; import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.taskbar.LauncherTaskbarUIController; import com.android.launcher3.touch.PagedOrientationHandler; @@ -129,7 +129,8 @@ public final class LauncherActivityInterface extends float fromDepthRatio = BACKGROUND_APP.getDepth(activity); float toDepthRatio = OVERVIEW.getDepth(activity); pa.addFloat(getDepthController(), - new ClampedDepthProperty(fromDepthRatio, toDepthRatio), + new LauncherAnimUtils.ClampedProperty<>( + DepthController.STATE_DEPTH, fromDepthRatio, toDepthRatio), fromDepthRatio, toDepthRatio, LINEAR); } }; diff --git a/quickstep/src/com/android/quickstep/util/BaseDepthController.java b/quickstep/src/com/android/quickstep/util/BaseDepthController.java index 29ae9a13ca..064e67515c 100644 --- a/quickstep/src/com/android/quickstep/util/BaseDepthController.java +++ b/quickstep/src/com/android/quickstep/util/BaseDepthController.java @@ -71,7 +71,7 @@ public class BaseDepthController { * Ratio from 0 to 1, where 0 is fully zoomed out, and 1 is zoomed in. * @see android.service.wallpaper.WallpaperService.Engine#onZoomChanged(float) */ - protected float mDepth; + private float mDepth; protected SurfaceControl mSurface; @@ -143,7 +143,7 @@ public class BaseDepthController { } } - protected void setDepth(float depth) { + private void setDepth(float depth) { depth = Utilities.boundToRange(depth, 0, 1); // Round out the depth to dedupe frequent, non-perceptable updates int depthI = (int) (depth * 256); diff --git a/src/com/android/launcher3/LauncherAnimUtils.java b/src/com/android/launcher3/LauncherAnimUtils.java index b858d1a13a..4e80d41402 100644 --- a/src/com/android/launcher3/LauncherAnimUtils.java +++ b/src/com/android/launcher3/LauncherAnimUtils.java @@ -218,4 +218,32 @@ public class LauncherAnimUtils { } }; } + + /** + * A property that updates the specified property within a given range of values (ie. even if + * the animator goes beyond 0..1, the interpolated value will still be bounded). + * @param the specified property + */ + public static class ClampedProperty extends FloatProperty { + private final FloatProperty mProperty; + private final float mMinValue; + private final float mMaxValue; + + public ClampedProperty(FloatProperty property, float minValue, float maxValue) { + super(property.getName() + "Clamped"); + mProperty = property; + mMinValue = minValue; + mMaxValue = maxValue; + } + + @Override + public void setValue(T t, float v) { + mProperty.set(t, Utilities.boundToRange(v, mMinValue, mMaxValue)); + } + + @Override + public Float get(T t) { + return mProperty.get(t); + } + } } diff --git a/src/com/android/launcher3/util/MultiPropertyFactory.java b/src/com/android/launcher3/util/MultiPropertyFactory.java index e7a7785323..43daf087ee 100644 --- a/src/com/android/launcher3/util/MultiPropertyFactory.java +++ b/src/com/android/launcher3/util/MultiPropertyFactory.java @@ -107,12 +107,9 @@ public class MultiPropertyFactory { @Override public Float get(T object) { - // The scale of the view should match mLastAggregatedValue. Still, if it has been - // changed without using this property, it can differ. As this get method is usually - // used to set the starting point on an animation, this would result in some jumps - // when the view scale is different than the last aggregated value. To stay on the - // safe side, let's return the real view scale. - return mProperty.get(object); + // Callers of MultiProperty should only care about the sub-property that it sets. If + // the overall value is needed, mProperty.get should be called directly. + return mValue; } @Override From 1852459977aa220a07d4663310dbf03df273f02f Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Tue, 18 Oct 2022 17:06:15 +0100 Subject: [PATCH 085/429] Enable wallpaper blur for widget picker Fix: 240580498 Test: Go to walppaper&style, set new wallpaper, then go to widget picker, wallpaper depth should transition smoothly Change-Id: Iadabd0e755f861fb1e8967209dd647faed6e4916 --- src/com/android/launcher3/config/FeatureFlags.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 3a530affad..211ec77f4b 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -283,7 +283,7 @@ public final class FeatureFlags { "In foldables, when reordering the icons and widgets, is now going to use both sides"); public static final BooleanFlag ENABLE_WIDGET_PICKER_DEPTH = new DeviceFlag( - "ENABLE_WIDGET_PICKER_DEPTH", false, "Enable changing depth in widget picker."); + "ENABLE_WIDGET_PICKER_DEPTH", true, "Enable changing depth in widget picker."); public static final BooleanFlag SHOW_DELIGHTFUL_PAGINATION_FOLDER = new DeviceFlag( "SHOW_DELIGHTFUL_PAGINATION_FOLDER", false, From dd11f089ccfe23e4f74eca83cd3449dd7e299fe7 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Mon, 17 Oct 2022 22:48:03 +0000 Subject: [PATCH 086/429] Revert "Revert "Using Transaction directly instead of building s..." Revert^2 "Removing unused surface transaction wrappers" 2460910c8c454bc2d3c9ae35bd32eeb590851788 Bug: 221961069 Test: Presubmit Change-Id: I0028c9fe0de6fde6a77de84e4858fda14cd578dd --- .../launcher3/QuickstepTransitionManager.java | 124 +++++++------- .../android/quickstep/AbsSwipeUpHandler.java | 16 +- .../quickstep/FallbackSwipeHandler.java | 14 +- .../LauncherBackAnimationController.java | 14 +- .../quickstep/SwipeUpAnimationLogic.java | 12 +- .../com/android/quickstep/TaskViewUtils.java | 22 ++- .../DeviceLockedInputConsumer.java | 6 +- .../SwipeUpGestureTutorialController.java | 31 ++-- .../util/RecordingSurfaceTransaction.java | 28 +++ .../util/RemoteFadeOutAnimationListener.java | 4 +- .../quickstep/util/SurfaceTransaction.java | 161 ++++++++++++++++++ .../util/SurfaceTransactionApplier.java | 13 +- .../quickstep/util/TaskViewSimulator.java | 12 +- .../quickstep/util/TransformParams.java | 43 ++--- .../android/quickstep/views/RecentsView.java | 11 +- .../WidgetsPredicationUpdateTaskTest.java | 2 - .../quickstep/util/TaskViewSimulatorTest.java | 19 ++- 17 files changed, 349 insertions(+), 183 deletions(-) create mode 100644 quickstep/src/com/android/quickstep/util/RecordingSurfaceTransaction.java create mode 100644 quickstep/src/com/android/quickstep/util/SurfaceTransaction.java diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 9a1ed4d56d..03caf907f6 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -122,6 +122,8 @@ import com.android.quickstep.util.MultiValueUpdateListener; import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.RemoteAnimationProvider; import com.android.quickstep.util.StaggeredWorkspaceAnim; +import com.android.quickstep.util.SurfaceTransaction; +import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties; import com.android.quickstep.util.SurfaceTransactionApplier; import com.android.quickstep.util.WorkspaceRevealAnim; import com.android.quickstep.views.FloatingWidgetView; @@ -134,7 +136,6 @@ import com.android.systemui.shared.system.RemoteAnimationDefinitionCompat; import com.android.systemui.shared.system.RemoteAnimationRunnerCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.RemoteTransitionCompat; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; import com.android.wm.shell.startingsurface.IStartingWindowListener; import java.util.ArrayList; @@ -813,10 +814,11 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener return; } - ArrayList params = new ArrayList<>(); + SurfaceTransaction transaction = new SurfaceTransaction(); + for (int i = appTargets.length - 1; i >= 0; i--) { RemoteAnimationTargetCompat target = appTargets[i]; - SurfaceParams.Builder builder = new SurfaceParams.Builder(target.leash); + SurfaceProperties builder = transaction.forSurface(target.leash); if (target.mode == MODE_OPENING) { matrix.setScale(scale, scale); @@ -837,11 +839,11 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener floatingView.update(mIconAlpha.value, 255, floatingIconBounds, percent, 0f, mWindowRadius.value * scale, true /* isOpening */); - builder.withMatrix(matrix) - .withWindowCrop(crop) - .withAlpha(1f - mIconAlpha.value) - .withCornerRadius(mWindowRadius.value) - .withShadowRadius(mShadowRadius.value); + builder.setMatrix(matrix) + .setWindowCrop(crop) + .setAlpha(1f - mIconAlpha.value) + .setCornerRadius(mWindowRadius.value) + .setShadowRadius(mShadowRadius.value); } else if (target.mode == MODE_CLOSING) { if (target.localBounds != null) { final Rect localBounds = target.localBounds; @@ -861,29 +863,26 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener tmpPos.y = tmp; } matrix.setTranslate(tmpPos.x, tmpPos.y); - builder.withMatrix(matrix) - .withWindowCrop(crop) - .withAlpha(1f); + builder.setMatrix(matrix) + .setWindowCrop(crop) + .setAlpha(1f); } - params.add(builder.build()); } if (navBarTarget != null) { - final SurfaceParams.Builder navBuilder = - new SurfaceParams.Builder(navBarTarget.leash); + SurfaceProperties navBuilder = + transaction.forSurface(navBarTarget.leash); if (mNavFadeIn.value > mNavFadeIn.getStartValue()) { matrix.setScale(scale, scale); matrix.postTranslate(windowTransX0, windowTransY0); - navBuilder.withMatrix(matrix) - .withWindowCrop(crop) - .withAlpha(mNavFadeIn.value); + navBuilder.setMatrix(matrix) + .setWindowCrop(crop) + .setAlpha(mNavFadeIn.value); } else { - navBuilder.withAlpha(mNavFadeOut.value); + navBuilder.setAlpha(mNavFadeOut.value); } - params.add(navBuilder.build()); } - - surfaceApplier.scheduleApply(params.toArray(new SurfaceParams[params.size()])); + surfaceApplier.scheduleApply(transaction); } }; appAnimator.addUpdateListener(listener); @@ -999,37 +998,33 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener matrix.postScale(mAppWindowScale, mAppWindowScale, widgetBackgroundBounds.left, widgetBackgroundBounds.top); - ArrayList params = new ArrayList<>(); + SurfaceTransaction transaction = new SurfaceTransaction(); float floatingViewAlpha = appTargetsAreTranslucent ? 1 - mPreviewAlpha.value : 1; for (int i = appTargets.length - 1; i >= 0; i--) { RemoteAnimationTargetCompat target = appTargets[i]; - SurfaceParams.Builder builder = new SurfaceParams.Builder(target.leash); + SurfaceProperties builder = transaction.forSurface(target.leash); if (target.mode == MODE_OPENING) { floatingView.update(widgetBackgroundBounds, floatingViewAlpha, mWidgetForegroundAlpha.value, mWidgetFallbackBackgroundAlpha.value, mCornerRadiusProgress.value); - builder.withMatrix(matrix) - .withWindowCrop(appWindowCrop) - .withAlpha(mPreviewAlpha.value) - .withCornerRadius(mWindowRadius.value / mAppWindowScale); + builder.setMatrix(matrix) + .setWindowCrop(appWindowCrop) + .setAlpha(mPreviewAlpha.value) + .setCornerRadius(mWindowRadius.value / mAppWindowScale); } - params.add(builder.build()); } if (navBarTarget != null) { - final SurfaceParams.Builder navBuilder = - new SurfaceParams.Builder(navBarTarget.leash); + SurfaceProperties navBuilder = transaction.forSurface(navBarTarget.leash); if (mNavFadeIn.value > mNavFadeIn.getStartValue()) { - navBuilder.withMatrix(matrix) - .withWindowCrop(appWindowCrop) - .withAlpha(mNavFadeIn.value); + navBuilder.setMatrix(matrix) + .setWindowCrop(appWindowCrop) + .setAlpha(mNavFadeIn.value); } else { - navBuilder.withAlpha(mNavFadeOut.value); + navBuilder.setAlpha(mNavFadeOut.value); } - params.add(navBuilder.build()); } - - surfaceApplier.scheduleApply(params.toArray(new SurfaceParams[params.size()])); + surfaceApplier.scheduleApply(transaction); } }); @@ -1224,16 +1219,15 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener unlockAnimator.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { - SurfaceParams[] params = new SurfaceParams[appTargets.length]; + SurfaceTransaction transaction = new SurfaceTransaction(); for (int i = appTargets.length - 1; i >= 0; i--) { RemoteAnimationTargetCompat target = appTargets[i]; - params[i] = new SurfaceParams.Builder(target.leash) - .withAlpha(1f) - .withWindowCrop(target.screenSpaceBounds) - .withCornerRadius(cornerRadius) - .build(); + transaction.forSurface(target.leash) + .setAlpha(1f) + .setWindowCrop(target.screenSpaceBounds) + .setCornerRadius(cornerRadius); } - surfaceApplier.scheduleApply(params); + surfaceApplier.scheduleApply(transaction); } }); return unlockAnimator; @@ -1451,10 +1445,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener @Override public void onUpdate(float percent, boolean initOnly) { - SurfaceParams[] params = new SurfaceParams[appTargets.length]; + SurfaceTransaction transaction = new SurfaceTransaction(); for (int i = appTargets.length - 1; i >= 0; i--) { RemoteAnimationTargetCompat target = appTargets[i]; - SurfaceParams.Builder builder = new SurfaceParams.Builder(target.leash); + SurfaceProperties builder = transaction.forSurface(target.leash); if (target.localBounds != null) { tmpPos.set(target.localBounds.left, target.localBounds.top); @@ -1476,20 +1470,19 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener tmpRect.centerY()); matrix.postTranslate(0, mDy.value); matrix.postTranslate(tmpPos.x, tmpPos.y); - builder.withMatrix(matrix) - .withWindowCrop(crop) - .withAlpha(mAlpha.value) - .withCornerRadius(windowCornerRadius) - .withShadowRadius(mShadowRadius.value); + builder.setMatrix(matrix) + .setWindowCrop(crop) + .setAlpha(mAlpha.value) + .setCornerRadius(windowCornerRadius) + .setShadowRadius(mShadowRadius.value); } else if (target.mode == MODE_OPENING) { matrix.setTranslate(tmpPos.x, tmpPos.y); - builder.withMatrix(matrix) - .withWindowCrop(crop) - .withAlpha(1f); + builder.setMatrix(matrix) + .setWindowCrop(crop) + .setAlpha(1f); } - params[i] = builder.build(); } - surfaceApplier.scheduleApply(params); + surfaceApplier.scheduleApply(transaction); } }); @@ -1859,10 +1852,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener @Override public void onUpdate(RectF currentRectF, float progress) { - SurfaceParams[] params = new SurfaceParams[mAppTargets.length]; + SurfaceTransaction transaction = new SurfaceTransaction(); for (int i = mAppTargets.length - 1; i >= 0; i--) { RemoteAnimationTargetCompat target = mAppTargets[i]; - SurfaceParams.Builder builder = new SurfaceParams.Builder(target.leash); + SurfaceProperties builder = transaction.forSurface(target.leash); if (target.localBounds != null) { mTmpPos.set(target.localBounds.left, target.localBounds.top); @@ -1897,18 +1890,17 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener mMatrix.setScale(scale, scale); mMatrix.postTranslate(mCurrentRect.left, mCurrentRect.top); - builder.withMatrix(mMatrix) - .withWindowCrop(mTmpRect) - .withAlpha(getWindowAlpha(progress)) - .withCornerRadius(getCornerRadius(progress) / scale); + builder.setMatrix(mMatrix) + .setWindowCrop(mTmpRect) + .setAlpha(getWindowAlpha(progress)) + .setCornerRadius(getCornerRadius(progress) / scale); } else if (target.mode == MODE_OPENING) { mMatrix.setTranslate(mTmpPos.x, mTmpPos.y); - builder.withMatrix(mMatrix) - .withAlpha(1f); + builder.setMatrix(mMatrix) + .setAlpha(1f); } - params[i] = builder.build(); } - mSurfaceApplier.scheduleApply(params); + mSurfaceApplier.scheduleApply(transaction); } protected float getWindowAlpha(float progress) { diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 07ddcc8b31..d728b7539b 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -116,6 +116,7 @@ import com.android.quickstep.util.ProtoTracer; import com.android.quickstep.util.RecentsOrientedState; import com.android.quickstep.util.RectFSpringAnim; import com.android.quickstep.util.StaggeredWorkspaceAnim; +import com.android.quickstep.util.SurfaceTransaction; import com.android.quickstep.util.SurfaceTransactionApplier; import com.android.quickstep.util.SwipePipToHomeAnimator; import com.android.quickstep.util.TaskViewSimulator; @@ -128,8 +129,6 @@ import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.wm.shell.common.TransactionPool; @@ -2108,16 +2107,13 @@ public abstract class AbsSwipeUpHandler, // When revealing the app with launcher splash screen, make the app visible // and behind the splash view before the splash is animated away. - SyncRtSurfaceTransactionApplierCompat surfaceApplier = - new SyncRtSurfaceTransactionApplierCompat(splashView); - ArrayList params = new ArrayList<>(); + SurfaceTransactionApplier surfaceApplier = + new SurfaceTransactionApplier(splashView); + SurfaceTransaction transaction = new SurfaceTransaction(); for (RemoteAnimationTargetCompat target : appearedTaskTargets) { - SurfaceParams.Builder builder = new SurfaceParams.Builder(target.leash); - builder.withAlpha(1); - builder.withLayer(-1); - params.add(builder.build()); + transaction.forSurface(target.leash).setAlpha(1).setLayer(-1); } - surfaceApplier.scheduleApply(params.toArray(new SurfaceParams[0])); + surfaceApplier.scheduleApply(transaction); SplashScreenExitAnimationUtils.startAnimations(splashView, taskTarget.leash, mSplashMainWindowShiftLength, new TransactionPool(), new Rect(), diff --git a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java index 99f7bdd2e7..e55e966c13 100644 --- a/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java +++ b/quickstep/src/com/android/quickstep/FallbackSwipeHandler.java @@ -65,12 +65,12 @@ import com.android.launcher3.util.DisplayController; import com.android.quickstep.fallback.FallbackRecentsView; import com.android.quickstep.fallback.RecentsState; import com.android.quickstep.util.RectFSpringAnim; +import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties; import com.android.quickstep.util.TransformParams; import com.android.quickstep.util.TransformParams.BuilderProxy; import com.android.systemui.shared.recents.model.Task.TaskKey; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; import java.lang.ref.WeakReference; import java.util.ArrayList; @@ -125,18 +125,18 @@ public class FallbackSwipeHandler extends } } - private void updateHomeActivityTransformDuringSwipeUp(SurfaceParams.Builder builder, + private void updateHomeActivityTransformDuringSwipeUp(SurfaceProperties builder, RemoteAnimationTargetCompat app, TransformParams params) { setHomeScaleAndAlpha(builder, app, mCurrentShift.value, Utilities.boundToRange(1 - mCurrentShift.value, 0, 1)); } - private void setHomeScaleAndAlpha(SurfaceParams.Builder builder, + private void setHomeScaleAndAlpha(SurfaceProperties builder, RemoteAnimationTargetCompat app, float verticalShift, float alpha) { float scale = Utilities.mapRange(verticalShift, 1, mMaxLauncherScale); mTmpMatrix.setScale(scale, scale, app.localBounds.exactCenterX(), app.localBounds.exactCenterY()); - builder.withMatrix(mTmpMatrix).withAlpha(alpha); + builder.setMatrix(mTmpMatrix).setAlpha(alpha); } @Override @@ -279,12 +279,12 @@ public class FallbackSwipeHandler extends return mTargetRect; } - private void updateRecentsActivityTransformDuringHomeAnim(SurfaceParams.Builder builder, + private void updateRecentsActivityTransformDuringHomeAnim(SurfaceProperties builder, RemoteAnimationTargetCompat app, TransformParams params) { - builder.withAlpha(mRecentsAlpha.value); + builder.setAlpha(mRecentsAlpha.value); } - private void updateHomeActivityTransformDuringHomeAnim(SurfaceParams.Builder builder, + private void updateHomeActivityTransformDuringHomeAnim(SurfaceProperties builder, RemoteAnimationTargetCompat app, TransformParams params) { setHomeScaleAndAlpha(builder, app, mVerticalShiftForScale.value, mHomeAlpha.value); } diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java index 7a281dd2a7..ee3b0752b9 100644 --- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java +++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java @@ -46,7 +46,6 @@ import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.quickstep.util.RectFSpringAnim; import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; /** * Controls the animation of swiping back and returning to launcher. @@ -242,20 +241,17 @@ public class LauncherBackAnimationController { /** Transform the target window to match the target rect. */ private void applyTransform(RectF targetRect, float cornerRadius) { - SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder builder = - new SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder(mBackTarget.leash); final float scale = targetRect.width() / mStartRect.width(); mTransformMatrix.reset(); mTransformMatrix.setScale(scale, scale); mTransformMatrix.postTranslate(targetRect.left, targetRect.top); - builder.withMatrix(mTransformMatrix) - .withWindowCrop(mStartRect) - .withCornerRadius(cornerRadius); - SyncRtSurfaceTransactionApplierCompat.SurfaceParams surfaceParams = builder.build(); - if (surfaceParams.surface.isValid()) { - surfaceParams.applyTo(mTransaction); + if (mBackTarget.leash.isValid()) { + mTransaction.setMatrix(mBackTarget.leash, mTransformMatrix, new float[9]); + mTransaction.setWindowCrop(mBackTarget.leash, mStartRect); + mTransaction.setCornerRadius(mBackTarget.leash, cornerRadius); } + mTransaction.apply(); } diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java index baeb514e18..71e8a774f7 100644 --- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java +++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java @@ -37,11 +37,11 @@ import com.android.launcher3.touch.PagedOrientationHandler; import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle; import com.android.quickstep.util.AnimatorControllerWithResistance; import com.android.quickstep.util.RectFSpringAnim; +import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties; import com.android.quickstep.util.TaskViewSimulator; import com.android.quickstep.util.TransformParams; import com.android.quickstep.util.TransformParams.BuilderProxy; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder; import java.util.Arrays; import java.util.function.Consumer; @@ -335,11 +335,11 @@ public abstract class SwipeUpAnimationLogic implements } @Override - public void onBuildTargetParams( - Builder builder, RemoteAnimationTargetCompat app, TransformParams params) { - builder.withMatrix(mMatrix) - .withWindowCrop(mCropRect) - .withCornerRadius(params.getCornerRadius()); + public void onBuildTargetParams(SurfaceProperties builder, RemoteAnimationTargetCompat app, + TransformParams params) { + builder.setMatrix(mMatrix) + .setWindowCrop(mCropRect) + .setCornerRadius(params.getCornerRadius()); } @Override diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java index df80e2f867..bfebbbcbfa 100644 --- a/quickstep/src/com/android/quickstep/TaskViewUtils.java +++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java @@ -70,6 +70,8 @@ import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.util.DisplayController; import com.android.quickstep.RemoteTargetGluer.RemoteTargetHandle; import com.android.quickstep.util.MultiValueUpdateListener; +import com.android.quickstep.util.SurfaceTransaction; +import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties; import com.android.quickstep.util.SurfaceTransactionApplier; import com.android.quickstep.util.TaskViewSimulator; import com.android.quickstep.util.TransformParams; @@ -80,7 +82,6 @@ import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; import java.util.ArrayList; import java.util.List; @@ -250,21 +251,24 @@ public final class TaskViewUtils { @Override public void onUpdate(float percent, boolean initOnly) { - final SurfaceParams.Builder navBuilder = - new SurfaceParams.Builder(navBarTarget.leash); + // TODO Do we need to operate over multiple TVSs for the navbar leash? for (RemoteTargetHandle handle : remoteTargetHandles) { + SurfaceTransaction transaction = new SurfaceTransaction(); + SurfaceProperties navBuilder = + transaction.forSurface(navBarTarget.leash); + if (mNavFadeIn.value > mNavFadeIn.getStartValue()) { TaskViewSimulator taskViewSimulator = handle.getTaskViewSimulator(); taskViewSimulator.getCurrentCropRect().round(cropRect); - navBuilder.withMatrix(taskViewSimulator.getCurrentMatrix()) - .withWindowCrop(cropRect) - .withAlpha(mNavFadeIn.value); + navBuilder.setMatrix(taskViewSimulator.getCurrentMatrix()) + .setWindowCrop(cropRect) + .setAlpha(mNavFadeIn.value); } else { - navBuilder.withAlpha(mNavFadeOut.value); + navBuilder.setAlpha(mNavFadeOut.value); } - handle.getTransformParams().applySurfaceParams(navBuilder.build()); + handle.getTransformParams().applySurfaceParams(transaction); } } }); @@ -480,7 +484,7 @@ public final class TaskViewUtils { * If {@param launchingTaskView} is not null, then this will play the tasks launch animation * from the position of the GroupedTaskView (when user taps on the TaskView to start it). * Technically this case should be taken care of by - * {@link #composeRecentsSplitLaunchAnimatorLegacy()} below, but the way we launch tasks whether + * {@link #composeRecentsSplitLaunchAnimatorLegacy} below, but the way we launch tasks whether * it's a single task or multiple tasks results in different entry-points. * * If it is null, then it will simply fade in the starting apps and fade out launcher (for the diff --git a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java index 6bc24f2b9b..c131c055f6 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java @@ -53,13 +53,13 @@ import com.android.quickstep.RecentsAnimationController; import com.android.quickstep.RecentsAnimationDeviceState; import com.android.quickstep.RecentsAnimationTargets; import com.android.quickstep.TaskAnimationManager; +import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties; import com.android.quickstep.util.TransformParams; import com.android.quickstep.util.TransformParams.BuilderProxy; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputMonitorCompat; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder; import java.util.HashMap; @@ -290,9 +290,9 @@ public class DeviceLockedInputConsumer implements InputConsumer, @Override public void onBuildTargetParams( - Builder builder, RemoteAnimationTargetCompat app, TransformParams params) { + SurfaceProperties builder, RemoteAnimationTargetCompat app, TransformParams params) { mMatrix.setTranslate(0, mProgress.value * mMaxTranslationY); - builder.withMatrix(mMatrix); + builder.setMatrix(mMatrix); } @Override diff --git a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java index fa7bc04b30..d7ff0be3fa 100644 --- a/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java +++ b/quickstep/src/com/android/quickstep/interaction/SwipeUpGestureTutorialController.java @@ -33,7 +33,6 @@ import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.os.Build; -import android.view.SurfaceControl; import android.view.View; import android.view.ViewOutlineProvider; @@ -53,9 +52,11 @@ import com.android.quickstep.RecentsAnimationDeviceState; import com.android.quickstep.RemoteTargetGluer; import com.android.quickstep.SwipeUpAnimationLogic; import com.android.quickstep.SwipeUpAnimationLogic.RunningWindowAnim; +import com.android.quickstep.util.RecordingSurfaceTransaction; import com.android.quickstep.util.RectFSpringAnim; +import com.android.quickstep.util.SurfaceTransaction; +import com.android.quickstep.util.SurfaceTransaction.MockProperties; import com.android.quickstep.util.TransformParams; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; @TargetApi(Build.VERSION_CODES.R) abstract class SwipeUpGestureTutorialController extends TutorialController { @@ -415,21 +416,23 @@ abstract class SwipeUpGestureTutorialController extends TutorialController { private class FakeTransformParams extends TransformParams { @Override - public SurfaceParams[] createSurfaceParams(BuilderProxy proxy) { - SurfaceParams.Builder builder = new SurfaceParams.Builder((SurfaceControl) null); - proxy.onBuildTargetParams(builder, null, this); - return new SurfaceParams[] {builder.build()}; + public SurfaceTransaction createSurfaceParams(BuilderProxy proxy) { + RecordingSurfaceTransaction transaction = new RecordingSurfaceTransaction(); + proxy.onBuildTargetParams(transaction.mockProperties, null, this); + return transaction; } @Override - public void applySurfaceParams(SurfaceParams[] params) { - SurfaceParams p = params[0]; - mFakeTaskView.setAnimationMatrix(p.matrix); - mFakePreviousTaskView.setAnimationMatrix(p.matrix); - mFakeTaskViewRect.set(p.windowCrop); - mFakeTaskViewRadius = p.cornerRadius; - mFakeTaskView.invalidateOutline(); - mFakePreviousTaskView.invalidateOutline(); + public void applySurfaceParams(SurfaceTransaction params) { + if (params instanceof RecordingSurfaceTransaction) { + MockProperties p = ((RecordingSurfaceTransaction) params).mockProperties; + mFakeTaskView.setAnimationMatrix(p.matrix); + mFakePreviousTaskView.setAnimationMatrix(p.matrix); + mFakeTaskViewRect.set(p.windowCrop); + mFakeTaskViewRadius = p.cornerRadius; + mFakeTaskView.invalidateOutline(); + mFakePreviousTaskView.invalidateOutline(); + } } } } diff --git a/quickstep/src/com/android/quickstep/util/RecordingSurfaceTransaction.java b/quickstep/src/com/android/quickstep/util/RecordingSurfaceTransaction.java new file mode 100644 index 0000000000..a2f48ddc9b --- /dev/null +++ b/quickstep/src/com/android/quickstep/util/RecordingSurfaceTransaction.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2022 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; + +/** + * Extension for {@link SurfaceTransaction} which records the commands for mocking + */ +public class RecordingSurfaceTransaction extends SurfaceTransaction { + + /** + * A mock builder which can be used for recording values + */ + public final MockProperties mockProperties = new MockProperties(); + +} diff --git a/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java b/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java index 81c124f7e2..b2e159ee10 100644 --- a/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java +++ b/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java @@ -19,10 +19,10 @@ import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MOD import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.view.SurfaceControl.Transaction; import com.android.quickstep.RemoteAnimationTargets; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -import com.android.systemui.shared.system.TransactionCompat; /** * Animation listener which fades out the closing targets @@ -40,7 +40,7 @@ public class RemoteFadeOutAnimationListener implements AnimatorUpdateListener { @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { - TransactionCompat t = new TransactionCompat(); + Transaction t = new Transaction(); if (mFirstFrame) { for (RemoteAnimationTargetCompat target : mTarget.unfilteredApps) { t.show(target.leash); diff --git a/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java b/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java new file mode 100644 index 0000000000..7ab285dfa7 --- /dev/null +++ b/quickstep/src/com/android/quickstep/util/SurfaceTransaction.java @@ -0,0 +1,161 @@ +/* + * Copyright (C) 2022 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 android.graphics.Matrix; +import android.graphics.Rect; +import android.view.SurfaceControl; +import android.view.SurfaceControl.Transaction; + +/** + * Helper class for building a {@link Transaction}. + */ +public class SurfaceTransaction { + + private final Transaction mTransaction = new Transaction(); + private final float[] mTmpValues = new float[9]; + + /** + * Creates a new builder for the provided surface + */ + public SurfaceProperties forSurface(SurfaceControl surface) { + return surface.isValid() ? new SurfaceProperties(surface) : new MockProperties(); + } + + /** + * Returns the final transaction + */ + public Transaction getTransaction() { + return mTransaction; + } + + /** + * Utility class to update surface params in a transaction + */ + public class SurfaceProperties { + + private final SurfaceControl mSurface; + + SurfaceProperties(SurfaceControl surface) { + mSurface = surface; + } + + /** + * @param alpha The alpha value to apply to the surface. + * @return this Builder + */ + public SurfaceProperties setAlpha(float alpha) { + mTransaction.setAlpha(mSurface, alpha); + return this; + } + + /** + * @param matrix The matrix to apply to the surface. + * @return this Builder + */ + public SurfaceProperties setMatrix(Matrix matrix) { + mTransaction.setMatrix(mSurface, matrix, mTmpValues); + return this; + } + + /** + * @param windowCrop The window crop to apply to the surface. + * @return this Builder + */ + public SurfaceProperties setWindowCrop(Rect windowCrop) { + mTransaction.setWindowCrop(mSurface, windowCrop); + return this; + } + + /** + * @param relativeLayer The relative layer. + * @return this Builder + */ + public SurfaceProperties setLayer(int relativeLayer) { + mTransaction.setLayer(mSurface, relativeLayer); + return this; + } + + /** + * @param radius the Radius for rounded corners to apply to the surface. + * @return this Builder + */ + public SurfaceProperties setCornerRadius(float radius) { + mTransaction.setCornerRadius(mSurface, radius); + return this; + } + + /** + * @param radius the Radius for the shadows to apply to the surface. + * @return this Builder + */ + public SurfaceProperties setShadowRadius(float radius) { + mTransaction.setShadowRadius(mSurface, radius); + return this; + } + } + + /** + * Extension of {@link SurfaceProperties} which just stores all the values locally + */ + public class MockProperties extends SurfaceProperties { + + public float alpha = -1; + public Matrix matrix = null; + public Rect windowCrop = null; + public float cornerRadius = 0; + public float shadowRadius = 0; + + protected MockProperties() { + super(null); + } + + @Override + public SurfaceProperties setAlpha(float alpha) { + this.alpha = alpha; + return this; + } + + @Override + public SurfaceProperties setMatrix(Matrix matrix) { + this.matrix = matrix; + return this; + } + + @Override + public SurfaceProperties setWindowCrop(Rect windowCrop) { + this.windowCrop = windowCrop; + return this; + } + + @Override + public SurfaceProperties setLayer(int relativeLayer) { + return this; + } + + @Override + public SurfaceProperties setCornerRadius(float radius) { + this.cornerRadius = radius; + return this; + } + + @Override + public SurfaceProperties setShadowRadius(float radius) { + this.shadowRadius = radius; + return this; + } + } +} diff --git a/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java b/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java index 1200208e30..95473dc39a 100644 --- a/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java +++ b/quickstep/src/com/android/quickstep/util/SurfaceTransactionApplier.java @@ -25,7 +25,6 @@ import android.view.View; import android.view.ViewRootImpl; import com.android.quickstep.RemoteAnimationTargets.ReleaseCheck; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; import java.util.function.Consumer; @@ -70,18 +69,12 @@ public class SurfaceTransactionApplier extends ReleaseCheck { * @param params The surface parameters to apply. DO NOT MODIFY the list after passing into * this method to avoid synchronization issues. */ - public void scheduleApply(final SurfaceParams... params) { + public void scheduleApply(SurfaceTransaction params) { View view = mTargetViewRootImpl.getView(); if (view == null) { return; } - Transaction t = new Transaction(); - for (int i = params.length - 1; i >= 0; i--) { - SurfaceParams surfaceParams = params[i]; - if (surfaceParams.surface.isValid()) { - surfaceParams.applyTo(t); - } - } + Transaction t = params.getTransaction(); mLastSequenceNumber++; final int toApplySeqNo = mLastSequenceNumber; @@ -102,7 +95,7 @@ public class SurfaceTransactionApplier extends ReleaseCheck { } /** - * Creates an instance of SyncRtSurfaceTransactionApplier, deferring until the target view is + * Creates an instance of SurfaceTransactionApplier, deferring until the target view is * attached if necessary. */ public static void create( diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java index c03aa3f446..ff612f55b7 100644 --- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java +++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java @@ -46,11 +46,11 @@ import com.android.launcher3.util.TraceHelper; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.BaseActivityInterface; import com.android.quickstep.TaskAnimationManager; +import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties; import com.android.quickstep.views.TaskView.FullscreenDrawParams; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.recents.utilities.PreviewPositionHelper; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams.Builder; /** * A utility class which emulates the layout behavior of TaskView and RecentsView @@ -386,10 +386,10 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { @Override public void onBuildTargetParams( - Builder builder, RemoteAnimationTargetCompat app, TransformParams params) { - builder.withMatrix(mMatrix) - .withWindowCrop(mTmpCropRect) - .withCornerRadius(getCurrentCornerRadius()); + SurfaceProperties builder, RemoteAnimationTargetCompat app, TransformParams params) { + builder.setMatrix(mMatrix) + .setWindowCrop(mTmpCropRect) + .setCornerRadius(getCurrentCornerRadius()); // If mDrawsBelowRecents is unset, no reordering will be enforced. if (mDrawsBelowRecents != null) { @@ -398,7 +398,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { // conflict with layers that WM core positions (ie. the input consumers). For shell // transitions, the animation leashes are reparented to an animation container so we // can bump layers as needed. - builder.withLayer(mDrawsBelowRecents + builder.setLayer(mDrawsBelowRecents ? Integer.MIN_VALUE + 1 : ENABLE_SHELL_TRANSITIONS ? Integer.MAX_VALUE : 0); } diff --git a/quickstep/src/com/android/quickstep/util/TransformParams.java b/quickstep/src/com/android/quickstep/util/TransformParams.java index a7f25d40ef..3d505c6234 100644 --- a/quickstep/src/com/android/quickstep/util/TransformParams.java +++ b/quickstep/src/com/android/quickstep/util/TransformParams.java @@ -21,10 +21,8 @@ import android.view.SurfaceControl; import com.android.launcher3.Utilities; import com.android.launcher3.anim.Interpolators; import com.android.quickstep.RemoteAnimationTargets; +import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; -import com.android.systemui.shared.system.TransactionCompat; public class TransformParams { @@ -113,8 +111,7 @@ public class TransformParams { * Sets the SyncRtSurfaceTransactionApplierCompat that will apply the SurfaceParams that * are computed based on these TransformParams. */ - public TransformParams setSyncTransactionApplier( - SurfaceTransactionApplier applier) { + public TransformParams setSyncTransactionApplier(SurfaceTransactionApplier applier) { mSyncTransactionApplier = applier; return this; } @@ -137,16 +134,14 @@ public class TransformParams { return this; } - public SurfaceParams[] createSurfaceParams(BuilderProxy proxy) { + public SurfaceTransaction createSurfaceParams(BuilderProxy proxy) { RemoteAnimationTargets targets = mTargetSet; - final int appLength = targets.unfilteredApps.length; - final int wallpaperLength = targets.wallpapers != null ? targets.wallpapers.length : 0; - SurfaceParams[] surfaceParams = new SurfaceParams[appLength + wallpaperLength]; + SurfaceTransaction transaction = new SurfaceTransaction(); mRecentsSurface = getRecentsSurface(targets); - for (int i = 0; i < appLength; i++) { + for (int i = 0; i < targets.unfilteredApps.length; i++) { RemoteAnimationTargetCompat app = targets.unfilteredApps[i]; - SurfaceParams.Builder builder = new SurfaceParams.Builder(app.leash); + SurfaceProperties builder = transaction.forSurface(app.leash); if (app.mode == targets.targetMode) { if (app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) { @@ -156,9 +151,9 @@ public class TransformParams { if (app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT && app.isNotInRecents) { float progress = Utilities.boundToRange(getProgress(), 0, 1); - builder.withAlpha(1 - Interpolators.DEACCEL_2_5.getInterpolation(progress)); + builder.setAlpha(1 - Interpolators.DEACCEL_2_5.getInterpolation(progress)); } else { - builder.withAlpha(getTargetAlpha()); + builder.setAlpha(getTargetAlpha()); } proxy.onBuildTargetParams(builder, app, this); @@ -166,15 +161,15 @@ public class TransformParams { } else { mBaseBuilderProxy.onBuildTargetParams(builder, app, this); } - surfaceParams[i] = builder.build(); } + // always put wallpaper layer to bottom. + final int wallpaperLength = targets.wallpapers != null ? targets.wallpapers.length : 0; for (int i = 0; i < wallpaperLength; i++) { RemoteAnimationTargetCompat wallpaper = targets.wallpapers[i]; - surfaceParams[appLength + i] = new SurfaceParams.Builder(wallpaper.leash) - .withLayer(Integer.MIN_VALUE).build(); + transaction.forSurface(wallpaper.leash).setLayer(Integer.MIN_VALUE); } - return surfaceParams; + return transaction; } private static SurfaceControl getRecentsSurface(RemoteAnimationTargets targets) { @@ -213,15 +208,11 @@ public class TransformParams { return mTargetSet; } - public void applySurfaceParams(SurfaceParams... params) { + public void applySurfaceParams(SurfaceTransaction builder) { if (mSyncTransactionApplier != null) { - mSyncTransactionApplier.scheduleApply(params); + mSyncTransactionApplier.scheduleApply(builder); } else { - TransactionCompat t = new TransactionCompat(); - for (SurfaceParams param : params) { - SyncRtSurfaceTransactionApplierCompat.applyParams(t, param); - } - t.apply(); + builder.getTransaction().apply(); } } @@ -229,9 +220,9 @@ public class TransformParams { public interface BuilderProxy { BuilderProxy NO_OP = (builder, app, params) -> { }; - BuilderProxy ALWAYS_VISIBLE = (builder, app, params) ->builder.withAlpha(1); + BuilderProxy ALWAYS_VISIBLE = (builder, app, params) -> builder.setAlpha(1); - void onBuildTargetParams(SurfaceParams.Builder builder, + void onBuildTargetParams(SurfaceProperties builder, RemoteAnimationTargetCompat app, TransformParams params); } } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index c8ef9582f8..dbfd358a0e 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -180,6 +180,7 @@ import com.android.quickstep.util.RecentsOrientedState; import com.android.quickstep.util.SplitAnimationTimings; import com.android.quickstep.util.SplitScreenBounds; import com.android.quickstep.util.SplitSelectStateController; +import com.android.quickstep.util.SurfaceTransaction; import com.android.quickstep.util.SurfaceTransactionApplier; import com.android.quickstep.util.TaskViewSimulator; import com.android.quickstep.util.TaskVisualsChangeListener; @@ -192,7 +193,6 @@ import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import com.android.systemui.shared.system.PackageManagerWrapper; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.wm.shell.pip.IPipAnimationListener; @@ -1077,14 +1077,15 @@ public abstract class RecentsView { float percent = valueAnimator.getAnimatedFraction(); - SurfaceParams.Builder builder = new SurfaceParams.Builder( - apps[apps.length - 1].leash); + SurfaceTransaction transaction = new SurfaceTransaction(); Matrix matrix = new Matrix(); matrix.postScale(percent, percent); matrix.postTranslate(mActivity.getDeviceProfile().widthPx * (1 - percent) / 2, mActivity.getDeviceProfile().heightPx * (1 - percent) / 2); - builder.withAlpha(percent).withMatrix(matrix); - surfaceApplier.scheduleApply(builder.build()); + transaction.forSurface(apps[apps.length - 1].leash) + .setAlpha(percent) + .setMatrix(matrix); + surfaceApplier.scheduleApply(transaction); }); anim.play(appAnimator); anim.addListener(new AnimatorListenerAdapter() { diff --git a/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java b/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java index c1b3beb475..b90369132b 100644 --- a/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java +++ b/quickstep/tests/src/com/android/launcher3/model/WidgetsPredicationUpdateTaskTest.java @@ -36,7 +36,6 @@ import android.appwidget.AppWidgetProviderInfo; import android.content.ComponentName; import android.os.UserHandle; import android.text.TextUtils; -import android.util.Log; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; @@ -111,7 +110,6 @@ public final class WidgetsPredicationUpdateTaskTest { doReturn(allWidgets).when(manager).getInstalledProvidersForProfile(eq(myUserHandle())); doAnswer(i -> { String pkg = i.getArgument(0); - Log.e("Hello", "Getting v " + pkg); return TextUtils.isEmpty(pkg) ? allWidgets : allWidgets.stream() .filter(a -> pkg.equals(a.provider.getPackageName())) .collect(Collectors.toList()); diff --git a/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java b/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java index 190b002d09..97eee1f285 100644 --- a/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java +++ b/quickstep/tests/src/com/android/quickstep/util/TaskViewSimulatorTest.java @@ -24,7 +24,6 @@ import android.graphics.Rect; import android.graphics.RectF; import android.util.ArrayMap; import android.view.Surface; -import android.view.SurfaceControl; import androidx.test.ext.junit.runners.AndroidJUnit4; import androidx.test.filters.SmallTest; @@ -42,8 +41,8 @@ import com.android.launcher3.util.window.CachedDisplayInfo; import com.android.launcher3.util.window.WindowManagerProxy; import com.android.quickstep.FallbackActivityInterface; import com.android.quickstep.SystemUiProxy; +import com.android.quickstep.util.SurfaceTransaction.MockProperties; import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -import com.android.systemui.shared.system.SyncRtSurfaceTransactionApplierCompat.SurfaceParams; import org.hamcrest.Description; import org.hamcrest.TypeSafeMatcher; @@ -207,17 +206,21 @@ public class TaskViewSimulatorTest { } @Override - public SurfaceParams[] createSurfaceParams(BuilderProxy proxy) { - SurfaceParams.Builder builder = new SurfaceParams.Builder((SurfaceControl) null); - proxy.onBuildTargetParams(builder, mock(RemoteAnimationTargetCompat.class), this); - return new SurfaceParams[] {builder.build()}; + public SurfaceTransaction createSurfaceParams(BuilderProxy proxy) { + RecordingSurfaceTransaction transaction = new RecordingSurfaceTransaction(); + proxy.onBuildTargetParams( + transaction.mockProperties, mock(RemoteAnimationTargetCompat.class), this); + return transaction; } @Override - public void applySurfaceParams(SurfaceParams[] params) { + public void applySurfaceParams(SurfaceTransaction params) { + Assert.assertTrue(params instanceof RecordingSurfaceTransaction); + MockProperties p = ((RecordingSurfaceTransaction) params).mockProperties; + // Verify that the task position remains the same RectF newAppBounds = new RectF(mAppBounds); - params[0].matrix.mapRect(newAppBounds); + p.matrix.mapRect(newAppBounds); Assert.assertThat(newAppBounds, new AlmostSame(mAppBounds)); System.err.println("Bounds mapped: " + mAppBounds + " => " + newAppBounds); From 1028a726efbff75df60e2dde9d7d13d933cf7b52 Mon Sep 17 00:00:00 2001 From: Federico Baron Date: Thu, 13 Oct 2022 14:09:38 -0700 Subject: [PATCH 087/429] Get rid of spring loaded mode for home gardening design For the new home gardening mode, we plan on not having a spring loaded mode where the overlay shrinks, so when we have the flag for home gardening on, we won't be having the workspace have the green overlay and the icons shrink Bug: 251259222 Test: Hold on an icon in workspace to enter edit workspace mode, notice how we no longer shrink the workspace Change-Id: Ibf1c38eecc117a838eca20a860d47c355955b513 --- src/com/android/launcher3/CellLayout.java | 11 ++++++++--- src/com/android/launcher3/Workspace.java | 1 - .../android/launcher3/states/SpringLoadedState.java | 13 +++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index c1df403b54..cdd8f5a1c8 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -19,6 +19,7 @@ package com.android.launcher3; import static android.animation.ValueAnimator.areAnimatorsEnabled; import static com.android.launcher3.anim.Interpolators.DEACCEL_1_5; +import static com.android.launcher3.config.FeatureFlags.SHOW_HOME_GARDENING; import static com.android.launcher3.dragndrop.DraggableView.DRAGGABLE_ICON; import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR; @@ -552,7 +553,9 @@ public class CellLayout extends ViewGroup { public void setSpringLoadedProgress(float progress) { if (Float.compare(progress, mSpringLoadedProgress) != 0) { mSpringLoadedProgress = progress; - updateBgAlpha(); + if (!SHOW_HOME_GARDENING.get()) { + updateBgAlpha(); + } setGridAlpha(progress); } } @@ -577,7 +580,9 @@ public class CellLayout extends ViewGroup { public void setScrollProgress(float progress) { if (Float.compare(Math.abs(progress), mScrollProgress) != 0) { mScrollProgress = Math.abs(progress); - updateBgAlpha(); + if (!SHOW_HOME_GARDENING.get()) { + updateBgAlpha(); + } } } @@ -616,7 +621,7 @@ public class CellLayout extends ViewGroup { } } - if (mVisualizeDropLocation) { + if (mVisualizeDropLocation && !SHOW_HOME_GARDENING.get()) { for (int i = 0; i < mDragOutlines.length; i++) { final float alpha = mDragOutlineAlphas[i]; if (alpha <= 0) continue; diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 6aff83e300..5d388dcbed 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -107,7 +107,6 @@ import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.RunnableList; import com.android.launcher3.util.Thunk; import com.android.launcher3.util.WallpaperOffsetInterpolator; -import com.android.launcher3.views.ActivityContext; import com.android.launcher3.widget.LauncherAppWidgetHost; import com.android.launcher3.widget.LauncherAppWidgetHost.ProviderChangedListener; import com.android.launcher3.widget.LauncherAppWidgetHostView; diff --git a/src/com/android/launcher3/states/SpringLoadedState.java b/src/com/android/launcher3/states/SpringLoadedState.java index 3286afb67c..f5d511c7d3 100644 --- a/src/com/android/launcher3/states/SpringLoadedState.java +++ b/src/com/android/launcher3/states/SpringLoadedState.java @@ -15,6 +15,7 @@ */ package com.android.launcher3.states; +import static com.android.launcher3.config.FeatureFlags.SHOW_HOME_GARDENING; import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_HOME; import android.content.Context; @@ -44,6 +45,11 @@ public class SpringLoadedState extends LauncherState { @Override public ScaleAndTranslation getWorkspaceScaleAndTranslation(Launcher launcher) { + + if (SHOW_HOME_GARDENING.get()) { + return super.getWorkspaceScaleAndTranslation(launcher); + } + DeviceProfile grid = launcher.getDeviceProfile(); Workspace ws = launcher.getWorkspace(); if (ws.getChildCount() == 0) { @@ -62,6 +68,9 @@ public class SpringLoadedState extends LauncherState { @Override protected float getDepthUnchecked(Context context) { + if (SHOW_HOME_GARDENING.get()) { + return 0; + } return 0.5f; } @@ -72,6 +81,10 @@ public class SpringLoadedState extends LauncherState { @Override public float getWorkspaceBackgroundAlpha(Launcher launcher) { + if (SHOW_HOME_GARDENING.get()) { + return 0; + } + return 0.2f; } } From dbd01bf6f9db1159f6e43a89b326b5169ea0b6df Mon Sep 17 00:00:00 2001 From: Holly Sun Date: Wed, 21 Sep 2022 16:34:14 -0700 Subject: [PATCH 088/429] Log a-z apps count. Test: manual Bug: 247432075 Change-Id: I9538a75bc3cb3d1e8e9089fc5e27d5d770cafb62 --- .../quickstep/logging/StatsLogCompatManager.java | 10 +++++++++- .../launcher3/allapps/BaseAllAppsContainerView.java | 5 +++++ .../android/launcher3/logging/StatsLogManager.java | 13 ++++++++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java index a9ff0fb07f..79c578df53 100644 --- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java +++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java @@ -217,6 +217,7 @@ public class StatsLogCompatManager extends StatsLogManager { private Optional mEditText = Optional.empty(); private SliceItem mSliceItem; private LauncherAtom.Slice mSlice; + private Optional mCardinality = Optional.empty(); StatsCompatLogger(Context context, ActivityContext activityContext) { mContext = context; @@ -303,6 +304,12 @@ public class StatsLogCompatManager extends StatsLogManager { return this; } + @Override + public StatsLogger withCardinality(int cardinality) { + this.mCardinality = Optional.of(cardinality); + return this; + } + @Override public void log(EventEnum event) { if (!Utilities.ATLEAST_R) { @@ -421,6 +428,7 @@ public class StatsLogCompatManager extends StatsLogManager { if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { return; } + int cardinality = mCardinality.orElseGet(() -> getCardinality(atomInfo)); SysUiStatsLog.write( SysUiStatsLog.LAUNCHER_EVENT, SysUiStatsLog.LAUNCHER_UICHANGED__ACTION__DEFAULT_ACTION /* deprecated */, @@ -446,7 +454,7 @@ public class StatsLogCompatManager extends StatsLogManager { atomInfo.getFolderIcon().getFromLabelState().getNumber() /* fromState */, atomInfo.getFolderIcon().getToLabelState().getNumber() /* toState */, atomInfo.getFolderIcon().getLabelInfo() /* edittext */, - getCardinality(atomInfo) /* cardinality */, + cardinality /* cardinality */, getFeatures(atomInfo) /* features */, getSearchAttributes(atomInfo) /* searchAttributes */, getAttributes(atomInfo) /* attributes */ diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java index 70c1e18301..11df81ae12 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java @@ -15,6 +15,7 @@ */ package com.android.launcher3.allapps; +import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_COUNT; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_PERSONAL_TAB; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_TAP_ON_WORK_TAB; @@ -244,6 +245,10 @@ public abstract class BaseAllAppsContainerView Date: Wed, 19 Oct 2022 14:25:10 +0000 Subject: [PATCH 089/429] Add CUJ_RECENTS_SCROLLING This adds Jank instrumentation every time recent tasks are scrolled. Bug: 231130484 Bug: 228969045 Test: recorded prefetto trace while scrolling Change-Id: I3904257ef60a4e09c91a0d5297beadad0bce8785 --- quickstep/src/com/android/quickstep/views/RecentsView.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index c8ef9582f8..4752470164 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -1245,6 +1245,8 @@ public abstract class RecentsView 0) { setSwipeDownShouldLaunchApp(true); } + InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_RECENTS_SCROLLING); } @Override From 5fd67c75fa359065d9f87bcdef0fcc750f10da50 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 19 Oct 2022 10:26:05 -0700 Subject: [PATCH 090/429] Removing the dependency on LooperExecutor in ViewCapture Bug: 254487496 Test: Verified that the frame time stays the same Change-Id: Ib6ffc209e6df5b1293245971cc12d085549bcd1d --- .../android/quickstep/util/ViewCapture.java | 53 ++++++++++++------- 1 file changed, 34 insertions(+), 19 deletions(-) diff --git a/quickstep/src/com/android/quickstep/util/ViewCapture.java b/quickstep/src/com/android/quickstep/util/ViewCapture.java index 6171c5dbea..ba7d7f557c 100644 --- a/quickstep/src/com/android/quickstep/util/ViewCapture.java +++ b/quickstep/src/com/android/quickstep/util/ViewCapture.java @@ -23,10 +23,9 @@ import static java.util.stream.Collectors.toList; import android.content.Context; import android.content.res.Resources; -import android.os.Handler; import android.os.Looper; -import android.os.Message; import android.os.Process; +import android.os.SystemClock; import android.os.Trace; import android.text.TextUtils; import android.util.Base64; @@ -57,7 +56,9 @@ import java.io.OutputStream; import java.io.PrintWriter; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.Future; +import java.util.concurrent.Executor; +import java.util.concurrent.FutureTask; +import java.util.function.Consumer; import java.util.zip.GZIPOutputStream; /** @@ -83,7 +84,7 @@ public class ViewCapture { private final List mListeners = new ArrayList<>(); private final Context mContext; - private final LooperExecutor mExecutor; + private final Executor mExecutor; // Pool used for capturing view tree on the UI thread. private ViewRef mPool = new ViewRef(); @@ -156,8 +157,13 @@ public class ViewCapture { ViewIdProvider idProvider = new ViewIdProvider(mContext.getResources()); // Collect all the tasks first so that all the tasks are posted on the executor - List>> tasks = mListeners.stream() - .map(l -> Pair.create(l.name, mExecutor.submit(() -> l.dumpToProto(idProvider)))) + List>> tasks = mListeners.stream() + .map(l -> { + FutureTask task = + new FutureTask(() -> l.dumpToProto(idProvider)); + mExecutor.execute(task); + return Pair.create(l.name, task); + }) .collect(toList()); tasks.forEach(pair -> { @@ -187,7 +193,6 @@ public class ViewCapture { private final View mRoot; public final String name; - private final Handler mHandler; private final ViewRef mViewRef = new ViewRef(); private int mFrameIndexBg = -1; @@ -196,20 +201,23 @@ public class ViewCapture { private final ViewPropertyRef[] mNodesBg = new ViewPropertyRef[MEMORY_SIZE]; private boolean mDestroyed = false; + private final Consumer mCaptureCallback = this::captureViewPropertiesBg; WindowListener(View view, String name) { mRoot = view; this.name = name; - mHandler = new Handler(mExecutor.getLooper(), this::captureViewPropertiesBg); } @Override public void onDraw() { Trace.beginSection("view_capture"); captureViewTree(mRoot, mViewRef); - Message m = Message.obtain(mHandler); - m.obj = mViewRef.next; - mHandler.sendMessage(m); + ViewRef captured = mViewRef.next; + if (captured != null) { + captured.callback = mCaptureCallback; + captured.creationTime = SystemClock.uptimeMillis(); + mExecutor.execute(captured); + } mIsFirstFrame = false; Trace.endSection(); } @@ -219,12 +227,8 @@ public class ViewCapture { * back to the pool */ @WorkerThread - private boolean captureViewPropertiesBg(Message msg) { - ViewRef viewRefStart = (ViewRef) msg.obj; - long time = msg.getWhen(); - if (viewRefStart == null) { - return false; - } + private void captureViewPropertiesBg(ViewRef viewRefStart) { + long time = viewRefStart.creationTime; mFrameIndexBg++; if (mFrameIndexBg >= MEMORY_SIZE) { mFrameIndexBg = 0; @@ -292,7 +296,6 @@ public class ViewCapture { viewRefEnd = viewRefEnd.next; } mNodesBg[mFrameIndexBg] = resultStart; - return true; } private ViewPropertyRef findInLastFrame(int hashCode) { @@ -464,11 +467,14 @@ public class ViewCapture { } } - private static class ViewRef { + private static class ViewRef implements Runnable { public View view; public int childCount = 0; public ViewRef next; + public Consumer callback = null; + public long creationTime = 0; + public void transferTo(ViewPropertyRef out) { out.childCount = this.childCount; @@ -495,6 +501,15 @@ public class ViewCapture { out.visibility = view.getVisibility(); out.willNotDraw = view.willNotDraw(); } + + @Override + public void run() { + Consumer oldCallback = callback; + callback = null; + if (oldCallback != null) { + oldCallback.accept(this); + } + } } private static final class ViewIdProvider { From 0de35265c112bf8488a3d5c799808bf4cc0e5272 Mon Sep 17 00:00:00 2001 From: Anushree Ganjam Date: Wed, 12 Oct 2022 20:41:29 +0000 Subject: [PATCH 091/429] Add scroll up and scroll down logging. Bug: 247601175 Test: Manual. https://paste.googleplex.com/5757099224072192 Change-Id: Iec1697e1580c75572c9e77ec349942301ee87694 --- .../allapps/AllAppsRecyclerView.java | 34 +++++++++++++++++-- .../launcher3/logging/StatsLogManager.java | 14 ++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index 21a7dfbb41..0efa7c4444 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -17,7 +17,11 @@ package com.android.launcher3.allapps; import static android.view.View.MeasureSpec.UNSPECIFIED; -import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_SCROLLED; +import static com.android.launcher3.logger.LauncherAtom.ContainerInfo; +import static com.android.launcher3.logger.LauncherAtom.SearchResultContainer; +import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_SCROLLED_DOWN; +import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_SCROLLED_UNKNOWN_DIRECTION; +import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_SCROLLED_UP; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_VERTICAL_SWIPE_BEGIN; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_VERTICAL_SWIPE_END; import static com.android.launcher3.util.LogConfig.SEARCH_LOGGING; @@ -31,6 +35,7 @@ import android.util.SparseIntArray; import androidx.recyclerview.widget.RecyclerView; import com.android.launcher3.DeviceProfile; +import com.android.launcher3.ExtendedEditText; import com.android.launcher3.FastScrollRecyclerView; import com.android.launcher3.LauncherAppState; import com.android.launcher3.R; @@ -56,6 +61,7 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { private final SparseIntArray mViewHeights = new SparseIntArray(); private final SparseIntArray mCachedScrollPositions = new SparseIntArray(); private final AllAppsFastScrollHelper mFastScrollHelper; + private int mCumulativeVerticalScroll; private final AdapterDataObserver mObserver = new RecyclerView.AdapterDataObserver() { @@ -157,7 +163,7 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { StatsLogManager mgr = ActivityContext.lookupContext(getContext()).getStatsLogManager(); switch (state) { case SCROLL_STATE_DRAGGING: - mgr.logger().log(LAUNCHER_ALLAPPS_SCROLLED); + mCumulativeVerticalScroll = 0; requestFocus(); mgr.logger().sendToInteractionJankMonitor( LAUNCHER_ALLAPPS_VERTICAL_SWIPE_BEGIN, this); @@ -166,10 +172,17 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { case SCROLL_STATE_IDLE: mgr.logger().sendToInteractionJankMonitor( LAUNCHER_ALLAPPS_VERTICAL_SWIPE_END, this); + logCumulativeVerticalScroll(); break; } } + @Override + public void onScrolled(int dx, int dy) { + super.onScrolled(dx, dy); + mCumulativeVerticalScroll += dy; + } + /** * Maps the touch (from 0..1) to the adapter position that should be visible. */ @@ -349,4 +362,21 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { public boolean hasOverlappingRendering() { return false; } + + private void logCumulativeVerticalScroll() { + ActivityContext context = ActivityContext.lookupContext(getContext()); + StatsLogManager mgr = context.getStatsLogManager(); + ExtendedEditText editText = context.getAppsView().getSearchUiManager().getEditText(); + ContainerInfo containerInfo = ContainerInfo.newBuilder().setSearchResultContainer( + SearchResultContainer + .newBuilder() + .setQueryLength((editText == null) ? -1 : editText.length())).build(); + + // mCumulativeVerticalScroll == 0 when user comes back to original position, we don't + // know the direction of scrolling. + mgr.logger().withContainerInfo(containerInfo).log( + mCumulativeVerticalScroll == 0 ? LAUNCHER_ALLAPPS_SCROLLED_UNKNOWN_DIRECTION + : (mCumulativeVerticalScroll > 0) ? LAUNCHER_ALLAPPS_SCROLLED_DOWN + : LAUNCHER_ALLAPPS_SCROLLED_UP); + } } diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java index 22627b4ac2..837e47a4af 100644 --- a/src/com/android/launcher3/logging/StatsLogManager.java +++ b/src/com/android/launcher3/logging/StatsLogManager.java @@ -555,6 +555,20 @@ public class StatsLogManager implements ResourceBasedOverride { + "result page etc.") LAUNCHER_ALLAPPS_SCROLLED(985), + @UiEvent(doc = "User scrolled up on one of the all apps surfaces such as A-Z list, search " + + "result page etc.") + LAUNCHER_ALLAPPS_SCROLLED_UP(1229), + + @UiEvent(doc = + "User scrolled down on one of the all apps surfaces such as A-Z list, search " + + "result page etc.") + LAUNCHER_ALLAPPS_SCROLLED_DOWN(1230), + + @UiEvent(doc = "User scrolled on one of the all apps surfaces such as A-Z list, search " + + "result page etc and we don't know the direction since user came back to " + + "original position from which they scrolled.") + LAUNCHER_ALLAPPS_SCROLLED_UNKNOWN_DIRECTION(1231), + @UiEvent(doc = "User tapped taskbar home button") LAUNCHER_TASKBAR_HOME_BUTTON_TAP(1003), From b066f41fa3bc4d550a30e848bb0fc0b61980211b Mon Sep 17 00:00:00 2001 From: Sukesh Ram Date: Mon, 11 Jul 2022 14:51:59 -0700 Subject: [PATCH 092/429] Drag from appDrawer & pin onto secondary display homescreen Bug: 239246505 Test: Manual Change-Id: I817d8ef700f2d7caec6fa63123935502f17f2d2f Merged-In: I817d8ef700f2d7caec6fa63123935502f17f2d2f --- .../launcher3/config/FeatureFlags.java | 4 + .../secondarydisplay/PinnedAppsAdapter.java | 16 +- .../SecondaryDisplayLauncher.java | 140 ++++++++++++- .../SecondaryDragController.java | 194 ++++++++++++++++++ .../secondarydisplay/SecondaryDragLayer.java | 49 ++++- .../secondarydisplay/SecondaryDragView.java | 66 ++++++ 6 files changed, 461 insertions(+), 8 deletions(-) create mode 100644 src/com/android/launcher3/secondarydisplay/SecondaryDragController.java create mode 100644 src/com/android/launcher3/secondarydisplay/SecondaryDragView.java diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 3a530affad..ee9059298d 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -300,6 +300,10 @@ public final class FeatureFlags { public static final BooleanFlag ENABLE_TRANSIENT_TASKBAR = getDebugFlag( "ENABLE_TRANSIENT_TASKBAR", false, "Enables transient taskbar."); + public static final BooleanFlag SECONDARY_DRAG_N_DROP_TO_PIN = getDebugFlag( + "SECONDARY_DRAG_N_DROP_TO_PIN", false, + "Enable dragging and dropping to pin apps within secondary display"); + public static void initialize(Context context) { synchronized (sDebugFlags) { for (DebugFlag flag : sDebugFlags) { diff --git a/src/com/android/launcher3/secondarydisplay/PinnedAppsAdapter.java b/src/com/android/launcher3/secondarydisplay/PinnedAppsAdapter.java index a0ed77e38f..f03c62ac5c 100644 --- a/src/com/android/launcher3/secondarydisplay/PinnedAppsAdapter.java +++ b/src/com/android/launcher3/secondarydisplay/PinnedAppsAdapter.java @@ -168,15 +168,18 @@ public class PinnedAppsAdapter extends BaseAdapter implements OnSharedPreference mPrefs.unregisterOnSharedPreferenceChangeListener(this); } - private void update(ItemInfo info, Function op) { + /** + * Pins or unpins apps from home screen + */ + public void update(ItemInfo info, Function op) { ComponentKey key = new ComponentKey(info.getTargetComponent(), info.user); if (op.apply(key)) { createFilteredAppsList(); Set copy = new HashSet<>(mPinnedApps); Executors.MODEL_EXECUTOR.submit(() -> mPrefs.edit().putStringSet(PINNED_APPS_KEY, - copy.stream().map(this::encode).collect(Collectors.toSet())) - .apply()); + copy.stream().map(this::encode).collect(Collectors.toSet())) + .apply()); } } @@ -210,6 +213,13 @@ public class PinnedAppsAdapter extends BaseAdapter implements OnSharedPreference mPinnedApps.contains(new ComponentKey(info.getTargetComponent(), info.user))); } + /** + * Pins app to home screen + */ + public void addPinnedApp(ItemInfo info) { + update(info, mPinnedApps::add); + } + private class PinUnPinShortcut extends SystemShortcut { private final boolean mIsPinned; diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java index a55f7e3b69..1bea5908e8 100644 --- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java +++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java @@ -18,6 +18,9 @@ package com.android.launcher3.secondarydisplay; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; import android.content.Intent; +import android.graphics.Point; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; @@ -26,6 +29,9 @@ import android.view.inputmethod.InputMethodManager; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseDraggingActivity; +import com.android.launcher3.BubbleTextView; +import com.android.launcher3.DragSource; +import com.android.launcher3.DropTarget; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherModel; @@ -33,6 +39,11 @@ import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.allapps.ActivityAllAppsContainerView; +import com.android.launcher3.dragndrop.DragController; +import com.android.launcher3.dragndrop.DragOptions; +import com.android.launcher3.dragndrop.DraggableView; +import com.android.launcher3.graphics.DragPreviewProvider; +import com.android.launcher3.icons.FastBitmapDrawable; import com.android.launcher3.model.BgDataModel; import com.android.launcher3.model.StringCache; import com.android.launcher3.model.data.AppInfo; @@ -52,11 +63,11 @@ import java.util.HashMap; * Launcher activity for secondary displays */ public class SecondaryDisplayLauncher extends BaseDraggingActivity - implements BgDataModel.Callbacks { + implements BgDataModel.Callbacks, DragController.DragListener { private LauncherModel mModel; - private BaseDragLayer mDragLayer; + private SecondaryDragController mDragController; private ActivityAllAppsContainerView mAppsView; private View mAppsButton; @@ -69,10 +80,13 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity private boolean mBindingItems = false; private SecondaryDisplayPredictions mSecondaryDisplayPredictions; + private final int[] mTempXY = new int[2]; + @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mModel = LauncherAppState.getInstance(this).getModel(); + mDragController = new SecondaryDragController(this); mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this)); mSecondaryDisplayPredictions = SecondaryDisplayPredictions.newInstance(this); if (getWindow().getDecorView().isAttachedToWindow()) { @@ -86,6 +100,12 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity initUi(); } + @Override + public void onDetachedFromWindow() { + super.onDetachedFromWindow(); + this.getDragController().removeDragListener(this); + } + private void initUi() { if (mDragLayer != null) { return; @@ -106,12 +126,19 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity mAppsView = findViewById(R.id.apps_view); mAppsButton = findViewById(R.id.all_apps_button); + mDragController.addDragListener(this); mPopupDataProvider = new PopupDataProvider( mAppsView.getAppsStore()::updateNotificationDots); mModel.addCallbacksAndLoad(this); } + @Override + protected void onPause() { + super.onPause(); + mDragController.cancelDrag(); + } + @Override public void onNewIntent(Intent intent) { super.onNewIntent(intent); @@ -129,12 +156,21 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity showAppDrawer(false); } + public DragController getDragController() { + return mDragController; + } + @Override public void onBackPressed() { if (finishAutoCancelActionMode()) { return; } + if (mDragController.isDragging()) { + mDragController.cancelDrag(); + return; + } + // Note: There should be at most one log per method call. This is enforced implicitly // by using if-else statements. AbstractFloatingView topView = AbstractFloatingView.getTopOpenView(this); @@ -202,7 +238,7 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity float closeR = Themes.getDialogCornerRadius(this); float startR = mAppsButton.getWidth() / 2f; - float[] buttonPos = new float[] { startR, startR}; + float[] buttonPos = new float[]{startR, startR}; mDragLayer.getDescendantCoordRelativeToSelf(mAppsButton, buttonPos); mDragLayer.mapCoordInSelfToDescendant(mAppsView, buttonPos); final Animator animator = ViewAnimationUtils.createCircularReveal(mAppsView, @@ -236,6 +272,7 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity @Override public void startBinding() { mBindingItems = true; + mDragController.cancelDrag(); } @Override @@ -308,4 +345,101 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity startActivitySafely(v, intent, item); } } + + /** + * Core functionality for beginning a drag operation for an item that will be dropped within + * the secondary display grid home screen + */ + public void beginDragShared(View child, DragSource source, DragOptions options) { + Object dragObject = child.getTag(); + if (!(dragObject instanceof ItemInfo)) { + String msg = "Drag started with a view that has no tag set. This " + + "will cause a crash (issue 11627249) down the line. " + + "View: " + child + " tag: " + child.getTag(); + throw new IllegalStateException(msg); + } + beginDragShared(child, source, (ItemInfo) dragObject, + new DragPreviewProvider(child), options); + } + + private void beginDragShared(View child, DragSource source, + ItemInfo dragObject, DragPreviewProvider previewProvider, DragOptions options) { + + float iconScale = 1f; + if (child instanceof BubbleTextView) { + FastBitmapDrawable icon = ((BubbleTextView) child).getIcon(); + if (icon != null) { + iconScale = icon.getAnimatedScale(); + } + } + + // clear pressed state if necessary + child.clearFocus(); + child.setPressed(false); + if (child instanceof BubbleTextView) { + BubbleTextView icon = (BubbleTextView) child; + icon.clearPressedBackground(); + } + + DraggableView draggableView = null; + if (child instanceof DraggableView) { + draggableView = (DraggableView) child; + } + + final View contentView = previewProvider.getContentView(); + final float scale; + // The draggable drawable follows the touch point around on the screen + final Drawable drawable; + if (contentView == null) { + drawable = previewProvider.createDrawable(); + scale = previewProvider.getScaleAndPosition(drawable, mTempXY); + } else { + drawable = null; + scale = previewProvider.getScaleAndPosition(contentView, mTempXY); + } + int halfPadding = previewProvider.previewPadding / 2; + int dragLayerX = mTempXY[0]; + int dragLayerY = mTempXY[1]; + + Point dragVisualizeOffset = null; + Rect dragRect = new Rect(); + if (draggableView != null) { + draggableView.getSourceVisualDragBounds(dragRect); + dragLayerY += dragRect.top; + dragVisualizeOffset = new Point(-halfPadding, halfPadding); + } + if (contentView != null) { + mDragController.startDrag( + contentView, + draggableView, + dragLayerX, + dragLayerY, + source, + dragObject, + dragVisualizeOffset, + dragRect, + scale * iconScale, + scale, + options); + } else { + mDragController.startDrag( + drawable, + draggableView, + dragLayerX, + dragLayerY, + source, + dragObject, + dragVisualizeOffset, + dragRect, + scale * iconScale, + scale, + options); + } + } + + @Override + public void onDragStart(DropTarget.DragObject dragObject, DragOptions options) { } + + @Override + public void onDragEnd() { } } diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragController.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragController.java new file mode 100644 index 0000000000..9bf27642ef --- /dev/null +++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragController.java @@ -0,0 +1,194 @@ +/* + * Copyright (C) 2022 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.launcher3.secondarydisplay; + +import android.content.res.Resources; +import android.graphics.Point; +import android.graphics.Rect; +import android.graphics.drawable.Drawable; +import android.util.Log; +import android.view.HapticFeedbackConstants; +import android.view.View; + +import androidx.annotation.Nullable; + +import com.android.launcher3.AbstractFloatingView; +import com.android.launcher3.DragSource; +import com.android.launcher3.DropTarget; +import com.android.launcher3.R; +import com.android.launcher3.accessibility.DragViewStateAnnouncer; +import com.android.launcher3.dragndrop.DragController; +import com.android.launcher3.dragndrop.DragDriver; +import com.android.launcher3.dragndrop.DragOptions; +import com.android.launcher3.dragndrop.DragView; +import com.android.launcher3.dragndrop.DraggableView; +import com.android.launcher3.model.data.ItemInfo; +import com.android.launcher3.testing.shared.TestProtocol; + +/** + * Drag controller for Secondary Launcher activity + */ +public class SecondaryDragController extends DragController { + + private static final boolean PROFILE_DRAWING_DURING_DRAG = false; + + public SecondaryDragController(SecondaryDisplayLauncher secondaryLauncher) { + super(secondaryLauncher); + } + + @Override + protected DragView startDrag(@Nullable Drawable drawable, @Nullable View view, + DraggableView originalView, int dragLayerX, int dragLayerY, DragSource source, + ItemInfo dragInfo, Point dragOffset, Rect dragRegion, float initialDragViewScale, + float dragViewScaleOnDrop, DragOptions options) { + + if (TestProtocol.sDebugTracing) { + Log.d(TestProtocol.NO_DROP_TARGET, "5"); + } + + if (PROFILE_DRAWING_DURING_DRAG) { + android.os.Debug.startMethodTracing("Launcher"); + } + mActivity.hideKeyboard(); + + mOptions = options; + if (mOptions.simulatedDndStartPoint != null) { + mLastTouch.x = mMotionDown.x = mOptions.simulatedDndStartPoint.x; + mLastTouch.y = mMotionDown.y = mOptions.simulatedDndStartPoint.y; + } + + final int registrationX = mMotionDown.x - dragLayerX; + final int registrationY = mMotionDown.y - dragLayerY; + + final int dragRegionLeft = dragRegion == null ? 0 : dragRegion.left; + final int dragRegionTop = dragRegion == null ? 0 : dragRegion.top; + + mLastDropTarget = null; + + mDragObject = new DropTarget.DragObject(mActivity.getApplicationContext()); + mDragObject.originalView = originalView; + + mIsInPreDrag = mOptions.preDragCondition != null + && !mOptions.preDragCondition.shouldStartDrag(0); + + final Resources res = mActivity.getResources(); + final float scaleDps = mIsInPreDrag + ? res.getDimensionPixelSize(R.dimen.pre_drag_view_scale) : 0f; + + final DragView dragView = mDragObject.dragView = drawable != null + ? new SecondaryDragView( + mActivity, + drawable, + registrationX, + registrationY, + initialDragViewScale, + dragViewScaleOnDrop, + scaleDps) + : new SecondaryDragView( + mActivity, + view, + view.getMeasuredWidth(), + view.getMeasuredHeight(), + registrationX, + registrationY, + initialDragViewScale, + dragViewScaleOnDrop, + scaleDps); + dragView.setItemInfo(dragInfo); + mDragObject.dragComplete = false; + + mDragObject.xOffset = mMotionDown.x - (dragLayerX + dragRegionLeft); + mDragObject.yOffset = mMotionDown.y - (dragLayerY + dragRegionTop); + + mDragDriver = DragDriver.create(this, mOptions, ev -> { + }); + if (!mOptions.isAccessibleDrag) { + mDragObject.stateAnnouncer = DragViewStateAnnouncer.createFor(dragView); + } + + mDragObject.dragSource = source; + mDragObject.dragInfo = dragInfo; + mDragObject.originalDragInfo = mDragObject.dragInfo.makeShallowCopy(); + + if (dragOffset != null) { + dragView.setDragVisualizeOffset(new Point(dragOffset)); + } + if (dragRegion != null) { + dragView.setDragRegion(new Rect(dragRegion)); + } + + mActivity.getDragLayer().performHapticFeedback(HapticFeedbackConstants.LONG_PRESS); + dragView.show(mLastTouch.x, mLastTouch.y); + mDistanceSinceScroll = 0; + + if (!mIsInPreDrag) { + callOnDragStart(); + } else if (mOptions.preDragCondition != null) { + mOptions.preDragCondition.onPreDragStart(mDragObject); + } + + handleMoveEvent(mLastTouch.x, mLastTouch.y); + return dragView; + } + + @Override + protected void exitDrag() { } + + @Override + protected DropTarget getDefaultDropTarget(int[] dropCoordinates) { + DropTarget target = new DropTarget() { + @Override + public boolean isDropEnabled() { + return true; + } + + @Override + public void onDrop(DragObject dragObject, DragOptions options) { + ((SecondaryDragLayer) mActivity.getDragLayer()).getPinnedAppsAdapter().addPinnedApp( + dragObject.dragInfo); + dragObject.dragView.remove(); + } + + @Override + public void onDragEnter(DragObject dragObject) { + if (getDistanceDragged() > mActivity.getResources().getDimensionPixelSize( + R.dimen.drag_distanceThreshold)) { + mActivity.showAppDrawer(false); + AbstractFloatingView.closeAllOpenViews(mActivity); + } + } + + @Override + public void onDragOver(DragObject dragObject) { } + + @Override + public void onDragExit(DragObject dragObject) { } + + @Override + public boolean acceptDrop(DragObject dragObject) { + return true; + } + + @Override + public void prepareAccessibilityDrop() { } + + @Override + public void getHitRectRelativeToDragLayer(Rect outRect) { } + }; + return target; + } +} diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java index c79d70dacc..42d597044e 100644 --- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java +++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java @@ -29,8 +29,12 @@ import android.widget.GridView; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BubbleTextView; import com.android.launcher3.DeviceProfile; +import com.android.launcher3.DropTarget; import com.android.launcher3.R; import com.android.launcher3.allapps.ActivityAllAppsContainerView; +import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.dragndrop.DragOptions; +import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.popup.PopupContainerWithArrow; import com.android.launcher3.popup.PopupDataProvider; @@ -59,7 +63,8 @@ public class SecondaryDragLayer extends BaseDragLayer @Override public void recreateControllers() { - mControllers = new TouchController[] {new CloseAllAppsTouchController()}; + mControllers = new TouchController[]{new CloseAllAppsTouchController(), + mActivity.getDragController()}; } /** @@ -166,6 +171,10 @@ public class SecondaryDragLayer extends BaseDragLayer } } + public PinnedAppsAdapter getPinnedAppsAdapter() { + return mPinnedAppsAdapter; + } + private boolean onIconLongClicked(View v) { if (!(v instanceof BubbleTextView)) { return false; @@ -183,6 +192,7 @@ public class SecondaryDragLayer extends BaseDragLayer if (popupDataProvider == null) { return false; } + final PopupContainerWithArrow container = (PopupContainerWithArrow) mActivity.getLayoutInflater().inflate( R.layout.popup_container, mActivity.getDragLayer(), false); @@ -192,7 +202,42 @@ public class SecondaryDragLayer extends BaseDragLayer Collections.emptyList(), Arrays.asList(mPinnedAppsAdapter.getSystemShortcut(item, v), APP_INFO.getShortcut(mActivity, item, v))); - v.getParent().requestDisallowInterceptTouchEvent(true); + container.requestFocus(); + + if (!FeatureFlags.SECONDARY_DRAG_N_DROP_TO_PIN.get() || !mActivity.isAppDrawerShown()) { + return true; + } + + DragOptions options = new DragOptions(); + DeviceProfile grid = mActivity.getDeviceProfile(); + options.intrinsicIconScaleFactor = (float) grid.allAppsIconSizePx / grid.iconSizePx; + options.preDragCondition = container.createPreDragCondition(false); + if (options.preDragCondition == null) { + options.preDragCondition = new DragOptions.PreDragCondition() { + private DragView mDragView; + + @Override + public boolean shouldStartDrag(double distanceDragged) { + return mDragView != null && mDragView.isAnimationFinished(); + } + + @Override + public void onPreDragStart(DropTarget.DragObject dragObject) { + mDragView = dragObject.dragView; + if (!shouldStartDrag(0)) { + mDragView.setOnAnimationEndCallback(() -> { + mActivity.beginDragShared(v, mActivity.getAppsView(), options); + }); + } + } + + @Override + public void onPreDragEnd(DropTarget.DragObject dragObject, boolean dragStarted) { + mDragView = null; + } + }; + } + mActivity.beginDragShared(v, mActivity.getAppsView(), options); return true; } } diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragView.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragView.java new file mode 100644 index 0000000000..0168b8fc0d --- /dev/null +++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragView.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2022 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.launcher3.secondarydisplay; + +import android.graphics.drawable.Drawable; +import android.view.View; + +import com.android.launcher3.R; +import com.android.launcher3.dragndrop.DragView; + +/** + * A DragView drawn/used by the Secondary Launcher activity. + */ +public class SecondaryDragView extends DragView { + + public SecondaryDragView(SecondaryDisplayLauncher launcher, + Drawable drawable, + int registrationX, int registrationY, float initialScale, float scaleOnDrop, + float finalScaleDps) { + super(launcher, drawable, registrationX, registrationY, initialScale, scaleOnDrop, + finalScaleDps); + } + + public SecondaryDragView(SecondaryDisplayLauncher launcher, View content, int width, int height, + int registrationX, int registrationY, float initialScale, float scaleOnDrop, + float finalScaleDps) { + super(launcher, content, width, height, registrationX, registrationY, initialScale, + scaleOnDrop, finalScaleDps); + } + + @Override + public void animateTo(int toTouchX, int toTouchY, Runnable onCompleteRunnable, int duration) { + Runnable onAnimationEnd = () -> { + if (onCompleteRunnable != null) { + onCompleteRunnable.run(); + } + mActivity.getDragLayer().removeView(this); + }; + + duration = Math.max(duration, + getResources().getInteger(R.integer.config_dropAnimMinDuration)); + + animate() + .translationX(toTouchX - mRegistrationX) + .translationY(toTouchY - mRegistrationY) + .scaleX(mScaleOnDrop) + .scaleY(mScaleOnDrop) + .withEndAction(onAnimationEnd) + .setDuration(duration) + .start(); + } +} From 9ca77448773dbe6c35a25d00ec3c05732d267fb0 Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Thu, 20 Oct 2022 00:40:01 +0000 Subject: [PATCH 093/429] Remove redundant createAdapter override. It is the same as ActivityAllAppsContainerView#createAdapter, so it can be cleaned up. Test: Manual Fix: 254545341 Change-Id: Ib23369a53c8c0a1f8f05b671526eb82a07b6f0e3 --- .../taskbar/allapps/TaskbarAllAppsContainerView.java | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java index ce51f7dc71..e41c75fea0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java @@ -20,10 +20,6 @@ import android.util.AttributeSet; import android.view.WindowInsets; import com.android.launcher3.allapps.ActivityAllAppsContainerView; -import com.android.launcher3.allapps.AllAppsGridAdapter; -import com.android.launcher3.allapps.AlphabeticalAppsList; -import com.android.launcher3.allapps.BaseAdapterProvider; -import com.android.launcher3.allapps.BaseAllAppsAdapter; import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; /** All apps container accessible from taskbar. */ @@ -43,12 +39,4 @@ public class TaskbarAllAppsContainerView extends setInsets(insets.getInsets(WindowInsets.Type.systemBars()).toRect()); return super.onApplyWindowInsets(insets); } - - @Override - protected BaseAllAppsAdapter createAdapter( - AlphabeticalAppsList appsList, - BaseAdapterProvider[] adapterProviders) { - return new AllAppsGridAdapter<>(mActivityContext, getLayoutInflater(), appsList, - adapterProviders); - } } From 981034687a989fecf144580fc41b93a231be4f0a Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Tue, 18 Oct 2022 21:11:51 -0700 Subject: [PATCH 094/429] Scale screenWidth for split proportionally for thumbnail matrix * Instead of passing in screenWidth to be that of entire screen when using split, scale screenWidth to that of only the amount that the given split app is taking. * Created TODO(b/254378592) to consolidate different SplitBounds classes Fixes: 250817893 Test: Checked phone/tablet swiping quickswitching portrait and landscape Change-Id: I5c3b2076110e358366284b2c794fd8df8a79f034 --- .../quickstep/util/TaskViewSimulator.java | 12 ++++++++++++ .../quickstep/views/GroupedTaskView.java | 18 ++++++++++++++++-- .../util/SplitConfigurationOptions.java | 1 + 3 files changed, 29 insertions(+), 2 deletions(-) diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java index c03aa3f446..a991bf19ff 100644 --- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java +++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java @@ -191,6 +191,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { mStagePosition = mThumbnailPosition.equals(splitInfo.leftTopBounds) ? STAGE_POSITION_TOP_OR_LEFT : STAGE_POSITION_BOTTOM_OR_RIGHT; + mPositionHelper.setSplitBounds(convertSplitBounds(mSplitBounds), mStagePosition); } /** @@ -418,4 +419,15 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { return Math.max(Math.abs(mTempPoint[0]), Math.abs(mTempPoint[1])); } + /** + * TODO(b/254378592): Remove this after consolidation of classes + */ + public static com.android.wm.shell.util.SplitBounds convertSplitBounds(SplitBounds bounds) { + return new com.android.wm.shell.util.SplitBounds( + bounds.leftTopBounds, + bounds.rightBottomBounds, + bounds.leftTopTaskId, + bounds.rightBottomTaskId + ); + } } diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java index 71b0c60971..7b9d9cdcac 100644 --- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java +++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java @@ -19,6 +19,7 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.util.RunnableList; +import com.android.launcher3.util.SplitConfigurationOptions; import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds; import com.android.launcher3.util.TransformingTouchDelegate; import com.android.quickstep.RecentsModel; @@ -26,8 +27,10 @@ import com.android.quickstep.TaskIconCache; import com.android.quickstep.TaskThumbnailCache; import com.android.quickstep.util.CancellableTask; import com.android.quickstep.util.RecentsOrientedState; +import com.android.quickstep.util.TaskViewSimulator; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.recents.model.ThumbnailData; +import com.android.systemui.shared.recents.utilities.PreviewPositionHelper; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import java.util.HashMap; @@ -86,9 +89,19 @@ public class GroupedTaskView extends TaskView { mTaskIdContainer[1] = secondary.key.id; mTaskIdAttributeContainer[1] = new TaskIdAttributeContainer(secondary, mSnapshotView2, mIconView2, STAGE_POSITION_BOTTOM_OR_RIGHT); - mTaskIdAttributeContainer[0].setStagePosition(STAGE_POSITION_TOP_OR_LEFT); + mTaskIdAttributeContainer[0].setStagePosition( + SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT); mSnapshotView2.bind(secondary); mSplitBoundsConfig = splitBoundsConfig; + if (mSplitBoundsConfig == null) { + return; + } + mSnapshotView.getPreviewPositionHelper().setSplitBounds(TaskViewSimulator + .convertSplitBounds(splitBoundsConfig), + PreviewPositionHelper.STAGE_POSITION_TOP_OR_LEFT); + mSnapshotView2.getPreviewPositionHelper().setSplitBounds(TaskViewSimulator + .convertSplitBounds(splitBoundsConfig), + PreviewPositionHelper.STAGE_POSITION_BOTTOM_OR_RIGHT); } @Override @@ -207,7 +220,8 @@ public class GroupedTaskView extends TaskView { @Override public void launchTask(@NonNull Consumer callback, boolean freezeTaskList) { getRecentsView().getSplitSelectController().launchTasks(mTask.key.id, mSecondaryTask.key.id, - STAGE_POSITION_TOP_OR_LEFT, callback, freezeTaskList, getSplitRatio()); + SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT, callback, freezeTaskList, + getSplitRatio()); } @Override diff --git a/src/com/android/launcher3/util/SplitConfigurationOptions.java b/src/com/android/launcher3/util/SplitConfigurationOptions.java index 88e1b22bab..3eff783586 100644 --- a/src/com/android/launcher3/util/SplitConfigurationOptions.java +++ b/src/com/android/launcher3/util/SplitConfigurationOptions.java @@ -100,6 +100,7 @@ public final class SplitConfigurationOptions { * with the same name/functionality in wm.shell.util (which launcher3 cannot be built against) * * If you make changes here, consider making the same changes there + * TODO(b/254378592): We really need to consolidate this */ public static class SplitBounds { public final Rect leftTopBounds; From 0fb921ef36a91cb25bd22d8b0809eabbd550490c Mon Sep 17 00:00:00 2001 From: Tony Huang Date: Wed, 19 Oct 2022 08:48:45 +0000 Subject: [PATCH 095/429] Snapshot 2 tasks when swipe up split case Swipe up snapshot only capture the top one task, but for split screen case it should capture two tasks otherwise the snapshot in overview would be empty in some cases. Fix: 247420799 Test: manual Test: pass existing tests Change-Id: I3acd477eaca3cb98d86e2446dbb2dbd6295c687d --- .../src/com/android/quickstep/AbsSwipeUpHandler.java | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 07ddcc8b31..7021e643fa 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -1835,6 +1835,17 @@ public abstract class AbsSwipeUpHandler, if (mRecentsAnimationController == null) return; final ThumbnailData taskSnapshot = mRecentsAnimationController.screenshotTask(runningTaskId); + // If split case, we should update all split tasks snapshot + if (mIsSwipeForSplit) { + int[] splitTaskIds = TopTaskTracker.INSTANCE.get( + mContext).getRunningSplitTaskIds(); + for (int i = 0; i < splitTaskIds.length; i++) { + // Skip running one because done above. + if (splitTaskIds[i] == runningTaskId) continue; + + mRecentsAnimationController.screenshotTask(splitTaskIds[i]); + } + } MAIN_EXECUTOR.execute(() -> { mTaskSnapshot = taskSnapshot; if (!updateThumbnail(runningTaskId, false /* refreshView */)) { From a64a914ddf4370f96909a48c40f6c7de35bd08b5 Mon Sep 17 00:00:00 2001 From: Thales Lima Date: Tue, 18 Oct 2022 18:30:43 +0100 Subject: [PATCH 096/429] Calculate taskbar content size for edu Using the value calculated in layout was not working because TaskbarView onLayout() was being called after TaskbarEduView onMeasure(). Now uses the same value on all orientations based on taskbar icon size. Fixes: 252945031 Test: manual Change-Id: Ib6914901638c82f3b3ec4c9b86f6c20e84d34d0f --- .../taskbar/TaskbarEduController.java | 2 +- .../android/launcher3/taskbar/TaskbarView.java | 18 +++++++++++++----- .../taskbar/TaskbarViewController.java | 4 ++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java index 95b93febe0..2c2416170d 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java @@ -222,7 +222,7 @@ public class TaskbarEduController implements TaskbarControllers.LoggableTaskbarC } int getIconLayoutBoundsWidth() { - return mControllers.taskbarViewController.getIconLayoutBounds().width(); + return mControllers.taskbarViewController.getIconLayoutWidth(); } } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java index bb82d19734..1bddcca835 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java @@ -321,12 +321,8 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { int count = getChildCount(); - int countExcludingQsb = count; DeviceProfile deviceProfile = mActivityContext.getDeviceProfile(); - if (deviceProfile.isQsbInline) { - countExcludingQsb--; - } - int spaceNeeded = countExcludingQsb * (mItemMarginLeftRight * 2 + mIconTouchSize); + int spaceNeeded = getIconLayoutWidth(); int navSpaceNeeded = deviceProfile.hotseatBarEndOffset; boolean layoutRtl = isLayoutRtl(); int iconEnd = right - (right - left - spaceNeeded) / 2; @@ -416,6 +412,18 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar return mIconLayoutBounds; } + /** + * Returns the space used by the icons + */ + public int getIconLayoutWidth() { + int countExcludingQsb = getChildCount(); + DeviceProfile deviceProfile = mActivityContext.getDeviceProfile(); + if (deviceProfile.isQsbInline) { + countExcludingQsb--; + } + return countExcludingQsb * (mItemMarginLeftRight * 2 + mIconTouchSize); + } + /** * Returns the app icons currently shown in the taskbar. */ diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 16dd90db29..1530ce121a 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -193,6 +193,10 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar return mTaskbarView.getIconLayoutBounds(); } + public int getIconLayoutWidth() { + return mTaskbarView.getIconLayoutWidth(); + } + public View[] getIconViews() { return mTaskbarView.getIconViews(); } From ed8c69bacad42ea625912fda11df8d521f6121ff Mon Sep 17 00:00:00 2001 From: Thales Lima Date: Wed, 17 Aug 2022 12:21:21 -0400 Subject: [PATCH 097/429] Make all handheld grids scalable Also increase the icon size in the XML until the icon is sized correctly. Fix: 239419094 Bug: 235886078 Test: manual Change-Id: I0c7d75181a61177cc5993ba7002c3ccc8fd60fbf --- src/com/android/launcher3/InvariantDeviceProfile.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 6a262c3f91..a8d371eebd 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -1027,7 +1027,7 @@ public class InvariantDeviceProfile { R.styleable.ProfileDisplayOption_allAppsIconSize, iconSizes[INDEX_DEFAULT]); allAppsIconSizes[INDEX_LANDSCAPE] = a.getFloat( R.styleable.ProfileDisplayOption_allAppsIconSizeLandscape, - iconSizes[INDEX_DEFAULT]); + allAppsIconSizes[INDEX_DEFAULT]); allAppsIconSizes[INDEX_TWO_PANEL_PORTRAIT] = a.getFloat( R.styleable.ProfileDisplayOption_allAppsIconSizeTwoPanelPortrait, allAppsIconSizes[INDEX_DEFAULT]); From fc1928e32416de704948a14fac1cca5d17873b61 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Fri, 23 Sep 2022 14:33:59 -0700 Subject: [PATCH 098/429] Optimizing some icon generation code: 1) Fixing missing shadow from shortcut icons 2) Chaning all-apps icon rendering to draw background/foreground separately This allows us to reuse the bitmap generated for themed icons, instead of creating a new everytime Bug: 248308987 Test: Verified on device Change-Id: Ia3cbefb21a2ce676d6bb2df3d9375d61b5bed61b --- .../res/drawable/ic_floating_task_button.xml | 20 ++-- .../res/layout/taskbar_all_apps_button.xml | 23 +++++ .../layout/taskbar_floating_task_button.xml | 21 +++++ .../taskbar/LaunchFloatingTaskButton.java | 51 ---------- .../launcher3/taskbar/TaskbarView.java | 16 ++-- res/drawable/ic_all_apps_button.xml | 48 +++++----- res/values/attrs.xml | 6 -- res/values/styles.xml | 8 -- .../launcher3/icons/ShortcutCachingLogic.java | 3 +- .../launcher3/views/AllAppsButton.java | 50 ---------- .../launcher3/views/IconButtonView.java | 94 +++++++++++++++++++ .../widget/PendingItemDragHelper.java | 4 +- 12 files changed, 187 insertions(+), 157 deletions(-) create mode 100644 quickstep/res/layout/taskbar_all_apps_button.xml create mode 100644 quickstep/res/layout/taskbar_floating_task_button.xml delete mode 100644 quickstep/src/com/android/launcher3/taskbar/LaunchFloatingTaskButton.java delete mode 100644 src/com/android/launcher3/views/AllAppsButton.java create mode 100644 src/com/android/launcher3/views/IconButtonView.java diff --git a/quickstep/res/drawable/ic_floating_task_button.xml b/quickstep/res/drawable/ic_floating_task_button.xml index e50f65cee7..63b2fd85b7 100644 --- a/quickstep/res/drawable/ic_floating_task_button.xml +++ b/quickstep/res/drawable/ic_floating_task_button.xml @@ -19,11 +19,17 @@ android:height="24dp" android:viewportWidth="24" android:viewportHeight="24"> - - + + + + diff --git a/quickstep/res/layout/taskbar_all_apps_button.xml b/quickstep/res/layout/taskbar_all_apps_button.xml new file mode 100644 index 0000000000..b275305da4 --- /dev/null +++ b/quickstep/res/layout/taskbar_all_apps_button.xml @@ -0,0 +1,23 @@ + + + diff --git a/quickstep/res/layout/taskbar_floating_task_button.xml b/quickstep/res/layout/taskbar_floating_task_button.xml new file mode 100644 index 0000000000..b5beded54a --- /dev/null +++ b/quickstep/res/layout/taskbar_floating_task_button.xml @@ -0,0 +1,21 @@ + + + diff --git a/quickstep/src/com/android/launcher3/taskbar/LaunchFloatingTaskButton.java b/quickstep/src/com/android/launcher3/taskbar/LaunchFloatingTaskButton.java deleted file mode 100644 index b15669b5ef..0000000000 --- a/quickstep/src/com/android/launcher3/taskbar/LaunchFloatingTaskButton.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * Copyright (C) 2022 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.launcher3.taskbar; - -import android.content.Context; -import android.graphics.Bitmap; -import android.util.AttributeSet; -import android.view.ContextThemeWrapper; - -import com.android.launcher3.BubbleTextView; -import com.android.launcher3.LauncherAppState; -import com.android.launcher3.R; -import com.android.launcher3.icons.FastBitmapDrawable; - -/** - * Button in Taskbar that opens something in a floating task. - */ -public class LaunchFloatingTaskButton extends BubbleTextView { - - public LaunchFloatingTaskButton(Context context) { - this(context, null); - } - - public LaunchFloatingTaskButton(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public LaunchFloatingTaskButton(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - Context theme = new ContextThemeWrapper(context, R.style.AllAppsButtonTheme); - Bitmap bitmap = LauncherAppState.getInstance(context).getIconCache().getIconFactory() - .createScaledBitmapWithShadow( - theme.getDrawable(R.drawable.ic_floating_task_button)); - setIcon(new FastBitmapDrawable(bitmap)); - } -} diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java index bb82d19734..31c2132888 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java @@ -26,7 +26,6 @@ import android.util.Log; import android.view.LayoutInflater; import android.view.MotionEvent; import android.view.View; -import android.view.ViewGroup; import android.widget.FrameLayout; import androidx.annotation.LayoutRes; @@ -47,7 +46,6 @@ import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.util.LauncherBindableItemsContainer; import com.android.launcher3.views.ActivityContext; -import com.android.launcher3.views.AllAppsButton; import com.android.launcher3.views.DoubleShadowBubbleTextView; import java.util.function.Predicate; @@ -81,12 +79,12 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar private @Nullable FolderIcon mLeaveBehindFolderIcon; // Only non-null when device supports having an All Apps button. - private @Nullable AllAppsButton mAllAppsButton; + private @Nullable View mAllAppsButton; private View mQsb; // Only non-null when device supports having a floating task. - private @Nullable BubbleTextView mFloatingTaskButton; + private @Nullable View mFloatingTaskButton; private @Nullable Intent mFloatingTaskIntent; private static final boolean FLOATING_TASKS_ENABLED = SystemProperties.getBoolean("persist.wm.debug.floating_tasks", false); @@ -125,9 +123,8 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar mThemeIconsBackground = calculateThemeIconsBackground(); if (FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) { - mAllAppsButton = new AllAppsButton(context); - mAllAppsButton.setLayoutParams( - new ViewGroup.LayoutParams(mIconTouchSize, mIconTouchSize)); + mAllAppsButton = LayoutInflater.from(context) + .inflate(R.layout.taskbar_all_apps_button, this, false); mAllAppsButton.setPadding(mItemPadding, mItemPadding, mItemPadding, mItemPadding); } @@ -137,9 +134,8 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar if (FLOATING_TASKS_ENABLED) { mFloatingTaskIntent = FloatingTaskIntentResolver.getIntent(context); if (mFloatingTaskIntent != null) { - mFloatingTaskButton = new LaunchFloatingTaskButton(context); - mFloatingTaskButton.setLayoutParams( - new ViewGroup.LayoutParams(mIconTouchSize, mIconTouchSize)); + mFloatingTaskButton = LayoutInflater.from(context) + .inflate(R.layout.taskbar_floating_task_button, this, false); mFloatingTaskButton.setPadding(mItemPadding, mItemPadding, mItemPadding, mItemPadding); } else { diff --git a/res/drawable/ic_all_apps_button.xml b/res/drawable/ic_all_apps_button.xml index 5770d3cf19..7de390ac4a 100644 --- a/res/drawable/ic_all_apps_button.xml +++ b/res/drawable/ic_all_apps_button.xml @@ -18,27 +18,29 @@ android:width="80dp" android:height="80dp" android:viewportWidth="80" - android:viewportHeight="80" - android:theme="@style/AllAppsTheme"> - - - - - - - + android:viewportHeight="80"> + + + + + + + + diff --git a/res/values/attrs.xml b/res/values/attrs.xml index 862341400f..283c793e26 100644 --- a/res/values/attrs.xml +++ b/res/values/attrs.xml @@ -56,12 +56,6 @@ - - - - - - diff --git a/res/values/styles.xml b/res/values/styles.xml index 90553a160e..d0be420a1a 100644 --- a/res/values/styles.xml +++ b/res/values/styles.xml @@ -207,14 +207,6 @@ no - - diff --git a/src/com/android/launcher3/icons/ShortcutCachingLogic.java b/src/com/android/launcher3/icons/ShortcutCachingLogic.java index d5a79dde08..26ddc0bed7 100644 --- a/src/com/android/launcher3/icons/ShortcutCachingLogic.java +++ b/src/com/android/launcher3/icons/ShortcutCachingLogic.java @@ -76,7 +76,8 @@ public class ShortcutCachingLogic implements CachingLogic { Drawable unbadgedDrawable = ShortcutCachingLogic.getIcon( context, info, LauncherAppState.getIDP(context).fillResIconDpi); if (unbadgedDrawable == null) return BitmapInfo.LOW_RES_INFO; - return new BitmapInfo(li.createScaledBitmapWithoutShadow(unbadgedDrawable), + return new BitmapInfo( + li.createScaledBitmap(unbadgedDrawable, BaseIconFactory.MODE_WITH_SHADOW), Themes.getColorAccent(context)); } } diff --git a/src/com/android/launcher3/views/AllAppsButton.java b/src/com/android/launcher3/views/AllAppsButton.java deleted file mode 100644 index ab8e5dbff6..0000000000 --- a/src/com/android/launcher3/views/AllAppsButton.java +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (C) 2022 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.launcher3.views; - -import android.content.Context; -import android.graphics.Bitmap; -import android.util.AttributeSet; -import android.view.ContextThemeWrapper; - -import com.android.launcher3.BubbleTextView; -import com.android.launcher3.LauncherAppState; -import com.android.launcher3.R; -import com.android.launcher3.icons.FastBitmapDrawable; - -/** - * Button in Taskbar that opens All Apps. - */ -public class AllAppsButton extends BubbleTextView { - - public AllAppsButton(Context context) { - this(context, null); - } - - public AllAppsButton(Context context, AttributeSet attrs) { - this(context, attrs, 0); - } - - public AllAppsButton(Context context, AttributeSet attrs, int defStyle) { - super(context, attrs, defStyle); - - Context theme = new ContextThemeWrapper(context, R.style.AllAppsButtonTheme); - Bitmap bitmap = LauncherAppState.getInstance(context).getIconCache().getIconFactory() - .createScaledBitmapWithShadow(theme.getDrawable(R.drawable.ic_all_apps_button)); - setIcon(new FastBitmapDrawable(bitmap)); - setContentDescription(context.getString(R.string.all_apps_button_label)); - } -} diff --git a/src/com/android/launcher3/views/IconButtonView.java b/src/com/android/launcher3/views/IconButtonView.java new file mode 100644 index 0000000000..dd48c99c7d --- /dev/null +++ b/src/com/android/launcher3/views/IconButtonView.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2022 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.launcher3.views; + +import android.annotation.TargetApi; +import android.content.Context; +import android.content.res.ColorStateList; +import android.content.res.TypedArray; +import android.graphics.Bitmap; +import android.graphics.BlendMode; +import android.graphics.BlendModeColorFilter; +import android.graphics.Canvas; +import android.graphics.Color; +import android.graphics.Rect; +import android.graphics.drawable.ColorDrawable; +import android.graphics.drawable.Drawable; +import android.os.Build; +import android.util.AttributeSet; + +import com.android.launcher3.BubbleTextView; +import com.android.launcher3.icons.BaseIconFactory; +import com.android.launcher3.icons.FastBitmapDrawable; +import com.android.launcher3.icons.LauncherIcons; + +/** + * Button in Taskbar that shows a tinted background and foreground. + */ +public class IconButtonView extends BubbleTextView { + + private static final int[] ATTRS = {android.R.attr.icon}; + + public IconButtonView(Context context) { + this(context, null); + } + + public IconButtonView(Context context, AttributeSet attrs) { + this(context, attrs, 0); + } + + public IconButtonView(Context context, AttributeSet attrs, int defStyle) { + super(context, attrs, defStyle); + + TypedArray a = context.obtainStyledAttributes(attrs, ATTRS, defStyle, 0); + Drawable fg = a.getDrawable(0); + a.recycle(); + + ColorStateList tintList = getBackgroundTintList(); + int tint = tintList == null ? Color.WHITE : tintList.getDefaultColor(); + + if (fg == null) { + fg = new ColorDrawable(Color.TRANSPARENT); + } + try (BaseIconFactory factory = LauncherIcons.obtain(context)) { + setIcon(new IconDrawable(factory.getWhiteShadowLayer(), tint, fg)); + } + } + + private static class IconDrawable extends FastBitmapDrawable { + + private final Drawable mFg; + + @TargetApi(Build.VERSION_CODES.TIRAMISU) + IconDrawable(Bitmap b, int colorBg, Drawable fg) { + super(b); + mPaint.setColorFilter(new BlendModeColorFilter(colorBg, BlendMode.SRC_IN)); + mFg = fg; + } + + @Override + protected void drawInternal(Canvas canvas, Rect bounds) { + super.drawInternal(canvas, bounds); + mFg.draw(canvas); + } + + @Override + protected void onBoundsChange(Rect bounds) { + super.onBoundsChange(bounds); + mFg.setBounds(bounds); + } + } +} diff --git a/src/com/android/launcher3/widget/PendingItemDragHelper.java b/src/com/android/launcher3/widget/PendingItemDragHelper.java index c8d528b8e8..bbbc329c9c 100644 --- a/src/com/android/launcher3/widget/PendingItemDragHelper.java +++ b/src/com/android/launcher3/widget/PendingItemDragHelper.java @@ -39,6 +39,7 @@ import com.android.launcher3.R; import com.android.launcher3.dragndrop.DragOptions; import com.android.launcher3.dragndrop.DraggableView; import com.android.launcher3.graphics.DragPreviewProvider; +import com.android.launcher3.icons.BaseIconFactory; import com.android.launcher3.icons.FastBitmapDrawable; import com.android.launcher3.icons.LauncherIcons; import com.android.launcher3.icons.RoundDrawableWrapper; @@ -181,7 +182,8 @@ public class PendingItemDragHelper extends DragPreviewProvider { PendingAddShortcutInfo createShortcutInfo = (PendingAddShortcutInfo) mAddInfo; Drawable icon = createShortcutInfo.activityInfo.getFullResIcon(app.getIconCache()); LauncherIcons li = LauncherIcons.obtain(launcher); - preview = new FastBitmapDrawable(li.createScaledBitmapWithoutShadow(icon)); + preview = new FastBitmapDrawable( + li.createScaledBitmap(icon, BaseIconFactory.MODE_DEFAULT)); previewWidth = preview.getIntrinsicWidth(); previewHeight = preview.getIntrinsicHeight(); li.recycle(); From aee55077cc128d3f974e31b443d8ce870dc12093 Mon Sep 17 00:00:00 2001 From: Sukesh Ram Date: Tue, 19 Jul 2022 15:05:35 -0700 Subject: [PATCH 099/429] Fix crash on long press of prediction row icons Changed icon long click listener to use secondary display's long click listener instead of launcher's. Bug: 239616635 Test: Manual Change-Id: I9a4679ba82cacb5e2648481274876dbfc95d80ce Merged-In: I9a4679ba82cacb5e2648481274876dbfc95d80ce --- .../SecondaryDisplayPredictionsImpl.java | 21 +++++++++++++++---- .../SecondaryDisplayLauncher.java | 4 ++++ .../SecondaryDisplayPredictions.java | 10 +++++++++ .../secondarydisplay/SecondaryDragLayer.java | 3 ++- 4 files changed, 33 insertions(+), 5 deletions(-) diff --git a/quickstep/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictionsImpl.java b/quickstep/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictionsImpl.java index 5bf727a60b..8720bd8f26 100644 --- a/quickstep/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictionsImpl.java +++ b/quickstep/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictionsImpl.java @@ -18,7 +18,9 @@ package com.android.launcher3.secondarydisplay; import static com.android.launcher3.util.OnboardingPrefs.ALL_APPS_VISITED_COUNT; import android.content.Context; +import android.view.View; +import com.android.launcher3.allapps.ActivityAllAppsContainerView; import com.android.launcher3.appprediction.AppsDividerView; import com.android.launcher3.appprediction.PredictionRowView; import com.android.launcher3.model.BgDataModel; @@ -39,10 +41,13 @@ public final class SecondaryDisplayPredictionsImpl extends SecondaryDisplayPredi @Override void updateAppDivider() { OnboardingPrefs onboardingPrefs = mActivityContext.getOnboardingPrefs(); - mActivityContext.getAppsView().getFloatingHeaderView() - .findFixedRowByType(AppsDividerView.class) - .setShowAllAppsLabel(!onboardingPrefs.hasReachedMaxCount(ALL_APPS_VISITED_COUNT)); - onboardingPrefs.incrementEventCount(ALL_APPS_VISITED_COUNT); + if (onboardingPrefs != null) { + mActivityContext.getAppsView().getFloatingHeaderView() + .findFixedRowByType(AppsDividerView.class) + .setShowAllAppsLabel( + !onboardingPrefs.hasReachedMaxCount(ALL_APPS_VISITED_COUNT)); + onboardingPrefs.incrementEventCount(ALL_APPS_VISITED_COUNT); + } } @Override @@ -51,4 +56,12 @@ public final class SecondaryDisplayPredictionsImpl extends SecondaryDisplayPredi .findFixedRowByType(PredictionRowView.class) .setPredictedApps(item.items); } + + @Override + public void setLongClickListener(ActivityAllAppsContainerView appsView, + View.OnLongClickListener onIconLongClickListener) { + appsView.getFloatingHeaderView() + .findFixedRowByType(PredictionRowView.class) + .setOnIconLongClickListener(onIconLongClickListener); + } } diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java index 1bea5908e8..7b32d8b749 100644 --- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java +++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java @@ -303,6 +303,10 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity } } + public SecondaryDisplayPredictions getSecondaryDisplayPredictions() { + return mSecondaryDisplayPredictions; + } + @Override public StringCache getStringCache() { return mStringCache; diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictions.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictions.java index a58916ad80..21c50d38e8 100644 --- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictions.java +++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayPredictions.java @@ -16,8 +16,10 @@ package com.android.launcher3.secondarydisplay; import android.content.Context; +import android.view.View; import com.android.launcher3.R; +import com.android.launcher3.allapps.ActivityAllAppsContainerView; import com.android.launcher3.model.BgDataModel; import com.android.launcher3.util.ResourceBasedOverride; @@ -45,4 +47,12 @@ public class SecondaryDisplayPredictions implements ResourceBasedOverride { */ public void setPredictedApps(BgDataModel.FixedContainerItems item) { } + + /** + * Set long click listener for predicted apps in top of app drawer. + */ + public void setLongClickListener( + ActivityAllAppsContainerView appsView, + View.OnLongClickListener onIconLongClickListener) { + } } diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java index 42d597044e..5eac01ef62 100644 --- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java +++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java @@ -77,7 +77,8 @@ public class SecondaryDragLayer extends BaseDragLayer mAppsView = findViewById(R.id.apps_view); mAppsView.setOnIconLongClickListener(this::onIconLongClicked); - + mActivity.getSecondaryDisplayPredictions() + .setLongClickListener(mAppsView, this::onIconLongClicked); // Setup workspace mWorkspace = findViewById(R.id.workspace_grid); mPinnedAppsAdapter = new PinnedAppsAdapter(mActivity, mAppsView.getAppsStore(), From c6d4df87f0c60e9838440379c7b7a184133b287b Mon Sep 17 00:00:00 2001 From: Sukesh Ram Date: Tue, 2 Aug 2022 16:59:39 -0700 Subject: [PATCH 100/429] Added Tests for Secondary Display Launcher These UIAutomator tests for secondary display launcher cover app drawer, drag-n-drop functionality, app predictions, pin/unpinning icons, and correct back press behavior. We are deviating from go/modify-tapl due to the time constraints of this project as outlined here (https://docs.google.com/document/d/1wLb2h8qCPGur-VsufCH4mLnnuLDLcmMq0FrCo7ichu8/edit#heading=h.brf6af3bno4g). A preliminary design document has also been created to reference for future TAPL integration (https://docs.google.com/document/d/1H642SSu5DCM_zSXTsvTWumgm3OHIxsKEXvTlTeC4y54/edit?resourcekey=0-M9sTxdyQBi8bUy5cpjmJNA#heading=h.90f2s4sc5ic9). Before TAPL integration, we need to follow up on test rewrite to eliminate antipatterns in the following bug: b/242776943. Bug: 241166788 Test: Run Locally, on presubmit, and on a test on a cuttlefish emulator Change-Id: I556a47b93a7ea3b2583dbc1efd2de7623d820e2a Merged-In: I556a47b93a7ea3b2583dbc1efd2de7623d820e2a --- .../secondarydisplay/SecondaryDragLayer.java | 16 +- .../SecondaryDisplayLauncherTest.java | 266 ++++++++++++++++-- 2 files changed, 262 insertions(+), 20 deletions(-) diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java index 5eac01ef62..c8455b8a2b 100644 --- a/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java +++ b/src/com/android/launcher3/secondarydisplay/SecondaryDragLayer.java @@ -38,12 +38,14 @@ import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.popup.PopupContainerWithArrow; import com.android.launcher3.popup.PopupDataProvider; +import com.android.launcher3.popup.SystemShortcut; import com.android.launcher3.util.ShortcutUtil; import com.android.launcher3.util.TouchController; import com.android.launcher3.views.BaseDragLayer; -import java.util.Arrays; +import java.util.ArrayList; import java.util.Collections; +import java.util.List; /** * DragLayer for Secondary launcher @@ -194,15 +196,21 @@ public class SecondaryDragLayer extends BaseDragLayer return false; } + List systemShortcuts = new ArrayList<>(); + + // Hide redundant pin shortcut for app drawer icons if drag-n-drop is enabled. + if (!FeatureFlags.SECONDARY_DRAG_N_DROP_TO_PIN.get() || !mActivity.isAppDrawerShown()) { + systemShortcuts.add(mPinnedAppsAdapter.getSystemShortcut(item, v)); + } + systemShortcuts.add(APP_INFO.getShortcut(mActivity, item, v)); + final PopupContainerWithArrow container = (PopupContainerWithArrow) mActivity.getLayoutInflater().inflate( R.layout.popup_container, mActivity.getDragLayer(), false); container.populateAndShow((BubbleTextView) v, popupDataProvider.getShortcutCountForItem(item), - Collections.emptyList(), - Arrays.asList(mPinnedAppsAdapter.getSystemShortcut(item, v), - APP_INFO.getShortcut(mActivity, item, v))); + Collections.emptyList(), systemShortcuts); container.requestFocus(); if (!FeatureFlags.SECONDARY_DRAG_N_DROP_TO_PIN.get() || !mActivity.isAppDrawerShown()) { diff --git a/tests/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncherTest.java b/tests/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncherTest.java index 93fa705880..082e243694 100644 --- a/tests/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncherTest.java +++ b/tests/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncherTest.java @@ -15,39 +15,273 @@ */ package com.android.launcher3.secondarydisplay; -import static androidx.test.core.app.ActivityScenario.launch; +import static android.content.Context.MODE_PRIVATE; +import static android.content.Intent.FLAG_ACTIVITY_NEW_TASK; +import static android.view.MotionEvent.ACTION_DOWN; + +import static com.google.common.truth.Truth.assertThat; + +import android.content.Context; +import android.content.Intent; +import android.graphics.Point; +import android.os.SystemClock; +import android.view.MotionEvent; +import android.widget.TextView; -import androidx.test.core.app.ActivityScenario; -import androidx.test.espresso.intent.Intents; import androidx.test.ext.junit.runners.AndroidJUnit4; -import androidx.test.filters.MediumTest; +import androidx.test.filters.LargeTest; +import androidx.test.uiautomator.By; +import androidx.test.uiautomator.UiObject2; +import androidx.test.uiautomator.Until; + +import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.tapl.LauncherInstrumentation; +import com.android.launcher3.ui.AbstractLauncherUiTest; +import com.android.launcher3.util.LauncherModelHelper; import org.junit.After; -import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; /** - * Tests for {@link SecondaryDisplayLauncher} + * Tests for {@link SecondaryDisplayLauncher}. + * TODO (b/242776943): Remove anti-patterns & migrate prediction row tests to Quickstep directory */ -@MediumTest +@LargeTest @RunWith(AndroidJUnit4.class) -public class SecondaryDisplayLauncherTest { +public final class SecondaryDisplayLauncherTest extends AbstractLauncherUiTest { + private static final int WAIT_TIME_MS = 5000; + private static final int LONG_PRESS_DURATION_MS = 1000; + private static final int DRAG_TIME_MS = 160; - @Before - public void setUp() { - Intents.init(); + private static final String PINNED_APPS_KEY = "pinned_apps"; + + // Variables required to coordinate drag steps. + private Point mStartPoint; + private Point mEndPoint; + private long mDownTime; + + @Override + public void setUp() throws Exception { + super.setUp(); + setDragNDropFlag(true); } @After public void tearDown() { - Intents.release(); + mTargetContext.getSharedPreferences(PINNED_APPS_KEY, MODE_PRIVATE) + .edit().clear().commit(); } @Test - public void testAllAppsListOpens() { - ActivityScenario launcher = - launch(SecondaryDisplayLauncher.class); - launcher.onActivity(l -> l.showAppDrawer(true)); + @Ignore + public void initializeSecondaryDisplayLauncher_allAppsButtonVisible() { + assertThat(findObjectByResourceName("all_apps_button")).isNotNull(); + } + + @Test + @Ignore + public void allAppsButtonTap_opensAppDrawer() { + openAppDrawer(); + assertThat(findObjectByResourceName("search_container_all_apps")).isNotNull(); + } + + @Test + @Ignore("Launcher3 without quickstep doesn't have a predictions row.") + public void appDrawerOpened_predictionRowAppDividerVisible() { + openAppDrawer(); + assertThat(findObjectByResourceName("apps_divider_view")).isNotNull(); + } + + @Test + @Ignore + public void dragNDropDisabled_pinIconAddsToWorkspace() { + setDragNDropFlag(false); + openAppDrawer(); + UiObject2 app = findDescendantByResourceName( + findObjectByResourceName("apps_list_view"), "icon"); + app.click(LONG_PRESS_DURATION_MS); + UiObject2 popupContainer = findObjectByResourceName("popup_container"); + assertThat(popupContainer).isNotNull(); + UiObject2 pinIcon = findDescendantByTextOrDesc(popupContainer, "Add to home screen"); + assertThat(pinIcon).isNotNull(); + pinIcon.click(); + String appName = app.getContentDescription(); + assertThat(findAppInWorkspace(appName)).isNotNull(); + } + + @Test + @Ignore + public void pressBackFromAllApps_popupMenuOpen_returnsToWorkspace() { + openAppDrawer(); + assertThat(findObjectByResourceName("search_container_all_apps")).isNotNull(); + + findDescendantByResourceName(findObjectByResourceName("apps_list_view"), "icon") + .click(LONG_PRESS_DURATION_MS); + assertThat(findObjectByResourceName("popup_container")).isNotNull(); + + // First back press should close only popup menu. + mDevice.pressBack(); + assertThat(findObjectByResourceName("search_container_all_apps")).isNotNull(); + assertThat(findObjectByResourceName("popup_container")).isNull(); + + // Second back press should close app drawer. + mDevice.pressBack(); + assertThat(findObjectByResourceName("popup_container")).isNull(); + assertThat(findObjectByResourceName("search_container_all_apps")).isNull(); + } + + @Test + @Ignore("Launcher3 without quickstep doesn't have a predictions row.") + public void dragNDropFromPredictionsRow_pinToGrid() { + openAppDrawer(); + assertThat(findObjectByResourceName("prediction_row")).isNotNull(); + String appName = startDragFromPredictionRow(); + moveAppToCenterOfScreen(); + dropApp(); + + // Ensure app was added. + assertThat(findAppInWorkspace(appName)).isNotNull(); + } + + @Test + @Ignore + public void dragNDropFromAppDrawer_pinToGrid() { + openAppDrawer(); + String draggedAppName = startDragFromAllApps(); + moveAppToCenterOfScreen(); + dropApp(); + + // Ensure app was added. + assertThat(findAppInWorkspace(draggedAppName)).isNotNull(); + } + + @Test + @Ignore + public void tapRemoveButton_unpinApp() { + openAppDrawer(); + String draggedAppName = startDragFromAllApps(); + moveAppToCenterOfScreen(); + dropApp(); + removeAppByName(draggedAppName); + assertThat(findAppInWorkspace(draggedAppName)).isNull(); + } + + private void openAppDrawer() { + UiObject2 allAppsButton = findObjectByResourceName("all_apps_button"); + assertThat(allAppsButton).isNotNull(); + allAppsButton.click(); + } + + private String startDragFromAllApps() { + // Find app from app drawer. + UiObject2 allApps = findObjectByResourceName("apps_list_view"); + assertThat(allApps).isNotNull(); + UiObject2 icon = findDescendantByResourceName(allApps, "icon"); + assertThat(icon).isNotNull(); + String appName = icon.getContentDescription(); + + // Start drag action. + mDownTime = SystemClock.uptimeMillis(); + mStartPoint = icon.getVisibleCenter(); + mEndPoint = new Point(mStartPoint.x, mStartPoint.y); + mLauncher.sendPointer(mDownTime, mDownTime, ACTION_DOWN, mStartPoint, + LauncherInstrumentation.GestureScope.INSIDE); + assertThat(findObjectByResourceName("popup_container")).isNotNull(); + return appName; + } + + private String startDragFromPredictionRow() { + // Find app from predictions. + UiObject2 predictionRow = findObjectByResourceName("prediction_row"); + assertThat(predictionRow).isNotNull(); + + UiObject2 icon = findDescendantByResourceName(predictionRow, "icon"); + assertThat(icon).isNotNull(); + + String appName = icon.getContentDescription(); + UiObject2 app = findDescendantByAppName(predictionRow, appName); + assertThat(app).isNotNull(); + + // Start drag action. + mDownTime = SystemClock.uptimeMillis(); + mStartPoint = icon.getVisibleCenter(); + mEndPoint = new Point(mStartPoint.x, mStartPoint.y); + mLauncher.sendPointer(mDownTime, mDownTime, ACTION_DOWN, mStartPoint, + LauncherInstrumentation.GestureScope.INSIDE); + assertThat(findObjectByResourceName("popup_container")).isNotNull(); + return appName; + } + + private void moveAppToCenterOfScreen() { + mEndPoint.set(mDevice.getDisplayWidth() / 2, mDevice.getDisplayHeight() / 2); + mLauncher.movePointer(mDownTime, SystemClock.uptimeMillis(), DRAG_TIME_MS, true, + mStartPoint, mEndPoint, LauncherInstrumentation.GestureScope.INSIDE); + } + + private void dropApp() { + mLauncher.sendPointer(mDownTime, SystemClock.uptimeMillis(), MotionEvent.ACTION_UP, + mEndPoint, LauncherInstrumentation.GestureScope.INSIDE); + } + + private void removeAppByName(String appName) { + // Find app within home screen. + UiObject2 app = findDescendantByAppName(findObjectByResourceName("workspace_grid"), + appName); + if (app == null) return; + + // Open app's popup container. + app.click(LONG_PRESS_DURATION_MS); + UiObject2 popupContainer = findObjectByResourceName("popup_container"); + assertThat(popupContainer).isNotNull(); + + // Grab & click remove button. + UiObject2 removeButton = findDescendantByTextOrDesc(popupContainer, "Remove"); + assertThat(removeButton).isNotNull(); + removeButton.click(); + } + + private UiObject2 findAppInWorkspace(String appName) { + UiObject2 workspace = findObjectByResourceName("workspace_grid"); + return findDescendantByAppName(workspace, appName); + } + + private UiObject2 findObjectByResourceName(String resourceName) { + return mDevice.wait(Until.findObject(By.res(mTargetPackage, resourceName)), WAIT_TIME_MS); + } + + private UiObject2 findDescendantByResourceName(UiObject2 outerObject, + String resourceName) { + assertThat(outerObject).isNotNull(); + return outerObject.findObject(By.res(mTargetPackage, resourceName)); + } + + private UiObject2 findDescendantByAppName(UiObject2 outerObject, String appName) { + assertThat(outerObject).isNotNull(); + return outerObject.findObject(By.clazz(TextView.class).text(appName) + .pkg(mDevice.getLauncherPackageName())); + } + + private UiObject2 findDescendantByTextOrDesc(UiObject2 outerObject, String content) { + assertThat(outerObject).isNotNull(); + UiObject2 innerObject = outerObject.findObject(By.desc(content)); + if (innerObject == null) innerObject = outerObject.findObject(By.text(content)); + return innerObject; + } + + private void startSecondaryDisplayActivity() { + mTargetContext.startActivity(( + new Intent(mTargetContext, SecondaryDisplayLauncher.class).addFlags( + FLAG_ACTIVITY_NEW_TASK))); + } + + private void setDragNDropFlag(Boolean status) { + Context context = new LauncherModelHelper().sandboxContext; + context.getSharedPreferences(FeatureFlags.FLAGS_PREF_NAME, Context.MODE_PRIVATE).edit() + .putBoolean(FeatureFlags.SECONDARY_DRAG_N_DROP_TO_PIN.key, status) + .commit(); + FeatureFlags.initialize(context); + startSecondaryDisplayActivity(); } } From b5b3b054d1c01d6b2c445f5c929cac94d9860c20 Mon Sep 17 00:00:00 2001 From: Ats Jenk Date: Thu, 20 Oct 2022 17:06:47 -0700 Subject: [PATCH 101/429] Clicking on desktop tile brings apps to front Override launchTasks() method from TaskView to ensure we always call into WMShell to bring desktop apps to front. And don't run single task animation logic. Bug: 254738174 Test: manual, enable shell transitions, click on desktop tile in recents Change-Id: Ibe85cbe14d3378a89ba7bfd5f394f0c3e44f304d --- .../android/quickstep/views/DesktopTaskView.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java index 9874f9644a..8385afe82c 100644 --- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java +++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java @@ -284,11 +284,18 @@ public class DesktopTaskView extends TaskView { return false; } + @Override + public RunnableList launchTasks() { + showDesktopApps(); + getRecentsView().onTaskLaunchedInLiveTileMode(); + return new RunnableList(); + } + @Nullable @Override public RunnableList launchTaskAnimated() { RunnableList endCallback = new RunnableList(); - SystemUiProxy.INSTANCE.get(getContext()).showDesktopApps(); + showDesktopApps(); RecentsView recentsView = getRecentsView(); recentsView.addSideTaskLaunchCallback(endCallback); return endCallback; @@ -296,10 +303,14 @@ public class DesktopTaskView extends TaskView { @Override public void launchTask(@NonNull Consumer callback, boolean freezeTaskList) { - SystemUiProxy.INSTANCE.get(getContext()).showDesktopApps(); + showDesktopApps(); callback.accept(true); } + private void showDesktopApps() { + SystemUiProxy.INSTANCE.get(getContext()).showDesktopApps(); + } + @Override void refreshThumbnails(@Nullable HashMap thumbnailDatas) { // Sets new thumbnails based on the incoming data and refreshes the rest. From 2a2fbfe319d548d9b9f9a36044a4652e07107236 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Thu, 20 Oct 2022 14:01:34 -0700 Subject: [PATCH 102/429] Use updateButtonLayoutSpacing() for all states * During a merge conflict we prevented updateButtonLayoutSpacing() from running if device was in setup mode, however the code that does setup layout is in there. Fixes: 254589281 Test: Went through setup, back button shows up where expected Change-Id: Ib496bfc0e3ac9023a9fc5071867c3779721ab8ab --- .../taskbar/NavbarButtonsViewController.java | 79 +++++++++---------- 1 file changed, 38 insertions(+), 41 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index af422cb4c0..026fa2311b 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -694,14 +694,10 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT } /** - * Adds the correct spacing to 3 button nav container. No-op if using gesture nav, setup - * is incomplete, or in kids mode. + * Adds the correct spacing to 3 button nav container depending on if device is in kids mode, + * setup wizard, or normal 3 button nav. */ private void updateButtonLayoutSpacing() { - if (!mContext.isThreeButtonNav() || mContext.isNavBarKidsModeActive() - || !mContext.isUserSetupComplete()) { - return; - } DeviceProfile dp = mContext.getDeviceProfile(); Resources res = mContext.getResources(); boolean isInSetup = !mContext.isUserSetupComplete(); @@ -719,41 +715,6 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT return; } - // Add spacing after the end of the last nav button - FrameLayout.LayoutParams navButtonParams = - (FrameLayout.LayoutParams) mNavButtonContainer.getLayoutParams(); - navButtonParams.gravity = Gravity.END; - navButtonParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; - navButtonParams.height = MATCH_PARENT; - - int navMarginEnd = (int) res.getDimension(dp.inv.inlineNavButtonsEndSpacing); - int contextualWidth = mEndContextualContainer.getWidth(); - // If contextual buttons are showing, we check if the end margin is enough for the - // contextual button to be showing - if not, move the nav buttons over a smidge - if (isContextualButtonShowing() && navMarginEnd < contextualWidth) { - // Additional spacing, eat up half of space between last icon and nav button - navMarginEnd += res.getDimensionPixelSize(R.dimen.taskbar_hotseat_nav_spacing) / 2; - } - navButtonParams.setMarginEnd(navMarginEnd); - mNavButtonContainer.setLayoutParams(navButtonParams); - - // Add the spaces in between the nav buttons - int spaceInBetween = res.getDimensionPixelSize(R.dimen.taskbar_button_space_inbetween); - for (int i = 0; i < mNavButtonContainer.getChildCount(); i++) { - View navButton = mNavButtonContainer.getChildAt(i); - LinearLayout.LayoutParams buttonLayoutParams = - (LinearLayout.LayoutParams) navButton.getLayoutParams(); - buttonLayoutParams.weight = 0; - if (i == 0) { - buttonLayoutParams.setMarginEnd(spaceInBetween / 2); - } else if (i == mNavButtonContainer.getChildCount() - 1) { - buttonLayoutParams.setMarginStart(spaceInBetween / 2); - } else { - buttonLayoutParams.setMarginStart(spaceInBetween / 2); - buttonLayoutParams.setMarginEnd(spaceInBetween / 2); - } - } - if (isInSetup) { handleSetupUi(); @@ -829,6 +790,42 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT mNavButtonContainer.requestLayout(); mHomeButton.setOnLongClickListener(null); + } else if (mContext.isThreeButtonNav()) { + // Setup normal 3 button + // Add spacing after the end of the last nav button + FrameLayout.LayoutParams navButtonParams = + (FrameLayout.LayoutParams) mNavButtonContainer.getLayoutParams(); + navButtonParams.gravity = Gravity.END; + navButtonParams.width = FrameLayout.LayoutParams.WRAP_CONTENT; + navButtonParams.height = MATCH_PARENT; + + int navMarginEnd = (int) res.getDimension(dp.inv.inlineNavButtonsEndSpacing); + int contextualWidth = mEndContextualContainer.getWidth(); + // If contextual buttons are showing, we check if the end margin is enough for the + // contextual button to be showing - if not, move the nav buttons over a smidge + if (isContextualButtonShowing() && navMarginEnd < contextualWidth) { + // Additional spacing, eat up half of space between last icon and nav button + navMarginEnd += res.getDimensionPixelSize(R.dimen.taskbar_hotseat_nav_spacing) / 2; + } + navButtonParams.setMarginEnd(navMarginEnd); + mNavButtonContainer.setLayoutParams(navButtonParams); + + // Add the spaces in between the nav buttons + int spaceInBetween = res.getDimensionPixelSize(R.dimen.taskbar_button_space_inbetween); + for (int i = 0; i < mNavButtonContainer.getChildCount(); i++) { + View navButton = mNavButtonContainer.getChildAt(i); + LinearLayout.LayoutParams buttonLayoutParams = + (LinearLayout.LayoutParams) navButton.getLayoutParams(); + buttonLayoutParams.weight = 0; + if (i == 0) { + buttonLayoutParams.setMarginEnd(spaceInBetween / 2); + } else if (i == mNavButtonContainer.getChildCount() - 1) { + buttonLayoutParams.setMarginStart(spaceInBetween / 2); + } else { + buttonLayoutParams.setMarginStart(spaceInBetween / 2); + buttonLayoutParams.setMarginEnd(spaceInBetween / 2); + } + } } } From 9a90c2d52170be41d1a49192c0690d52a46c5eca Mon Sep 17 00:00:00 2001 From: Mady Mellor Date: Wed, 14 Sep 2022 15:17:21 -0700 Subject: [PATCH 103/429] Hide launcher when freeform tasks are visible This CL introduces a new controller to manage the visibility of the launcher workspace when desktop mode is active and freeform tasks are visible. This controller will be notified when the sysui state flag related to freeform task visibility is changed. The controller will modify the workspace visibility as well as the flags on the activity indicating if it's been paused / resumed based on freeform tasks being visible or not. Bug: 245569277 Test: manual - enable desktop mode and open some freeform tasks => observe that the contents of launcher is hidden and taskbar shows - remove all of the freeform tasks => observe that the contents of launcher reappears along with the hotseat. Change-Id: I378ab97b40cbb954a06f4e2426b195efddad905c --- .../DesktopVisibilityController.java | 98 +++++++++++++++++++ .../uioverrides/QuickstepLauncher.java | 7 ++ .../android/quickstep/AbsSwipeUpHandler.java | 14 ++- .../quickstep/BaseActivityInterface.java | 6 ++ .../quickstep/LauncherActivityInterface.java | 11 +++ .../quickstep/TouchInteractionService.java | 14 +++ .../quickstep/views/LauncherRecentsView.java | 3 + src/com/android/launcher3/BaseActivity.java | 20 +++- 8 files changed, 166 insertions(+), 7 deletions(-) create mode 100644 quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java diff --git a/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java new file mode 100644 index 0000000000..0c8952d705 --- /dev/null +++ b/quickstep/src/com/android/launcher3/statehandlers/DesktopVisibilityController.java @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2022 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.launcher3.statehandlers; + +import android.os.SystemProperties; +import android.view.View; + +import com.android.launcher3.Launcher; +import com.android.launcher3.LauncherState; +import com.android.launcher3.statemanager.StatefulActivity; +import com.android.launcher3.uioverrides.QuickstepLauncher; + +/** + * Controls the visibility of the workspace and the resumed / paused state when desktop mode + * is enabled. + */ +public class DesktopVisibilityController { + + private final Launcher mLauncher; + + private boolean mFreeformTasksVisible; + private boolean mInOverviewState; + + public DesktopVisibilityController(Launcher launcher) { + mLauncher = launcher; + } + + /** + * Whether desktop mode is supported. + */ + private boolean isDesktopModeSupported() { + return SystemProperties.getBoolean("persist.wm.debug.desktop_mode", false); + } + + /** + * Whether freeform windows are visible in desktop mode. + */ + public boolean areFreeformTasksVisible() { + return mFreeformTasksVisible; + } + + /** + * Sets whether freeform windows are visible and updates launcher visibility based on that. + */ + public void setFreeformTasksVisible(boolean freeformTasksVisible) { + if (freeformTasksVisible != mFreeformTasksVisible) { + mFreeformTasksVisible = freeformTasksVisible; + updateLauncherVisibility(); + } + } + + /** + * Sets whether the overview is visible and updates launcher visibility based on that. + */ + public void setOverviewStateEnabled(boolean overviewStateEnabled) { + if (overviewStateEnabled != mInOverviewState) { + mInOverviewState = overviewStateEnabled; + updateLauncherVisibility(); + } + } + + /** + * Updates launcher visibility and state to look like it is paused or resumed depending on + * whether freeform windows are showing in desktop mode. + */ + private void updateLauncherVisibility() { + StatefulActivity activity = + QuickstepLauncher.ACTIVITY_TRACKER.getCreatedActivity(); + View workspaceView = mLauncher.getWorkspace(); + if (activity == null || workspaceView == null || !isDesktopModeSupported()) return; + + if (mFreeformTasksVisible) { + workspaceView.setVisibility(View.INVISIBLE); + if (!mInOverviewState) { + // When freeform is visible & we're not in overview, we want launcher to appear + // paused, this ensures that taskbar displays. + activity.setPaused(); + } + } else { + workspaceView.setVisibility(View.VISIBLE); + // If freeform isn't visible ensure that launcher appears resumed to behave normally. + activity.setResumed(); + } + } +} diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 3203f44ce2..4d96bf73a0 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -96,6 +96,7 @@ import com.android.launcher3.popup.SystemShortcut; import com.android.launcher3.proxy.ProxyActivityStarter; import com.android.launcher3.proxy.StartActivityParams; import com.android.launcher3.statehandlers.DepthController; +import com.android.launcher3.statehandlers.DesktopVisibilityController; import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory; import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.taskbar.LauncherTaskbarUIController; @@ -167,6 +168,7 @@ public class QuickstepLauncher extends Launcher { private FixedContainerItems mAllAppsPredictions; private HotseatPredictionController mHotseatPredictionController; private DepthController mDepthController; + private DesktopVisibilityController mDesktopVisibilityController; private QuickstepTransitionManager mAppTransitionManager; private OverviewActionsView mActionsView; private TISBindHelper mTISBindHelper; @@ -207,6 +209,7 @@ public class QuickstepLauncher extends Launcher { mTISBindHelper = new TISBindHelper(this, this::onTISConnected); mDepthController = new DepthController(this); + mDesktopVisibilityController = new DesktopVisibilityController(this); mHotseatPredictionController = new HotseatPredictionController(this); mEnableWidgetDepth = ENABLE_WIDGET_PICKER_DEPTH.get() @@ -732,6 +735,10 @@ public class QuickstepLauncher extends Launcher { return mDepthController; } + public DesktopVisibilityController getDesktopVisibilityController() { + return mDesktopVisibilityController; + } + @Nullable public UnfoldTransitionProgressProvider getUnfoldTransitionProgressProvider() { return mUnfoldTransitionProgressProvider; diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 07ddcc8b31..59e786c5ec 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -1882,10 +1882,16 @@ public abstract class AbsSwipeUpHandler, } private void finishCurrentTransitionToRecents() { - // TODO(b/245569277#comment2): enable once isFreeformActive is implemented - mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED); - if (mRecentsAnimationController != null) { - mRecentsAnimationController.detachNavigationBarFromApp(true); + if (mRecentsAnimationController != null + && mActivityInterface.getDesktopVisibilityController() != null + && mActivityInterface.getDesktopVisibilityController().areFreeformTasksVisible()) { + mRecentsAnimationController.finish(true /* toRecents */, + () -> mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED)); + } else { + mStateCallback.setStateOnUiThread(STATE_CURRENT_TASK_FINISHED); + if (mRecentsAnimationController != null) { + mRecentsAnimationController.detachNavigationBarFromApp(true); + } } ActiveGestureLog.INSTANCE.addLog( /* event= */ "finishRecentsAnimation", diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java index d4320043b0..294fa90ae4 100644 --- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java +++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java @@ -50,6 +50,7 @@ import com.android.launcher3.R; import com.android.launcher3.anim.AnimatorPlaybackController; import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.statehandlers.DepthController; +import com.android.launcher3.statehandlers.DesktopVisibilityController; import com.android.launcher3.statemanager.BaseState; import com.android.launcher3.statemanager.StatefulActivity; import com.android.launcher3.taskbar.TaskbarUIController; @@ -141,6 +142,11 @@ public abstract class BaseActivityInterface Date: Mon, 3 Oct 2022 15:48:13 -0700 Subject: [PATCH 104/429] Autohide and autoshow pagination in workspace Added code similar to WorkspacePageIndicator.java in order to autoshow and autohide the pagination in Workspace using PageIndicatorDots.java Bug: 249773534 Test: Manual Change-Id: I3b26d929d71510cf2f9d5342ee4c59007b8429cd --- .../launcher3/folder/FolderPagedView.java | 1 + .../pageindicators/PageIndicatorDots.java | 128 ++++++++++++++++-- 2 files changed, 114 insertions(+), 15 deletions(-) diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java index 0bcb97a818..efd511de37 100644 --- a/src/com/android/launcher3/folder/FolderPagedView.java +++ b/src/com/android/launcher3/folder/FolderPagedView.java @@ -113,6 +113,7 @@ public class FolderPagedView extends PagedView implements Cli public void setFolder(Folder folder) { mFolder = folder; mPageIndicator = folder.findViewById(R.id.folder_page_indicator); + mPageIndicator.setShouldAutoHide(false); initParentViews(folder); } diff --git a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java index 98ce9511a2..3770de8eb2 100644 --- a/src/com/android/launcher3/pageindicators/PageIndicatorDots.java +++ b/src/com/android/launcher3/pageindicators/PageIndicatorDots.java @@ -32,13 +32,18 @@ import android.graphics.Paint.Style; import android.graphics.Rect; import android.graphics.RectF; import android.graphics.drawable.Drawable; +import android.os.Handler; +import android.os.Looper; import android.util.AttributeSet; -import android.util.Property; +import android.util.FloatProperty; import android.view.View; +import android.view.ViewConfiguration; import android.view.ViewOutlineProvider; import android.view.animation.Interpolator; import android.view.animation.OvershootInterpolator; +import androidx.annotation.Nullable; + import com.android.launcher3.Insettable; import com.android.launcher3.R; import com.android.launcher3.Utilities; @@ -54,6 +59,8 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator private static final float SHIFT_PER_ANIMATION = 0.5f; private static final float SHIFT_THRESHOLD = 0.1f; private static final long ANIMATION_DURATION = 150; + private static final int PAGINATION_FADE_DELAY = ViewConfiguration.getScrollDefaultDelay(); + private static final int ALPHA_ANIMATE_DURATION = ViewConfiguration.getScrollBarFadeDuration(); private static final int ENTER_ANIMATION_START_DELAY = 300; private static final int ENTER_ANIMATION_STAGGERED_DELAY = 150; @@ -63,6 +70,9 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator private static final int DOT_ALPHA = 128; private static final int DOT_GAP_FACTOR = 3; private static final float DOT_GAP_FACTOR_FLOAT = 3.8f; + private static final int VISIBLE_ALPHA = 1; + private static final int INVISIBLE_ALPHA = 0; + private Paint mPaginationPaint; // This value approximately overshoots to 1.5 times the original size. private static final float ENTER_ANIMATION_OVERSHOOT_TENSION = 4.9f; @@ -71,22 +81,36 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator private static final RectF sTempRect = new RectF(); - private static final Property CURRENT_POSITION - = new Property(float.class, "current_position") { - @Override - public Float get(PageIndicatorDots obj) { - return obj.mCurrentPosition; - } + private static final FloatProperty CURRENT_POSITION = + new FloatProperty("current_position") { + @Override + public Float get(PageIndicatorDots obj) { + return obj.mCurrentPosition; + } - @Override - public void set(PageIndicatorDots obj, Float pos) { - obj.mCurrentPosition = pos; - obj.invalidate(); - obj.invalidateOutline(); - } - }; + @Override + public void setValue(PageIndicatorDots obj, float pos) { + obj.mCurrentPosition = pos; + obj.invalidate(); + obj.invalidateOutline(); + } + }; - private final Paint mPaginationPaint; + private static final FloatProperty PAGINATION_ALPHA = + new FloatProperty("pagination_alpha") { + @Override + public Float get(PageIndicatorDots obj) { + return obj.getAlpha(); + } + + @Override + public void setValue(PageIndicatorDots obj, float alpha) { + obj.setAlpha(alpha); + obj.invalidate(); + } + }; + + private final Handler mDelayedPaginationFadeHandler = new Handler(Looper.getMainLooper()); private final Drawable mPageIndicatorDrawable; private final float mDotRadius; private final float mCircleGap; @@ -98,6 +122,8 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator private int mActivePage; private int mCurrentScroll; private int mTotalScroll; + private boolean mShouldAutoHide = true; + private int mToAlpha; /** * The current position of the active dot including the animation progress. @@ -111,9 +137,12 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator private float mCurrentPosition; private float mFinalPosition; private ObjectAnimator mAnimator; + private @Nullable ObjectAnimator mAlphaAnimator; private float[] mEntryAnimationRadiusFactors; + private Runnable mHidePaginationRunnable = () -> animatePaginationToAlpha(INVISIBLE_ALPHA); + public PageIndicatorDots(Context context) { this(context, null); } @@ -153,6 +182,8 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator @Override public void setScroll(int currentScroll, int totalScroll) { + animatePaginationToAlpha(VISIBLE_ALPHA); + if (mNumPages <= 1) { mCurrentScroll = 0; return; @@ -166,6 +197,11 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator mCurrentScroll = currentScroll; mTotalScroll = totalScroll; invalidate(); + + if (mShouldAutoHide + && (getScrollPerPage() == 0 || mCurrentScroll % getScrollPerPage() == 0)) { + hideAfterDelay(); + } return; } @@ -187,6 +223,64 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator } } + @Override + public void setShouldAutoHide(boolean shouldAutoHide) { + mShouldAutoHide = shouldAutoHide; + if (shouldAutoHide && this.getAlpha() > INVISIBLE_ALPHA) { + hideAfterDelay(); + } else if (!shouldAutoHide) { + mDelayedPaginationFadeHandler.removeCallbacksAndMessages(null); + } + } + + private void hideAfterDelay() { + mDelayedPaginationFadeHandler.removeCallbacksAndMessages(null); + mDelayedPaginationFadeHandler.postDelayed(mHidePaginationRunnable, PAGINATION_FADE_DELAY); + } + + private void animatePaginationToAlpha(int alpha) { + if (alpha == mToAlpha) { + // Ignore the new animation if it is going to the same alpha as the current animation. + return; + } + mToAlpha = alpha; + + if (mAlphaAnimator != null) { + mAlphaAnimator.cancel(); + } + mAlphaAnimator = ObjectAnimator.ofFloat(this, PAGINATION_ALPHA, + alpha); + mAlphaAnimator.setDuration(ALPHA_ANIMATE_DURATION); + mAlphaAnimator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationEnd(Animator animation) { + mAlphaAnimator = null; + } + }); + mAlphaAnimator.start(); + + } + + /** + * Pauses all currently running animations. + */ + @Override + public void pauseAnimations() { + if (mAlphaAnimator != null) { + mAlphaAnimator.pause(); + } + } + + /** + * Force-ends all currently running or paused animations. + */ + @Override + public void skipAnimationsToEnd() { + if (mAlphaAnimator != null) { + mAlphaAnimator.end(); + } + } + private void animateToPosition(float position) { mFinalPosition = position; if (Math.abs(mCurrentPosition - mFinalPosition) < SHIFT_THRESHOLD) { @@ -282,6 +376,10 @@ public class PageIndicatorDots extends View implements Insettable, PageIndicator @Override protected void onDraw(Canvas canvas) { + if ((mShouldAutoHide && mTotalScroll == 0) || mNumPages < 2) { + return; + } + // Draw all page indicators; float circleGap = mCircleGap; float startX = (getWidth() - (mNumPages * circleGap) + mDotRadius) / 2; From ee0bc03d58aa3672e5afd14524682887b37ac1b0 Mon Sep 17 00:00:00 2001 From: Schneider Victor-tulias Date: Tue, 20 Sep 2022 13:54:29 -0700 Subject: [PATCH 105/429] Decrease TAPL All Apps scrolling flakiness scrolling in all apps did not factor in additional top padding in the all apps list recycler. This made it so that apps could occasionally scroll and be obcured by that top padding, making them un-tappable. Added this padding to the scrolling logic to make scrolling less flaky. Test: TaplTestsTaskbar, TaplTestsLauncher3 and presubmit Fixes: 248064856 Change-Id: Id76b92b4bc354917f3688ac53673d0ed7a905f02 --- .../taskbar/TaskbarActivityContext.java | 5 +++ .../allapps/TaskbarAllAppsController.java | 8 ++++ .../QuickstepTestInformationHandler.java | 20 ++++++++++ .../testing/TestInformationHandler.java | 5 +++ .../testing/shared/TestProtocol.java | 3 ++ .../com/android/launcher3/tapl/AllApps.java | 40 ++++++++++++++----- .../launcher3/tapl/AllAppsFromTaskbar.java | 8 ++++ .../android/launcher3/tapl/HomeAllApps.java | 8 ++++ 8 files changed, 86 insertions(+), 11 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 4c5e0bea8c..496a146f6b 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -907,4 +907,9 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mControllers.dumpLogs(prefix + "\t", pw); mDeviceProfile.dump(this, prefix, pw); } + + @VisibleForTesting + public int getTaskbarAllAppsTopPadding() { + return mControllers.taskbarAllAppsController.getTaskbarAllAppsTopPadding(); + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java index ea37944d69..85c63183ad 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java @@ -16,6 +16,7 @@ package com.android.launcher3.taskbar.allapps; import androidx.annotation.Nullable; +import androidx.annotation.VisibleForTesting; import com.android.launcher3.R; import com.android.launcher3.appprediction.PredictionRowView; @@ -123,4 +124,11 @@ public final class TaskbarAllAppsController { .findFixedRowByType(PredictionRowView.class) .setPredictedApps(mPredictedApps); } + + + @VisibleForTesting + public int getTaskbarAllAppsTopPadding() { + // Allow null-pointer since this should only be null if the apps view is not showing. + return mAppsView.getActiveRecyclerView().getClipBounds().top; + } } diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java index b7cdecd115..9621ce6eba 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -20,6 +20,7 @@ import com.android.quickstep.util.TISBindHelper; import java.util.concurrent.CountDownLatch; import java.util.concurrent.ExecutionException; import java.util.function.Consumer; +import java.util.function.Function; public class QuickstepTestInformationHandler extends TestInformationHandler { @@ -112,6 +113,13 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { resources.getDimensionPixelSize(R.dimen.taskbar_stashed_size)); return response; } + + case TestProtocol.REQUEST_TASKBAR_ALL_APPS_TOP_PADDING: { + return getTISBinderUIProperty(Bundle::putInt, tisBinder -> + tisBinder.getTaskbarManager() + .getCurrentActivityContext() + .getTaskbarAllAppsTopPadding()); + } } return super.call(method, arg, extras); @@ -159,4 +167,16 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { throw new RuntimeException(e); } } + + private Bundle getTISBinderUIProperty( + BundleSetter bundleSetter, Function provider) { + Bundle response = new Bundle(); + + runOnTISBinder(tisBinder -> bundleSetter.set( + response, + TestProtocol.TEST_INFO_RESPONSE_FIELD, + provider.apply(tisBinder))); + + return response; + } } diff --git a/src/com/android/launcher3/testing/TestInformationHandler.java b/src/com/android/launcher3/testing/TestInformationHandler.java index d3c9bc9676..7abf1e66a0 100644 --- a/src/com/android/launcher3/testing/TestInformationHandler.java +++ b/src/com/android/launcher3/testing/TestInformationHandler.java @@ -219,6 +219,11 @@ public class TestInformationHandler implements ResourceBasedOverride { return response; } + case TestProtocol.REQUEST_ALL_APPS_TOP_PADDING: { + return getLauncherUIProperty(Bundle::putInt, + l -> l.getAppsView().getActiveRecyclerView().getClipBounds().top); + } + default: return null; } diff --git a/src/com/android/launcher3/testing/shared/TestProtocol.java b/src/com/android/launcher3/testing/shared/TestProtocol.java index 5116b01ba5..10bb87779f 100644 --- a/src/com/android/launcher3/testing/shared/TestProtocol.java +++ b/src/com/android/launcher3/testing/shared/TestProtocol.java @@ -112,6 +112,9 @@ public final class TestProtocol { "get-activities-created-count"; public static final String REQUEST_GET_ACTIVITIES = "get-activities"; public static final String REQUEST_HAS_TIS = "has-touch-interaction-service"; + public static final String REQUEST_TASKBAR_ALL_APPS_TOP_PADDING = + "taskbar-all-apps-top-padding"; + public static final String REQUEST_ALL_APPS_TOP_PADDING = "all-apps-top-padding"; public static final String REQUEST_WORKSPACE_CELL_LAYOUT_SIZE = "workspace-cell-layout-size"; public static final String REQUEST_WORKSPACE_CELL_CENTER = "workspace-cell-center"; diff --git a/tests/tapl/com/android/launcher3/tapl/AllApps.java b/tests/tapl/com/android/launcher3/tapl/AllApps.java index 4791846626..6bbdf48da0 100644 --- a/tests/tapl/com/android/launcher3/tapl/AllApps.java +++ b/tests/tapl/com/android/launcher3/tapl/AllApps.java @@ -46,8 +46,7 @@ public abstract class AllApps extends LauncherInstrumentation.VisibleContainer { super(launcher); final UiObject2 allAppsContainer = verifyActiveContainer(); mHeight = mLauncher.getVisibleBounds(allAppsContainer).height(); - final UiObject2 appListRecycler = mLauncher.waitForObjectInContainer(allAppsContainer, - "apps_list_view"); + final UiObject2 appListRecycler = getAppListRecycler(allAppsContainer); // Wait for the recycler to populate. mLauncher.waitForObjectInContainer(appListRecycler, By.clazz(TextView.class)); verifyNotFrozen("All apps freeze flags upon opening all apps"); @@ -78,6 +77,11 @@ public abstract class AllApps extends LauncherInstrumentation.VisibleContainer { LauncherInstrumentation.log("hasClickableIcon: icon center is under search box"); return false; } + if (iconCenterInRecyclerTopPadding(appListRecycler, icon)) { + LauncherInstrumentation.log( + "hasClickableIcon: icon center is under the app list recycler's top padding."); + return false; + } if (iconBounds.bottom > displayBottom) { LauncherInstrumentation.log("hasClickableIcon: icon bottom below bottom offset"); return false; @@ -92,6 +96,13 @@ public abstract class AllApps extends LauncherInstrumentation.VisibleContainer { iconCenter.x, iconCenter.y); } + private boolean iconCenterInRecyclerTopPadding(UiObject2 appListRecycler, UiObject2 icon) { + final Point iconCenter = icon.getVisibleCenter(); + + return iconCenter.y <= mLauncher.getVisibleBounds(appListRecycler).top + + getAppsListRecyclerTopPadding(); + } + /** * Finds an icon. If the icon doesn't exist, return null. * Scrolls the app list when needed to make sure the icon is visible. @@ -105,9 +116,7 @@ public abstract class AllApps extends LauncherInstrumentation.VisibleContainer { LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "getting app icon " + appName + " on all apps")) { final UiObject2 allAppsContainer = verifyActiveContainer(); - final UiObject2 appListRecycler = mLauncher.waitForObjectInContainer(allAppsContainer, - "apps_list_view"); - final UiObject2 searchBox = hasSearchBox() ? getSearchBox(allAppsContainer) : null; + final UiObject2 appListRecycler = getAppListRecycler(allAppsContainer); int deviceHeight = mLauncher.getRealDisplaySize().y; int bottomGestureStartOnScreen = mLauncher.getBottomGestureStartOnScreen(); @@ -128,10 +137,9 @@ public abstract class AllApps extends LauncherInstrumentation.VisibleContainer { mLauncher.getVisibleBounds(icon).top < bottomGestureStartOnScreen) .collect(Collectors.toList()), - hasSearchBox() - ? mLauncher.getVisibleBounds(searchBox).bottom - - mLauncher.getVisibleBounds(allAppsContainer).top - : 0); + mLauncher.getVisibleBounds(appListRecycler).top + + getAppsListRecyclerTopPadding() + - mLauncher.getVisibleBounds(allAppsContainer).top); verifyActiveContainer(); final int newScroll = getAllAppsScroll(); mLauncher.assertTrue( @@ -180,16 +188,22 @@ public abstract class AllApps extends LauncherInstrumentation.VisibleContainer { protected abstract boolean hasSearchBox(); + protected abstract int getAppsListRecyclerTopPadding(); + private void scrollBackToBeginning() { try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "want to scroll back in all apps")) { LauncherInstrumentation.log("Scrolling to the beginning"); final UiObject2 allAppsContainer = verifyActiveContainer(); - final UiObject2 searchBox = hasSearchBox() ? getSearchBox(allAppsContainer) : null; + final UiObject2 appListRecycler = getAppListRecycler(allAppsContainer); int attempts = 0; final Rect margins = new Rect( - 0, hasSearchBox() ? mLauncher.getVisibleBounds(searchBox).bottom + 1 : 0, 0, 5); + /* left= */ 0, + mLauncher.getVisibleBounds(appListRecycler).top + + getAppsListRecyclerTopPadding() + 1, + /* right= */ 0, + /* bottom= */ 5); for (int scroll = getAllAppsScroll(); scroll != 0; @@ -220,6 +234,10 @@ public abstract class AllApps extends LauncherInstrumentation.VisibleContainer { .getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD); } + private UiObject2 getAppListRecycler(UiObject2 allAppsContainer) { + return mLauncher.waitForObjectInContainer(allAppsContainer, "apps_list_view"); + } + private UiObject2 getSearchBox(UiObject2 allAppsContainer) { return mLauncher.waitForObjectInContainer(allAppsContainer, "search_container_all_apps"); } diff --git a/tests/tapl/com/android/launcher3/tapl/AllAppsFromTaskbar.java b/tests/tapl/com/android/launcher3/tapl/AllAppsFromTaskbar.java index 516402563d..f804e28ceb 100644 --- a/tests/tapl/com/android/launcher3/tapl/AllAppsFromTaskbar.java +++ b/tests/tapl/com/android/launcher3/tapl/AllAppsFromTaskbar.java @@ -18,6 +18,8 @@ package com.android.launcher3.tapl; import androidx.annotation.NonNull; import androidx.test.uiautomator.UiObject2; +import com.android.launcher3.testing.shared.TestProtocol; + /** * Operations on AllApps opened from the Taskbar. */ @@ -48,4 +50,10 @@ public class AllAppsFromTaskbar extends AllApps { protected boolean hasSearchBox() { return false; } + + @Override + protected int getAppsListRecyclerTopPadding() { + return mLauncher.getTestInfo(TestProtocol.REQUEST_TASKBAR_ALL_APPS_TOP_PADDING) + .getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD); + } } diff --git a/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java b/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java index 7123de44a9..9a4c6d4dce 100644 --- a/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java +++ b/tests/tapl/com/android/launcher3/tapl/HomeAllApps.java @@ -18,6 +18,8 @@ package com.android.launcher3.tapl; import androidx.annotation.NonNull; import androidx.test.uiautomator.UiObject2; +import com.android.launcher3.testing.shared.TestProtocol; + public class HomeAllApps extends AllApps { private static final String BOTTOM_SHEET_RES_ID = "bottom_sheet_background"; @@ -47,6 +49,12 @@ public class HomeAllApps extends AllApps { return true; } + @Override + protected int getAppsListRecyclerTopPadding() { + return mLauncher.getTestInfo(TestProtocol.REQUEST_ALL_APPS_TOP_PADDING) + .getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD); + } + /** * Taps outside bottom sheet to dismiss and return to workspace. Available on tablets only. * @param tapRight Tap on the right of bottom sheet if true, or left otherwise. From a56f08e6770f42e1aa8f37cf1ff7b45b03728f13 Mon Sep 17 00:00:00 2001 From: Federico Baron Date: Thu, 13 Oct 2022 18:02:07 -0700 Subject: [PATCH 106/429] Set smartspace to 30% visibility on workspace edit for home gardening Here we set the smartspace to have 30% visibility to follow the guidelines set by https://docs.google.com/presentation/d/1FOmmCdmGmSMR77_901IOMbvbPVxPmjaAdxZjy-D9tw0/edit#slide=id.g159289e55db_0_229 Bug: 251259222 Test: Enter drag mode in workspace with SHOW_HOME_GARDENING flag on to see the changes Change-Id: Ia2ef4f1a49549fef9f8fbea7c007db8b81972f71 --- src/com/android/launcher3/CellLayout.java | 1 - src/com/android/launcher3/Workspace.java | 4 ++++ .../WorkspaceStateTransitionAnimation.java | 16 ++++++++++++++++ 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index cdd8f5a1c8..75d7b6b203 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -55,7 +55,6 @@ import android.view.ViewGroup; import android.view.accessibility.AccessibilityEvent; import androidx.annotation.IntDef; -import androidx.annotation.Nullable; import androidx.core.graphics.ColorUtils; import androidx.core.view.ViewCompat; diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index dd70ad09ef..ecb0808c48 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -919,6 +919,10 @@ public class Workspace extends PagedView return mScreenOrder; } + protected View getQsb() { + return mQsb; + } + /** * Returns the screen ID of a page that is shown together with the given page screen ID when the * two panel UI is enabled. diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java index a991c2f959..7699a1ab37 100644 --- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java +++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java @@ -29,11 +29,13 @@ import static com.android.launcher3.LauncherState.FLAG_HOTSEAT_INACCESSIBLE; import static com.android.launcher3.LauncherState.HINT_STATE; import static com.android.launcher3.LauncherState.HOTSEAT_ICONS; import static com.android.launcher3.LauncherState.NORMAL; +import static com.android.launcher3.LauncherState.SPRING_LOADED; import static com.android.launcher3.LauncherState.WORKSPACE_PAGE_INDICATOR; import static com.android.launcher3.anim.Interpolators.ACCEL_2; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.ZOOM_OUT; import static com.android.launcher3.anim.PropertySetter.NO_ANIM_PROPERTY_SETTER; +import static com.android.launcher3.config.FeatureFlags.SHOW_HOME_GARDENING; import static com.android.launcher3.graphics.Scrim.SCRIM_PROGRESS; import static com.android.launcher3.graphics.SysUiScrim.SYSUI_PROGRESS; import static com.android.launcher3.states.StateAnimationConfig.ANIM_HOTSEAT_FADE; @@ -69,6 +71,8 @@ import com.android.systemui.plugins.ResourceProvider; */ public class WorkspaceStateTransitionAnimation { + private static final float QSB_DISABLED_ALPHA = 0.3f; + private static final FloatProperty> WORKSPACE_SCALE_PROPERTY = WORKSPACE_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_WORKSPACE_STATE); @@ -155,6 +159,18 @@ public class WorkspaceStateTransitionAnimation { float hotseatIconsAlpha = (elements & HOTSEAT_ICONS) != 0 ? 1 : 0; propertySetter.setViewAlpha(hotseat, hotseatIconsAlpha, hotseatFadeInterpolator); + if (SHOW_HOME_GARDENING.get()) { + propertySetter.setViewAlpha( + mWorkspace.getQsb(), + state == SPRING_LOADED ? QSB_DISABLED_ALPHA : 1, + workspaceFadeInterpolator); + propertySetter.addEndListener(success -> { + if (success) { + mWorkspace.getQsb().setClickable(state != SPRING_LOADED); + } + }); + } + // Update the accessibility flags for hotseat based on launcher state. hotseat.setImportantForAccessibility( state.hasFlag(FLAG_HOTSEAT_INACCESSIBLE) From 0abfda8f2f41cd652bb621ecf57e61d3a13c0a6b Mon Sep 17 00:00:00 2001 From: Federico Baron Date: Tue, 18 Oct 2022 13:50:27 -0700 Subject: [PATCH 107/429] Rename first page pinned widget to mFirstPagePinnedWidget mQsb is the name used for the first page pinned widget. This variable name is bad since in some launchers the first page pinned widget is a qsb but sometimes it is a smartspace. Renaming the variable to mFirstPagePinnedWidget is a more accurate name for this variable. Bug: 251259222 Test: N/A Change-Id: I6d3c74163995d2267510ee546924917062c4955c --- src/com/android/launcher3/Workspace.java | 48 ++++++++++--------- .../WorkspaceStateTransitionAnimation.java | 8 ++-- 2 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index ecb0808c48..fe8b3641e3 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -224,8 +224,8 @@ public class Workspace extends PagedView // Variables relating to touch disambiguation (scrolling workspace vs. scrolling a widget) private float mXDown; private float mYDown; - private View mQsb; - private boolean mIsEventOverQsb; + private View mFirstPagePinnedItem; + private boolean mIsEventOverFirstPagePinnedItem; final static float START_DAMPING_TOUCH_SLOP_ANGLE = (float) Math.PI / 6; final static float MAX_SWIPE_ANGLE = (float) Math.PI / 3; @@ -575,20 +575,22 @@ public class Workspace extends PagedView // Add the first page CellLayout firstPage = insertNewWorkspaceScreen(Workspace.FIRST_SCREEN_ID, getChildCount()); - // Always add a QSB on the first screen. - if (mQsb == null) { - // In transposed layout, we add the QSB in the Grid. As workspace does not touch the - // edges, we do not need a full width QSB. - mQsb = LayoutInflater.from(getContext()) + // Always add a first page pinned widget on the first screen. + if (mFirstPagePinnedItem == null) { + // In transposed layout, we add the first page pinned widget in the Grid. + // As workspace does not touch the edges, we do not need a full + // width first page pinned widget. + mFirstPagePinnedItem = LayoutInflater.from(getContext()) .inflate(R.layout.search_container_workspace, firstPage, false); } int cellHSpan = mLauncher.getDeviceProfile().inv.numSearchContainerColumns; CellLayoutLayoutParams lp = new CellLayoutLayoutParams(0, 0, cellHSpan, 1); lp.canReorder = false; - if (!firstPage.addViewToCellLayout(mQsb, 0, R.id.search_container_workspace, lp, true)) { + if (!firstPage.addViewToCellLayout( + mFirstPagePinnedItem, 0, R.id.search_container_workspace, lp, true)) { Log.e(TAG, "Failed to add to item at (0, 0) to CellLayout"); - mQsb = null; + mFirstPagePinnedItem = null; } } @@ -597,9 +599,9 @@ public class Workspace extends PagedView // transition animations competing with us changing the scroll when we add pages disableLayoutTransitions(); - // Recycle the QSB widget - if (mQsb != null) { - ((ViewGroup) mQsb.getParent()).removeView(mQsb); + // Recycle the first page pinned widget + if (mFirstPagePinnedItem != null) { + ((ViewGroup) mFirstPagePinnedItem.getParent()).removeView(mFirstPagePinnedItem); } // Remove the pages and clear the screen models @@ -919,8 +921,8 @@ public class Workspace extends PagedView return mScreenOrder; } - protected View getQsb() { - return mQsb; + protected View getFirstPagePinnedItem() { + return mFirstPagePinnedItem; } /** @@ -1074,20 +1076,22 @@ public class Workspace extends PagedView mXDown = ev.getX(); mYDown = ev.getY(); - if (mQsb != null) { + if (mFirstPagePinnedItem != null) { mTempFXY[0] = mXDown + getScrollX(); mTempFXY[1] = mYDown + getScrollY(); - Utilities.mapCoordInSelfToDescendant(mQsb, this, mTempFXY); - mIsEventOverQsb = mQsb.getLeft() <= mTempFXY[0] && mQsb.getRight() >= mTempFXY[0] - && mQsb.getTop() <= mTempFXY[1] && mQsb.getBottom() >= mTempFXY[1]; + Utilities.mapCoordInSelfToDescendant(mFirstPagePinnedItem, this, mTempFXY); + mIsEventOverFirstPagePinnedItem = mFirstPagePinnedItem.getLeft() <= mTempFXY[0] + && mFirstPagePinnedItem.getRight() >= mTempFXY[0] + && mFirstPagePinnedItem.getTop() <= mTempFXY[1] + && mFirstPagePinnedItem.getBottom() >= mTempFXY[1]; } else { - mIsEventOverQsb = false; + mIsEventOverFirstPagePinnedItem = false; } } @Override protected void determineScrollingStart(MotionEvent ev) { - if (!isFinishedSwitchingState() || mIsEventOverQsb) return; + if (!isFinishedSwitchingState() || mIsEventOverFirstPagePinnedItem) return; float deltaX = ev.getX() - mXDown; float absDeltaX = Math.abs(deltaX); @@ -2538,10 +2542,10 @@ public class Workspace extends PagedView } private boolean isDragObjectOverSmartSpace(DragObject dragObject) { - if (mQsb == null) { + if (mFirstPagePinnedItem == null) { return false; } - getViewBoundsRelativeToWorkspace(mQsb, mTempRect); + getViewBoundsRelativeToWorkspace(mFirstPagePinnedItem, mTempRect); return mTempRect.contains(dragObject.x, dragObject.y); } diff --git a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java index 7699a1ab37..264c0a79dc 100644 --- a/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java +++ b/src/com/android/launcher3/WorkspaceStateTransitionAnimation.java @@ -71,7 +71,7 @@ import com.android.systemui.plugins.ResourceProvider; */ public class WorkspaceStateTransitionAnimation { - private static final float QSB_DISABLED_ALPHA = 0.3f; + private static final float FIRST_PAGE_PINNED_WIDGET_DISABLED_ALPHA = 0.3f; private static final FloatProperty> WORKSPACE_SCALE_PROPERTY = WORKSPACE_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_WORKSPACE_STATE); @@ -161,12 +161,12 @@ public class WorkspaceStateTransitionAnimation { if (SHOW_HOME_GARDENING.get()) { propertySetter.setViewAlpha( - mWorkspace.getQsb(), - state == SPRING_LOADED ? QSB_DISABLED_ALPHA : 1, + mWorkspace.getFirstPagePinnedItem(), + state == SPRING_LOADED ? FIRST_PAGE_PINNED_WIDGET_DISABLED_ALPHA : 1, workspaceFadeInterpolator); propertySetter.addEndListener(success -> { if (success) { - mWorkspace.getQsb().setClickable(state != SPRING_LOADED); + mWorkspace.getFirstPagePinnedItem().setClickable(state != SPRING_LOADED); } }); } From 64453ae482edd7aed7a32a4cf01e3a01ffb6f38f Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Fri, 21 Oct 2022 14:06:49 -0700 Subject: [PATCH 108/429] Introducing feature flag for optimizing overlay service connection Bug: 254903450 Test: n/a Change-Id: I2286be8583cc6dc46921b9ba8ef5505e5b8f0bf8 --- src/com/android/launcher3/config/FeatureFlags.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 75c28f9690..7a8a52324e 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -156,6 +156,11 @@ public final class FeatureFlags { "ENABLE_SMARTSPACE_DISMISS", true, "Adds a menu option to dismiss the current Enhanced Smartspace card."); + public static final BooleanFlag ENABLE_OVERLAY_CONNECTION_OPTIM = getDebugFlag( + "ENABLE_OVERLAY_CONNECTION_OPTIM", + false, + "Enable optimizing overlay service connection"); + /** * Enables region sampling for text color: Needs system health assessment before turning on */ From f31bf4e1e34af8fad4dca9ea408cc477d347a6e9 Mon Sep 17 00:00:00 2001 From: Shan Huang Date: Fri, 14 Oct 2022 22:17:21 +0000 Subject: [PATCH 109/429] DO NOT MERGE Use spring-y progress in back to home animation. Bug: 241788651 Test: m -j. Visual inspection. Change-Id: If2b0218367680853ae4ee89c5ecff224ab9b6f04 --- .../LauncherBackAnimationController.java | 56 ++++++++++--------- 1 file changed, 31 insertions(+), 25 deletions(-) diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java index ee3b0752b9..c0da8e4827 100644 --- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java +++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java @@ -36,6 +36,7 @@ import android.view.SurfaceControl; import android.view.animation.AnimationUtils; import android.view.animation.Interpolator; import android.window.BackEvent; +import android.window.BackProgressAnimator; import android.window.IOnBackInvokedCallback; import com.android.launcher3.AbstractFloatingView; @@ -90,6 +91,7 @@ public class LauncherBackAnimationController { private float mBackProgress = 0; private boolean mBackInProgress = false; private IOnBackInvokedCallback mBackCallback; + private BackProgressAnimator mProgressAnimator = new BackProgressAnimator(); public LauncherBackAnimationController( QuickstepLauncher launcher, @@ -118,30 +120,41 @@ public class LauncherBackAnimationController { mBackCallback = new IOnBackInvokedCallback.Stub() { @Override public void onBackCancelled() { - handler.post(() -> resetPositionAnimated()); + handler.post(() -> { + resetPositionAnimated(); + mProgressAnimator.reset(); + }); } @Override public void onBackInvoked() { - handler.post(() -> startTransition()); + handler.post(() -> { + startTransition(); + mProgressAnimator.reset(); + }); } @Override public void onBackProgressed(BackEvent backEvent) { - mBackProgress = backEvent.getProgress(); - // TODO: Update once the interpolation curve spec is finalized. - mBackProgress = - 1 - (1 - mBackProgress) * (1 - mBackProgress) * (1 - - mBackProgress); - if (!mBackInProgress) { - startBack(backEvent); - } else { - updateBackProgress(mBackProgress, backEvent); - } + handler.post(() -> { + mProgressAnimator.onBackProgressed(backEvent); + }); } @Override - public void onBackStarted() { } + public void onBackStarted(BackEvent backEvent) { + handler.post(() -> { + startBack(backEvent); + mProgressAnimator.onBackStarted(backEvent, event -> { + mBackProgress = event.getProgress(); + // TODO: Update once the interpolation curve spec is finalized. + mBackProgress = + 1 - (1 - mBackProgress) * (1 - mBackProgress) * (1 + - mBackProgress); + updateBackProgress(mBackProgress, event); + }); + }); + } }; SystemUiProxy.INSTANCE.get(mLauncher).setBackToLauncherCallback(mBackCallback); } @@ -169,6 +182,7 @@ public class LauncherBackAnimationController { if (mBackCallback != null) { SystemUiProxy.INSTANCE.get(mLauncher).clearBackToLauncherCallback(mBackCallback); } + mProgressAnimator.reset(); mBackCallback = null; } @@ -187,28 +201,20 @@ public class LauncherBackAnimationController { // TODO(b/218916755): Offset start rectangle in multiwindow mode. mStartRect.set(mBackTarget.windowConfiguration.getMaxBounds()); + mCurrentRect.set(mStartRect); } private void updateBackProgress(float progress, BackEvent event) { - if (mBackTarget == null) { + if (!mBackInProgress || mBackTarget == null) { return; } float screenWidth = mStartRect.width(); float screenHeight = mStartRect.height(); - float dX = Math.abs(event.getTouchX() - mInitialTouchPos.x); - // The 'follow width' is the width of the window if it completely matches - // the gesture displacement. - float followWidth = screenWidth - dX; - // The 'progress width' is the width of the window if it strictly linearly interpolates - // to minimum scale base on progress. - float progressWidth = Utilities.mapRange(progress, 1, MIN_WINDOW_SCALE) * screenWidth; - // The final width is derived from interpolating between the follow with and progress width - // using gesture progress. - float width = Utilities.mapRange(progress, followWidth, progressWidth); + float width = Utilities.mapRange(progress, 1, MIN_WINDOW_SCALE) * screenWidth; float height = screenHeight / screenWidth * width; float deltaYRatio = (event.getTouchY() - mInitialTouchPos.y) / screenHeight; // Base the window movement in the Y axis on the touch movement in the Y axis. - float deltaY = (float) Math.sin(deltaYRatio * Math.PI * 0.5f) * mWindowMaxDeltaY; + float deltaY = (float) Math.sin(deltaYRatio * Math.PI * 0.5f) * mWindowMaxDeltaY * progress; // Move the window along the Y axis. float top = (screenHeight - height) * 0.5f + deltaY; // Move the window along the X axis. From 4ed3dfc28a43ead701f5756e5e29e30028b32203 Mon Sep 17 00:00:00 2001 From: Becky Qiu Date: Wed, 19 Oct 2022 16:58:22 -0700 Subject: [PATCH 110/429] [Toast] Use a BaseSearchConfig for launcher3 to read allapps device config. Bug: 251387263 Test: local Change-Id: I92c52caff377e627305bc7999ae0205fe6269968 --- src/com/android/launcher3/Launcher.java | 13 +++++---- .../allapps/AllAppsTransitionController.java | 2 +- .../launcher3/allapps/BaseSearchConfig.java | 28 +++++++++++++++++++ 3 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 src/com/android/launcher3/allapps/BaseSearchConfig.java diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 3abefe0cad..a2cfff3080 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -131,6 +131,7 @@ import com.android.launcher3.allapps.AllAppsRecyclerView; import com.android.launcher3.allapps.AllAppsStore; import com.android.launcher3.allapps.AllAppsTransitionController; import com.android.launcher3.allapps.BaseAllAppsContainerView; +import com.android.launcher3.allapps.BaseSearchConfig; import com.android.launcher3.allapps.DiscoveryBounce; import com.android.launcher3.anim.PropertyListBuilder; import com.android.launcher3.compat.AccessibilityManagerCompat; @@ -395,6 +396,7 @@ public class Launcher extends StatefulActivity private LauncherState mPrevLauncherState; private StringCache mStringCache; + private BaseSearchConfig mBaseSearchConfig; @Override @TargetApi(Build.VERSION_CODES.S) @@ -545,6 +547,9 @@ public class Launcher extends StatefulActivity getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_ADJUST_NOTHING); } setTitle(R.string.home_screen); + + // TODO: move the SearchConfig to SearchState when new LauncherState is created. + mBaseSearchConfig = new BaseSearchConfig(); } protected LauncherOverlayManager getDefaultOverlay() { @@ -1592,12 +1597,8 @@ public class Launcher extends StatefulActivity return mOldConfig.orientation; } - /** - * Whether keyboard sync is enabled for transitions between Home and All Apps. - * TODO(b/251387263): move this method inside an All Apps specific config class. - */ - public boolean isKeyboardSyncEnabled() { - return false; + public BaseSearchConfig getSearchConfig() { + return mBaseSearchConfig; } @Override diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index 001b494439..25225ed940 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -228,7 +228,7 @@ public class AllAppsTransitionController StateAnimationConfig config, PendingAnimation builder) { if (mLauncher.isInState(ALL_APPS) && !ALL_APPS.equals(toState)) { // For atomic animations, we close the keyboard immediately. - if (!config.userControlled && !mLauncher.isKeyboardSyncEnabled()) { + if (!config.userControlled && !mLauncher.getSearchConfig().isKeyboardSyncEnabled()) { mLauncher.getAppsView().getSearchUiManager().getEditText().hideKeyboard(); } diff --git a/src/com/android/launcher3/allapps/BaseSearchConfig.java b/src/com/android/launcher3/allapps/BaseSearchConfig.java new file mode 100644 index 0000000000..9f47e8d82f --- /dev/null +++ b/src/com/android/launcher3/allapps/BaseSearchConfig.java @@ -0,0 +1,28 @@ +/* + * Copyright (C) 2022 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.launcher3.allapps; + +/** Base config values for search. */ +public class BaseSearchConfig { + public BaseSearchConfig() {} + + /** + * Returns whether to enable the synchronized keyboard transition between Home and All Apps. + */ + public boolean isKeyboardSyncEnabled() { + return false; + } +} From f34811d3a3c1969a45da452fe8ba6ff336c6e9a4 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Fri, 21 Oct 2022 20:42:34 +0000 Subject: [PATCH 111/429] Revert "Revert "Updating the scroll calculation from recyclerView to avoid view inflation"" Test: ABTD https://android-build.googleplex.com/builds/abtd/run/L52600000956969786 This reverts commit cee6ddf3deaed339e6d6df7f1682c725a00197b9. Reason for revert: Fixed in ag/20239136 Change-Id: I0e8446e66d9a86a94b40fcbd6de14da07abe8e5c --- .../launcher3/FastScrollRecyclerView.java | 56 +----- src/com/android/launcher3/Launcher.java | 2 +- .../launcher3/allapps/AllAppsGridAdapter.java | 15 +- .../allapps/AllAppsRecyclerView.java | 99 +--------- .../allapps/BaseAllAppsContainerView.java | 3 +- .../launcher3/allapps/FloatingHeaderView.java | 2 +- .../testing/TestInformationHandler.java | 4 +- .../util/ScrollableLayoutManager.java | 183 ++++++++++++++++++ .../views/RecyclerViewFastScroller.java | 6 - .../widget/picker/WidgetsRecyclerView.java | 49 +---- .../launcher3/ui/AbstractLauncherUiTest.java | 2 +- .../launcher3/ui/TaplTestsLauncher3.java | 2 +- 12 files changed, 212 insertions(+), 211 deletions(-) create mode 100644 src/com/android/launcher3/util/ScrollableLayoutManager.java diff --git a/src/com/android/launcher3/FastScrollRecyclerView.java b/src/com/android/launcher3/FastScrollRecyclerView.java index 747b755263..2f927d3142 100644 --- a/src/com/android/launcher3/FastScrollRecyclerView.java +++ b/src/com/android/launcher3/FastScrollRecyclerView.java @@ -24,7 +24,6 @@ import android.view.ViewGroup; import android.view.accessibility.AccessibilityNodeInfo; import androidx.annotation.Nullable; -import androidx.recyclerview.widget.LinearLayoutManager; import androidx.recyclerview.widget.RecyclerView; import com.android.launcher3.compat.AccessibilityManagerCompat; @@ -92,8 +91,7 @@ public abstract class FastScrollRecyclerView extends RecyclerView { protected int getAvailableScrollHeight() { // AvailableScrollHeight = Total height of the all items - first page height int firstPageHeight = getMeasuredHeight() - getPaddingTop() - getPaddingBottom(); - int totalHeightOfAllItems = getItemsHeight(/* untilIndex= */ getAdapter().getItemCount()); - int availableScrollHeight = totalHeightOfAllItems - firstPageHeight; + int availableScrollHeight = computeVerticalScrollRange() - firstPageHeight; return Math.max(0, availableScrollHeight); } @@ -146,10 +144,7 @@ public abstract class FastScrollRecyclerView extends RecyclerView { // IF scroller is at the very top OR there is no scroll bar because there is probably not // enough items to scroll, THEN it's okay for the container to be pulled down. - if (getCurrentScrollY() == 0) { - return true; - } - return getAdapter() == null || getAdapter().getItemCount() == 0; + return computeVerticalScrollOffset() == 0; } /** @@ -159,53 +154,6 @@ public abstract class FastScrollRecyclerView extends RecyclerView { return true; } - /** - * @return the scroll top of this recycler view. - */ - public int getCurrentScrollY() { - Adapter adapter = getAdapter(); - if (adapter == null) { - return -1; - } - if (adapter.getItemCount() == 0 || getChildCount() == 0) { - return -1; - } - - int itemPosition = NO_POSITION; - View child = null; - - LayoutManager layoutManager = getLayoutManager(); - if (layoutManager instanceof LinearLayoutManager) { - // Use the LayoutManager as the source of truth for visible positions. During - // animations, the view group child may not correspond to the visible views that appear - // at the top. - itemPosition = ((LinearLayoutManager) layoutManager).findFirstVisibleItemPosition(); - child = layoutManager.findViewByPosition(itemPosition); - } - - if (child == null) { - // If the layout manager returns null for any reason, which can happen before layout - // has occurred for the position, then look at the child of this view as a ViewGroup. - child = getChildAt(0); - itemPosition = getChildAdapterPosition(child); - } - if (itemPosition == NO_POSITION) { - return -1; - } - return getPaddingTop() + getItemsHeight(itemPosition) - - layoutManager.getDecoratedTop(child); - } - - /** - * Returns the sum of the height, in pixels, of this list adapter's items from index - * 0 (inclusive) until {@code untilIndex} (exclusive). If untilIndex is same as the itemCount, - * it returns the full height of all the items. - * - *

If the untilIndex is larger than the total number of items in this adapter, returns the - * sum of all items' height. - */ - protected abstract int getItemsHeight(int untilIndex); - /** * Maps the touch (from 0..1) to the adapter position that should be visible. *

Override in each subclass of this base class. diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 3abefe0cad..07d0f55321 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -2803,7 +2803,7 @@ public class Launcher extends StatefulActivity View v = getFirstMatch(Collections.singletonList(activeRecyclerView), preferredItem, packageAndUserAndApp); - if (v != null && activeRecyclerView.getCurrentScrollY() > 0) { + if (v != null && activeRecyclerView.computeVerticalScrollOffset() > 0) { RectF locationBounds = new RectF(); FloatingIconView.getLocationBoundsForView(this, v, false, locationBounds, new Rect()); diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java index fe0230a837..368a37384d 100644 --- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java +++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java @@ -26,7 +26,9 @@ import androidx.core.view.accessibility.AccessibilityNodeInfoCompat; import androidx.core.view.accessibility.AccessibilityRecordCompat; import androidx.recyclerview.widget.GridLayoutManager; import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.RecyclerView.Adapter; +import com.android.launcher3.util.ScrollableLayoutManager; import com.android.launcher3.views.ActivityContext; import java.util.List; @@ -66,10 +68,10 @@ public class AllAppsGridAdapter extends /** * A subclass of GridLayoutManager that overrides accessibility values during app search. */ - public class AppsGridLayoutManager extends GridLayoutManager { + public class AppsGridLayoutManager extends ScrollableLayoutManager { public AppsGridLayoutManager(Context context) { - super(context, 1, GridLayoutManager.VERTICAL, false); + super(context); } @Override @@ -129,6 +131,15 @@ public class AllAppsGridAdapter extends } return extraRows; } + + @Override + protected int incrementTotalHeight(Adapter adapter, int position, int heightUntilLastPos) { + AllAppsGridAdapter.AdapterItem item = mApps.getAdapterItems().get(position); + // only account for the first icon in the row since they are the same size within a row + return (isIconViewType(item.viewType) && item.rowAppIndex != 0) + ? heightUntilLastPos + : (heightUntilLastPos + mCachedSizes.get(item.viewType)); + } } @Override diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index 0efa7c4444..ac10892ece 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -15,8 +15,6 @@ */ package com.android.launcher3.allapps; -import static android.view.View.MeasureSpec.UNSPECIFIED; - import static com.android.launcher3.logger.LauncherAtom.ContainerInfo; import static com.android.launcher3.logger.LauncherAtom.SearchResultContainer; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_SCROLLED_DOWN; @@ -30,7 +28,6 @@ import android.content.Context; import android.graphics.Canvas; import android.util.AttributeSet; import android.util.Log; -import android.util.SparseIntArray; import androidx.recyclerview.widget.RecyclerView; @@ -54,41 +51,11 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { private static final boolean DEBUG = false; private static final boolean DEBUG_LATENCY = Utilities.isPropertyEnabled(SEARCH_LOGGING); - protected AlphabeticalAppsList mApps; protected final int mNumAppsPerRow; - - // The specific view heights that we use to calculate scroll - private final SparseIntArray mViewHeights = new SparseIntArray(); - private final SparseIntArray mCachedScrollPositions = new SparseIntArray(); private final AllAppsFastScrollHelper mFastScrollHelper; private int mCumulativeVerticalScroll; - - private final AdapterDataObserver mObserver = new RecyclerView.AdapterDataObserver() { - public void onChanged() { - mCachedScrollPositions.clear(); - } - - @Override - public void onItemRangeChanged(int positionStart, int itemCount) { - onChanged(); - } - - @Override - public void onItemRangeInserted(int positionStart, int itemCount) { - onChanged(); - } - - @Override - public void onItemRangeRemoved(int positionStart, int itemCount) { - onChanged(); - } - - @Override - public void onItemRangeMoved(int fromPosition, int toPosition, int itemCount) { - onChanged(); - } - }; + protected AlphabeticalAppsList mApps; public AllAppsRecyclerView(Context context) { this(context, null); @@ -128,12 +95,8 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_ALL_APPS_DIVIDER, 1); pool.setMaxRecycledViews(AllAppsGridAdapter.VIEW_TYPE_ICON, approxRows * (mNumAppsPerRow + 1)); - - mViewHeights.clear(); - mViewHeights.put(AllAppsGridAdapter.VIEW_TYPE_ICON, grid.allAppsCellHeightPx); } - @Override public void onDraw(Canvas c) { if (DEBUG) { @@ -212,17 +175,6 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { mFastScrollHelper.onFastScrollCompleted(); } - @Override - public void setAdapter(Adapter adapter) { - if (getAdapter() != null) { - getAdapter().unregisterAdapterDataObserver(mObserver); - } - super.setAdapter(adapter); - if (adapter != null) { - adapter.registerAdapterDataObserver(mObserver); - } - } - @Override protected boolean isPaddingOffsetRequired() { return true; @@ -244,13 +196,13 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { List items = mApps.getAdapterItems(); // Skip early if there are no items or we haven't been measured - if (items.isEmpty() || mNumAppsPerRow == 0) { + if (items.isEmpty() || mNumAppsPerRow == 0 || getChildCount() == 0) { mScrollbar.setThumbOffsetY(-1); return; } // Skip early if, there no child laid out in the container. - int scrollY = getCurrentScrollY(); + int scrollY = computeVerticalScrollOffset(); if (scrollY < 0) { mScrollbar.setThumbOffsetY(-1); return; @@ -305,51 +257,6 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { } } - @Override - protected int getItemsHeight(int position) { - List items = mApps.getAdapterItems(); - AllAppsGridAdapter.AdapterItem posItem = position < items.size() - ? items.get(position) : null; - int y = mCachedScrollPositions.get(position, -1); - if (y < 0) { - y = 0; - for (int i = 0; i < position; i++) { - AllAppsGridAdapter.AdapterItem item = items.get(i); - if (AllAppsGridAdapter.isIconViewType(item.viewType)) { - // Break once we reach the desired row - if (posItem != null && posItem.viewType == item.viewType && - posItem.rowIndex == item.rowIndex) { - break; - } - // Otherwise, only account for the first icon in the row since they are the same - // size within a row - if (item.rowAppIndex == 0) { - y += mViewHeights.get(item.viewType, 0); - } - } else { - // Rest of the views span the full width - int elHeight = mViewHeights.get(item.viewType); - if (elHeight == 0) { - ViewHolder holder = findViewHolderForAdapterPosition(i); - if (holder == null) { - holder = getAdapter().createViewHolder(this, item.viewType); - getAdapter().onBindViewHolder(holder, i); - holder.itemView.measure(UNSPECIFIED, UNSPECIFIED); - elHeight = holder.itemView.getMeasuredHeight(); - - getRecycledViewPool().putRecycledView(holder); - } else { - elHeight = holder.itemView.getMeasuredHeight(); - } - } - y += elHeight; - } - } - mCachedScrollPositions.put(position, y); - } - return y; - } - public int getScrollBarTop() { return getResources().getDimensionPixelOffset(R.dimen.all_apps_header_top_padding); } diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java index 70c1e18301..7f6247e33e 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java @@ -106,7 +106,8 @@ public abstract class BaseAllAppsContainerView l.getAppsView().getActiveRecyclerView().getCurrentScrollY()); + l -> l.getAppsView().getActiveRecyclerView().computeVerticalScrollOffset()); } case TestProtocol.REQUEST_WIDGETS_SCROLL_Y: { return getLauncherUIProperty(Bundle::putInt, - l -> WidgetsFullSheet.getWidgetsView(l).getCurrentScrollY()); + l -> WidgetsFullSheet.getWidgetsView(l).computeVerticalScrollOffset()); } case TestProtocol.REQUEST_TARGET_INSETS: { diff --git a/src/com/android/launcher3/util/ScrollableLayoutManager.java b/src/com/android/launcher3/util/ScrollableLayoutManager.java new file mode 100644 index 0000000000..17eaefda18 --- /dev/null +++ b/src/com/android/launcher3/util/ScrollableLayoutManager.java @@ -0,0 +1,183 @@ +/* + * Copyright (C) 2022 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.launcher3.util; + +import android.content.Context; +import android.util.SparseIntArray; +import android.view.View; + +import androidx.annotation.NonNull; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; +import androidx.recyclerview.widget.RecyclerView.Adapter; +import androidx.recyclerview.widget.RecyclerView.State; +import androidx.recyclerview.widget.RecyclerView.ViewHolder; + +/** + * Extension of {@link GridLayoutManager} with support for smooth scrolling + */ +public class ScrollableLayoutManager extends GridLayoutManager { + + // keyed on item type + protected final SparseIntArray mCachedSizes = new SparseIntArray(); + + private RecyclerView mRv; + + /** + * Precalculated total height keyed on the item position. This is always incremental. + * Subclass can override {@link #incrementTotalHeight} to incorporate the layout logic. + * For example all-apps should have same values for items in same row, + * sample values: 0, 10, 10, 10, 10, 20, 20, 20, 20 + * whereas widgets will have strictly increasing values + * sample values: 0, 10, 50, 60, 110 + */ + + // + private int[] mTotalHeightCache = new int[1]; + private int mLastValidHeightIndex = 0; + + public ScrollableLayoutManager(Context context) { + super(context, 1, GridLayoutManager.VERTICAL, false); + } + + @Override + public void onAttachedToWindow(RecyclerView view) { + super.onAttachedToWindow(view); + mRv = view; + } + + @Override + public void layoutDecorated(@NonNull View child, int left, int top, int right, int bottom) { + super.layoutDecorated(child, left, top, right, bottom); + mCachedSizes.put( + mRv.getChildViewHolder(child).getItemViewType(), child.getMeasuredHeight()); + } + + @Override + public void layoutDecoratedWithMargins(@NonNull View child, int left, int top, int right, + int bottom) { + super.layoutDecoratedWithMargins(child, left, top, right, bottom); + mCachedSizes.put( + mRv.getChildViewHolder(child).getItemViewType(), child.getMeasuredHeight()); + } + + @Override + public int computeVerticalScrollExtent(State state) { + return mRv == null ? 0 : mRv.getHeight(); + } + + @Override + public int computeVerticalScrollOffset(State state) { + Adapter adapter = mRv == null ? null : mRv.getAdapter(); + if (adapter == null) { + return 0; + } + if (adapter.getItemCount() == 0 || getChildCount() == 0) { + return 0; + } + View child = getChildAt(0); + ViewHolder holder = mRv.findContainingViewHolder(child); + if (holder == null) { + return 0; + } + int itemPosition = holder.getLayoutPosition(); + if (itemPosition < 0) { + return 0; + } + return getPaddingTop() + getItemsHeight(adapter, itemPosition) - getDecoratedTop(child); + } + + @Override + public int computeVerticalScrollRange(State state) { + Adapter adapter = mRv == null ? null : mRv.getAdapter(); + return adapter == null ? 0 : getItemsHeight(adapter, adapter.getItemCount()); + } + + /** + * Returns the sum of the height, in pixels, of this list adapter's items from index + * 0 (inclusive) until {@code untilIndex} (exclusive). If untilIndex is same as the itemCount, + * it returns the full height of all the items. + * + *

If the untilIndex is larger than the total number of items in this adapter, returns the + * sum of all items' height. + */ + private int getItemsHeight(Adapter adapter, int untilIndex) { + final int totalItems = adapter.getItemCount(); + if (mTotalHeightCache.length < (totalItems + 1)) { + mTotalHeightCache = new int[totalItems + 1]; + mLastValidHeightIndex = 0; + } + if (untilIndex > totalItems) { + untilIndex = totalItems; + } else if (untilIndex < 0) { + untilIndex = 0; + } + if (untilIndex <= mLastValidHeightIndex) { + return mTotalHeightCache[untilIndex]; + } + + int totalItemsHeight = mTotalHeightCache[mLastValidHeightIndex]; + for (int i = mLastValidHeightIndex; i < untilIndex; i++) { + totalItemsHeight = incrementTotalHeight(adapter, i, totalItemsHeight); + mTotalHeightCache[i + 1] = totalItemsHeight; + } + mLastValidHeightIndex = untilIndex; + return totalItemsHeight; + } + + /** + * The current implementation assumes a linear list with every item taking up the whole row. + * Subclasses should override this method to account for any spanning logic + */ + protected int incrementTotalHeight(Adapter adapter, int position, int heightUntilLastPos) { + return heightUntilLastPos + mCachedSizes.get(adapter.getItemViewType(position)); + } + + private void invalidateScrollCache() { + mLastValidHeightIndex = 0; + } + + @Override + public void onItemsAdded(RecyclerView recyclerView, int positionStart, int itemCount) { + super.onItemsAdded(recyclerView, positionStart, itemCount); + invalidateScrollCache(); + } + + @Override + public void onItemsChanged(RecyclerView recyclerView) { + super.onItemsChanged(recyclerView); + invalidateScrollCache(); + } + + @Override + public void onItemsRemoved(RecyclerView recyclerView, int positionStart, int itemCount) { + super.onItemsRemoved(recyclerView, positionStart, itemCount); + invalidateScrollCache(); + } + + @Override + public void onItemsMoved(RecyclerView recyclerView, int from, int to, int itemCount) { + super.onItemsMoved(recyclerView, from, to, itemCount); + invalidateScrollCache(); + } + + @Override + public void onItemsUpdated(RecyclerView recyclerView, int positionStart, int itemCount, + Object payload) { + super.onItemsUpdated(recyclerView, positionStart, itemCount, payload); + invalidateScrollCache(); + } +} diff --git a/src/com/android/launcher3/views/RecyclerViewFastScroller.java b/src/com/android/launcher3/views/RecyclerViewFastScroller.java index 40e4ce1c04..3af2e3c9dc 100644 --- a/src/com/android/launcher3/views/RecyclerViewFastScroller.java +++ b/src/com/android/launcher3/views/RecyclerViewFastScroller.java @@ -119,7 +119,6 @@ public class RecyclerViewFastScroller extends View { // prevent jumping, this offset is applied as the user scrolls. protected int mTouchOffsetY; protected int mThumbOffsetY; - protected int mRvOffsetY; // Fast scroller popup private TextView mPopupView; @@ -207,16 +206,11 @@ public class RecyclerViewFastScroller extends View { public void setThumbOffsetY(int y) { if (mThumbOffsetY == y) { - int rvCurrentOffsetY = mRv.getCurrentScrollY(); - if (mRvOffsetY != rvCurrentOffsetY) { - mRvOffsetY = mRv.getCurrentScrollY(); - } return; } updatePopupY(y); mThumbOffsetY = y; invalidate(); - mRvOffsetY = mRv.getCurrentScrollY(); } public int getThumbOffsetY() { diff --git a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java index 35fa7a42cc..5969e3e154 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java +++ b/src/com/android/launcher3/widget/picker/WidgetsRecyclerView.java @@ -19,7 +19,6 @@ package com.android.launcher3.widget.picker; import android.content.Context; import android.graphics.Point; import android.util.AttributeSet; -import android.util.SparseIntArray; import android.view.MotionEvent; import androidx.recyclerview.widget.LinearLayoutManager; @@ -28,6 +27,7 @@ import androidx.recyclerview.widget.RecyclerView.OnItemTouchListener; import com.android.launcher3.FastScrollRecyclerView; import com.android.launcher3.R; +import com.android.launcher3.util.ScrollableLayoutManager; /** * The widgets recycler view. @@ -42,14 +42,6 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte private boolean mTouchDownOnScroller; private HeaderViewDimensionsProvider mHeaderViewDimensionsProvider; - /** - * There is always 1 or 0 item of VIEW_TYPE_WIDGETS_LIST. Other types have fixes sizes, so the - * the size can be used for all other items of same type. Caching the last know size for - * VIEW_TYPE_WIDGETS_LIST allows us to use it to estimate full size even when - * VIEW_TYPE_WIDGETS_LIST is not visible on the screen. - */ - private final SparseIntArray mCachedSizes = new SparseIntArray(); - public WidgetsRecyclerView(Context context) { this(context, null); } @@ -68,9 +60,7 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte @Override protected void onFinishInflate() { super.onFinishInflate(); - // create a layout manager with Launcher's context so that scroll position - // can be preserved during screen rotation. - setLayoutManager(new LinearLayoutManager(getContext())); + setLayoutManager(new ScrollableLayoutManager(getContext())); } @Override @@ -114,7 +104,7 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte } // Skip early if, there no child laid out in the container. - int scrollY = getCurrentScrollY(); + int scrollY = computeVerticalScrollOffset(); if (scrollY < 0) { mScrollbar.setThumbOffsetY(-1); return; @@ -163,39 +153,6 @@ public class WidgetsRecyclerView extends FastScrollRecyclerView implements OnIte mHeaderViewDimensionsProvider = headerViewDimensionsProvider; } - /** - * Returns the sum of the height, in pixels, of this list adapter's items from index 0 until - * {@code untilIndex}. - * - *

If the untilIndex is larger than the total number of items in this adapter, returns the - * sum of all items' height. - */ - @Override - protected int getItemsHeight(int untilIndex) { - // Initialize cache - int childCount = getChildCount(); - int startPosition; - if (childCount > 0 - && ((startPosition = getChildAdapterPosition(getChildAt(0))) != NO_POSITION)) { - int loopCount = Math.min(getChildCount(), getAdapter().getItemCount() - startPosition); - for (int i = 0; i < loopCount; i++) { - mCachedSizes.put( - mAdapter.getItemViewType(startPosition + i), - getChildAt(i).getMeasuredHeight()); - } - } - - if (untilIndex > mAdapter.getItems().size()) { - untilIndex = mAdapter.getItems().size(); - } - int totalItemsHeight = 0; - for (int i = 0; i < untilIndex; i++) { - int type = mAdapter.getItemViewType(i); - totalItemsHeight += mCachedSizes.get(type); - } - return totalItemsHeight; - } - /** * Provides dimensions of the header view that is shown at the top of a * {@link WidgetsRecyclerView}. diff --git a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java index 32b62fb317..70d122bc90 100644 --- a/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java +++ b/tests/src/com/android/launcher3/ui/AbstractLauncherUiTest.java @@ -537,7 +537,7 @@ public abstract class AbstractLauncherUiTest { } protected int getAllAppsScroll(Launcher launcher) { - return launcher.getAppsView().getActiveRecyclerView().getCurrentScrollY(); + return launcher.getAppsView().getActiveRecyclerView().computeVerticalScrollOffset(); } private void checkLauncherIntegrity( diff --git a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java index a3eee00c51..cf5f5fc320 100644 --- a/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java +++ b/tests/src/com/android/launcher3/ui/TaplTestsLauncher3.java @@ -302,7 +302,7 @@ public class TaplTestsLauncher3 extends AbstractLauncherUiTest { } private int getWidgetsScroll(Launcher launcher) { - return getWidgetsView(launcher).getCurrentScrollY(); + return getWidgetsView(launcher).computeVerticalScrollOffset(); } private boolean isOptionsPopupVisible(Launcher launcher) { From 0130252c00ef268dfb80d9bff9c3da90bfffd7ff Mon Sep 17 00:00:00 2001 From: Schneider Victor-tulias Date: Mon, 24 Oct 2022 10:12:45 -0700 Subject: [PATCH 112/429] Remove obsolete cancel recents animation logic This logic was used as a workaroung for 2-button navigation mode. This mode is now obsolete, however the leftover logic clashes with gesture navigation mode. Removed old logic and unused variables. Test: manually tapped nav handle, then quickly swipped up Fixes: 255348258 Change-Id: Ib4e179c0c4d9769acae24f93cfde65d2c7a4dfd9 --- .../OtherActivityInputConsumer.java | 21 ------------------- 1 file changed, 21 deletions(-) diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index 7ccd8af97a..60d5ba4f01 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -39,8 +39,6 @@ import android.content.ContextWrapper; import android.content.Intent; import android.graphics.PointF; import android.os.Build; -import android.os.Handler; -import android.os.Looper; import android.util.Log; import android.view.MotionEvent; import android.view.VelocityTracker; @@ -57,7 +55,6 @@ import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.TraceHelper; import com.android.quickstep.AbsSwipeUpHandler; import com.android.quickstep.AbsSwipeUpHandler.Factory; -import com.android.quickstep.BaseActivityInterface; import com.android.quickstep.GestureState; import com.android.quickstep.InputConsumer; import com.android.quickstep.RecentsAnimationCallbacks; @@ -70,7 +67,6 @@ import com.android.quickstep.util.ActiveGestureLog; import com.android.quickstep.util.CachedEventDispatcher; import com.android.quickstep.util.MotionPauseDetector; import com.android.quickstep.util.NavBarPosition; -import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputChannelCompat.InputEventReceiver; import com.android.systemui.shared.system.InputMonitorCompat; @@ -101,7 +97,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC private final CachedEventDispatcher mRecentsViewDispatcher = new CachedEventDispatcher(); private final InputMonitorCompat mInputMonitorCompat; private final InputEventReceiver mInputEventReceiver; - private final BaseActivityInterface mActivityInterface; private final AbsSwipeUpHandler.Factory mHandlerFactory; @@ -136,12 +131,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC // Might be displacement in X or Y, depending on the direction we are swiping from the nav bar. private float mStartDisplacement; - private Handler mMainThreadHandler; - private Runnable mCancelRecentsAnimationRunnable = () -> { - ActivityManagerWrapper.getInstance().cancelRecentsAnimation( - true /* restoreHomeStackPosition */); - }; - public OtherActivityInputConsumer(Context base, RecentsAnimationDeviceState deviceState, TaskAnimationManager taskAnimationManager, GestureState gestureState, boolean isDeferredDownTarget, Consumer onCompleteCallback, @@ -152,9 +141,7 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mNavBarPosition = mDeviceState.getNavBarPosition(); mTaskAnimationManager = taskAnimationManager; mGestureState = gestureState; - mMainThreadHandler = new Handler(Looper.getMainLooper()); mHandlerFactory = handlerFactory; - mActivityInterface = mGestureState.getActivityInterface(); mMotionPauseDetector = new MotionPauseDetector(base, false, mNavBarPosition.isLeftEdge() || mNavBarPosition.isRightEdge() @@ -437,13 +424,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } onConsumerAboutToBeSwitched(); onInteractionGestureFinished(); - - // Cancel the recents animation if SysUI happens to handle UP before we have a chance - // to start the recents animation. In addition, workaround for b/126336729 by delaying - // the cancel of the animation for a period, in case SysUI is slow to handle UP and we - // handle DOWN & UP and move the home stack before SysUI can start the activity - mMainThreadHandler.removeCallbacks(mCancelRecentsAnimationRunnable); - mMainThreadHandler.postDelayed(mCancelRecentsAnimationRunnable, 100); } cleanupAfterGesture(); TraceHelper.INSTANCE.endSection(traceToken); @@ -465,7 +445,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC @Override public void onConsumerAboutToBeSwitched() { Preconditions.assertUIThread(); - mMainThreadHandler.removeCallbacks(mCancelRecentsAnimationRunnable); if (mInteractionHandler != null) { // The consumer is being switched while we are active. Set up the shared state to be // used by the next animation From 8a114433335a36921d1617c08322b74a8df808b0 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 19 Oct 2022 16:16:10 -0700 Subject: [PATCH 113/429] Removing unnecessary RemoteAnimationTargetCompat Merged-In: I12a4c29eaf9bd7d97d3c02074b4cc1ca452fc88a Bug: 221961069 Test: Presubmit Change-Id: I12a4c29eaf9bd7d97d3c02074b4cc1ca452fc88a --- .../launcher3/LauncherAnimationRunner.java | 24 ++-- .../launcher3/LauncherInitListener.java | 6 +- .../launcher3/QuickstepTransitionManager.java | 114 +++++++++--------- .../uioverrides/QuickstepLauncher.java | 6 +- .../android/quickstep/AbsSwipeUpHandler.java | 30 ++--- .../quickstep/BaseActivityInterface.java | 4 +- .../quickstep/FallbackActivityInterface.java | 4 +- .../quickstep/FallbackSwipeHandler.java | 28 ++--- .../com/android/quickstep/GestureState.java | 6 +- .../quickstep/LauncherActivityInterface.java | 4 +- .../LauncherBackAnimationController.java | 9 +- .../quickstep/LauncherSwipeHandlerV2.java | 6 +- .../android/quickstep/RecentsActivity.java | 27 +++-- .../quickstep/RecentsAnimationCallbacks.java | 25 ++-- .../quickstep/RecentsAnimationController.java | 4 +- .../quickstep/RecentsAnimationTargets.java | 9 +- .../quickstep/RemoteAnimationTargets.java | 63 +++++----- .../android/quickstep/RemoteTargetGluer.java | 29 +++-- .../quickstep/SwipeUpAnimationLogic.java | 4 +- .../com/android/quickstep/SystemUiProxy.java | 2 + .../quickstep/TaskAnimationManager.java | 33 +++-- .../src/com/android/quickstep/TaskUtils.java | 6 +- .../com/android/quickstep/TaskViewUtils.java | 41 ++++--- .../DeviceLockedInputConsumer.java | 4 +- .../util/RemoteAnimationProvider.java | 13 +- .../util/RemoteFadeOutAnimationListener.java | 14 +-- .../util/SplitSelectStateController.java | 6 +- .../quickstep/util/TaskViewSimulator.java | 13 +- .../quickstep/util/TransformParams.java | 22 ++-- .../quickstep/views/FloatingWidgetView.java | 4 +- .../android/quickstep/views/RecentsView.java | 6 +- .../com/android/quickstep/views/TaskView.java | 10 +- .../quickstep/util/TaskViewSimulatorTest.java | 4 +- 33 files changed, 297 insertions(+), 283 deletions(-) diff --git a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java index 62603e9d54..880aa6f97b 100644 --- a/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java +++ b/quickstep/src/com/android/launcher3/LauncherAnimationRunner.java @@ -28,13 +28,13 @@ import android.annotation.TargetApi; import android.content.Context; import android.os.Build; import android.os.Handler; +import android.view.RemoteAnimationTarget; import androidx.annotation.BinderThread; import androidx.annotation.Nullable; import androidx.annotation.UiThread; import com.android.systemui.shared.system.RemoteAnimationRunnerCompat; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.lang.ref.WeakReference; @@ -82,9 +82,9 @@ public class LauncherAnimationRunner implements RemoteAnimationRunnerCompat { @BinderThread public void onAnimationStart( int transit, - RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets, - RemoteAnimationTargetCompat[] nonAppTargets, + RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets, + RemoteAnimationTarget[] nonAppTargets, Runnable runnable) { Runnable r = () -> { finishExistingAnimation(); @@ -101,17 +101,17 @@ public class LauncherAnimationRunner implements RemoteAnimationRunnerCompat { // Called only in R platform @BinderThread - public void onAnimationStart(RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets, Runnable runnable) { + public void onAnimationStart(RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets, Runnable runnable) { onAnimationStart(0 /* transit */, appTargets, wallpaperTargets, - new RemoteAnimationTargetCompat[0], runnable); + new RemoteAnimationTarget[0], runnable); } // Called only in Q platform @BinderThread @Deprecated - public void onAnimationStart(RemoteAnimationTargetCompat[] appTargets, Runnable runnable) { - onAnimationStart(appTargets, new RemoteAnimationTargetCompat[0], runnable); + public void onAnimationStart(RemoteAnimationTarget[] appTargets, Runnable runnable) { + onAnimationStart(appTargets, new RemoteAnimationTarget[0], runnable); } @@ -229,9 +229,9 @@ public class LauncherAnimationRunner implements RemoteAnimationRunnerCompat { * call {@link AnimationResult#setAnimation} with the target animation to be run. */ void onCreateAnimation(int transit, - RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets, - RemoteAnimationTargetCompat[] nonAppTargets, + RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets, + RemoteAnimationTarget[] nonAppTargets, LauncherAnimationRunner.AnimationResult result); /** diff --git a/quickstep/src/com/android/launcher3/LauncherInitListener.java b/quickstep/src/com/android/launcher3/LauncherInitListener.java index c4e85f6014..28bd701a48 100644 --- a/quickstep/src/com/android/launcher3/LauncherInitListener.java +++ b/quickstep/src/com/android/launcher3/LauncherInitListener.java @@ -19,11 +19,11 @@ import android.animation.AnimatorSet; import android.annotation.TargetApi; import android.os.Build; import android.os.CancellationSignal; +import android.view.RemoteAnimationTarget; import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.quickstep.util.ActivityInitListener; import com.android.quickstep.util.RemoteAnimationProvider; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.util.function.BiPredicate; @@ -52,8 +52,8 @@ public class LauncherInitListener extends ActivityInitListener { CancellationSignal cancellationSignal = new CancellationSignal(); appTransitionManager.setRemoteAnimationProvider(new RemoteAnimationProvider() { @Override - public AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets) { + public AnimatorSet createWindowAnimation(RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets) { // On the first call clear the reference. cancellationSignal.cancel(); diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 8239d5e892..58b3a83cea 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -17,6 +17,8 @@ package com.android.launcher3; import static android.provider.Settings.Secure.LAUNCHER_TASKBAR_EDUCATION_SHOWING; +import static android.view.RemoteAnimationTarget.MODE_CLOSING; +import static android.view.RemoteAnimationTarget.MODE_OPENING; import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_NONE; import static android.window.StartingWindowInfo.STARTING_WINDOW_TYPE_SPLASH_SCREEN; @@ -49,8 +51,6 @@ import static com.android.launcher3.views.FloatingIconView.getFloatingIconView; import static com.android.quickstep.TaskViewUtils.findTaskViewToLaunch; import static com.android.systemui.shared.system.QuickStepContract.getWindowCornerRadius; import static com.android.systemui.shared.system.QuickStepContract.supportsRoundedCornersOnWindows; -import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; -import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -81,6 +81,7 @@ import android.provider.Settings; import android.util.Pair; import android.util.Size; import android.view.CrossWindowBlurListeners; +import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.View; import android.view.ViewRootImpl; @@ -135,7 +136,6 @@ import com.android.systemui.shared.system.QuickStepContract; import com.android.systemui.shared.system.RemoteAnimationAdapterCompat; import com.android.systemui.shared.system.RemoteAnimationDefinitionCompat; import com.android.systemui.shared.system.RemoteAnimationRunnerCompat; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.RemoteTransitionCompat; import com.android.wm.shell.startingsurface.IStartingWindowListener; @@ -312,7 +312,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener * @return true if the app is launching from recents, false if it most likely is not */ protected boolean isLaunchingFromRecents(@NonNull View v, - @Nullable RemoteAnimationTargetCompat[] targets) { + @Nullable RemoteAnimationTarget[] targets) { return mLauncher.getStateManager().getState().overviewUi && findTaskViewToLaunch(mLauncher.getOverviewPanel(), v, targets) != null; } @@ -326,18 +326,18 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener * @param launcherClosing true if the launcher app is closing */ protected void composeRecentsLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v, - @NonNull RemoteAnimationTargetCompat[] appTargets, - @NonNull RemoteAnimationTargetCompat[] wallpaperTargets, - @NonNull RemoteAnimationTargetCompat[] nonAppTargets, boolean launcherClosing) { + @NonNull RemoteAnimationTarget[] appTargets, + @NonNull RemoteAnimationTarget[] wallpaperTargets, + @NonNull RemoteAnimationTarget[] nonAppTargets, boolean launcherClosing) { TaskViewUtils.composeRecentsLaunchAnimator(anim, v, appTargets, wallpaperTargets, nonAppTargets, launcherClosing, mLauncher.getStateManager(), mLauncher.getOverviewPanel(), mLauncher.getDepthController()); } - private boolean areAllTargetsTranslucent(@NonNull RemoteAnimationTargetCompat[] targets) { + private boolean areAllTargetsTranslucent(@NonNull RemoteAnimationTarget[] targets) { boolean isAllOpeningTargetTrs = true; for (int i = 0; i < targets.length; i++) { - RemoteAnimationTargetCompat target = targets[i]; + RemoteAnimationTarget target = targets[i]; if (target.mode == MODE_OPENING) { isAllOpeningTargetTrs &= target.isTranslucent; } @@ -355,9 +355,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener * @param launcherClosing true if launcher is closing */ private void composeIconLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v, - @NonNull RemoteAnimationTargetCompat[] appTargets, - @NonNull RemoteAnimationTargetCompat[] wallpaperTargets, - @NonNull RemoteAnimationTargetCompat[] nonAppTargets, + @NonNull RemoteAnimationTarget[] appTargets, + @NonNull RemoteAnimationTarget[] wallpaperTargets, + @NonNull RemoteAnimationTarget[] nonAppTargets, boolean launcherClosing) { // Set the state animation first so that any state listeners are called // before our internal listeners. @@ -399,9 +399,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener private void composeWidgetLaunchAnimator( @NonNull AnimatorSet anim, @NonNull LauncherAppWidgetHostView v, - @NonNull RemoteAnimationTargetCompat[] appTargets, - @NonNull RemoteAnimationTargetCompat[] wallpaperTargets, - @NonNull RemoteAnimationTargetCompat[] nonAppTargets) { + @NonNull RemoteAnimationTarget[] appTargets, + @NonNull RemoteAnimationTarget[] wallpaperTargets, + @NonNull RemoteAnimationTarget[] nonAppTargets) { mLauncher.getStateManager().setCurrentAnimation(anim); Rect windowTargetBounds = getWindowTargetBounds(appTargets, getRotationChange(appTargets)); @@ -424,10 +424,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener * In multiwindow mode, we need to get the final size of the opening app window target to help * figure out where the floating view should animate to. */ - private Rect getWindowTargetBounds(@NonNull RemoteAnimationTargetCompat[] appTargets, + private Rect getWindowTargetBounds(@NonNull RemoteAnimationTarget[] appTargets, int rotationChange) { - RemoteAnimationTargetCompat target = null; - for (RemoteAnimationTargetCompat t : appTargets) { + RemoteAnimationTarget target = null; + for (RemoteAnimationTarget t : appTargets) { if (t.mode != MODE_OPENING) continue; target = t; break; @@ -649,9 +649,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener * @return Animator that controls the window of the opening targets from app icons. */ private Animator getOpeningWindowAnimators(View v, - RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets, - RemoteAnimationTargetCompat[] nonAppTargets, + RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets, + RemoteAnimationTarget[] nonAppTargets, Rect windowTargetBounds, boolean appTargetsAreTranslucent, int rotationChange) { RectF launcherIconBounds = new RectF(); FloatingIconView floatingView = FloatingIconView.getFloatingIconView(mLauncher, v, @@ -664,7 +664,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener SurfaceTransactionApplier surfaceApplier = new SurfaceTransactionApplier(floatingView); openingTargets.addReleaseCheck(surfaceApplier); - RemoteAnimationTargetCompat navBarTarget = openingTargets.getNavBarRemoteAnimationTarget(); + RemoteAnimationTarget navBarTarget = openingTargets.getNavBarRemoteAnimationTarget(); int[] dragLayerBounds = new int[2]; mDragLayer.getLocationOnScreen(dragLayerBounds); @@ -819,7 +819,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener SurfaceTransaction transaction = new SurfaceTransaction(); for (int i = appTargets.length - 1; i >= 0; i--) { - RemoteAnimationTargetCompat target = appTargets[i]; + RemoteAnimationTarget target = appTargets[i]; SurfaceProperties builder = transaction.forSurface(target.leash); if (target.mode == MODE_OPENING) { @@ -902,9 +902,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener } private Animator getOpeningWindowAnimatorsForWidget(LauncherAppWidgetHostView v, - RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets, - RemoteAnimationTargetCompat[] nonAppTargets, Rect windowTargetBounds, + RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets, + RemoteAnimationTarget[] nonAppTargets, Rect windowTargetBounds, boolean appTargetsAreTranslucent) { final RectF widgetBackgroundBounds = new RectF(); final Rect appWindowCrop = new Rect(); @@ -912,7 +912,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener RemoteAnimationTargets openingTargets = new RemoteAnimationTargets(appTargets, wallpaperTargets, nonAppTargets, MODE_OPENING); - RemoteAnimationTargetCompat openingTarget = openingTargets.getFirstAppTarget(); + RemoteAnimationTarget openingTarget = openingTargets.getFirstAppTarget(); int fallbackBackgroundColor = 0; if (openingTarget != null && supportsSSplashScreen()) { fallbackBackgroundColor = mTaskStartParams.containsKey(openingTarget.taskId) @@ -936,7 +936,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener SurfaceTransactionApplier surfaceApplier = new SurfaceTransactionApplier(floatingView); openingTargets.addReleaseCheck(surfaceApplier); - RemoteAnimationTargetCompat navBarTarget = openingTargets.getNavBarRemoteAnimationTarget(); + RemoteAnimationTarget navBarTarget = openingTargets.getNavBarRemoteAnimationTarget(); AnimatorSet animatorSet = new AnimatorSet(); ValueAnimator appAnimator = ValueAnimator.ofFloat(0, 1); @@ -1003,7 +1003,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener SurfaceTransaction transaction = new SurfaceTransaction(); float floatingViewAlpha = appTargetsAreTranslucent ? 1 - mPreviewAlpha.value : 1; for (int i = appTargets.length - 1; i >= 0; i--) { - RemoteAnimationTargetCompat target = appTargets[i]; + RemoteAnimationTarget target = appTargets[i]; SurfaceProperties builder = transaction.forSurface(target.leash); if (target.mode == MODE_OPENING) { floatingView.update(widgetBackgroundBounds, floatingViewAlpha, @@ -1174,8 +1174,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener } } - private boolean launcherIsATargetWithMode(RemoteAnimationTargetCompat[] targets, int mode) { - for (RemoteAnimationTargetCompat target : targets) { + private boolean launcherIsATargetWithMode(RemoteAnimationTarget[] targets, int mode) { + for (RemoteAnimationTarget target : targets) { if (target.mode == mode && target.taskInfo != null // Compare component name instead of task-id because transitions will promote // the target up to the root task while getTaskId returns the leaf. @@ -1187,9 +1187,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener return false; } - private boolean hasMultipleTargetsWithMode(RemoteAnimationTargetCompat[] targets, int mode) { + private boolean hasMultipleTargetsWithMode(RemoteAnimationTarget[] targets, int mode) { int numTargets = 0; - for (RemoteAnimationTargetCompat target : targets) { + for (RemoteAnimationTarget target : targets) { if (target.mode == mode) { numTargets++; } @@ -1211,8 +1211,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener /** * Animator that controls the transformations of the windows when unlocking the device. */ - private Animator getUnlockWindowAnimator(RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets) { + private Animator getUnlockWindowAnimator(RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets) { SurfaceTransactionApplier surfaceApplier = new SurfaceTransactionApplier(mDragLayer); ValueAnimator unlockAnimator = ValueAnimator.ofFloat(0, 1); unlockAnimator.setDuration(CLOSING_TRANSITION_DURATION_MS); @@ -1223,7 +1223,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener public void onAnimationStart(Animator animation) { SurfaceTransaction transaction = new SurfaceTransaction(); for (int i = appTargets.length - 1; i >= 0; i--) { - RemoteAnimationTargetCompat target = appTargets[i]; + RemoteAnimationTarget target = appTargets[i]; transaction.forSurface(target.leash) .setAlpha(1f) .setWindowCrop(target.screenSpaceBounds) @@ -1235,9 +1235,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener return unlockAnimator; } - private static int getRotationChange(RemoteAnimationTargetCompat[] appTargets) { + private static int getRotationChange(RemoteAnimationTarget[] appTargets) { int rotationChange = 0; - for (RemoteAnimationTargetCompat target : appTargets) { + for (RemoteAnimationTarget target : appTargets) { if (Math.abs(target.rotationChange) > Math.abs(rotationChange)) { rotationChange = target.rotationChange; } @@ -1248,8 +1248,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener /** * Returns view on launcher that corresponds to the closing app in the list of app targets */ - private @Nullable View findLauncherView(RemoteAnimationTargetCompat[] appTargets) { - for (RemoteAnimationTargetCompat appTarget : appTargets) { + private @Nullable View findLauncherView(RemoteAnimationTarget[] appTargets) { + for (RemoteAnimationTarget appTarget : appTargets) { if (appTarget.mode == MODE_CLOSING) { View launcherView = findLauncherView(appTarget); if (launcherView != null) { @@ -1263,7 +1263,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener /** * Returns view on launcher that corresponds to the {@param runningTaskTarget}. */ - private @Nullable View findLauncherView(RemoteAnimationTargetCompat runningTaskTarget) { + private @Nullable View findLauncherView(RemoteAnimationTarget runningTaskTarget) { if (runningTaskTarget == null || runningTaskTarget.taskInfo == null) { return null; } @@ -1324,15 +1324,15 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener * Closing animator that animates the window into its final location on the workspace. */ private RectFSpringAnim getClosingWindowAnimators(AnimatorSet animation, - RemoteAnimationTargetCompat[] targets, View launcherView, PointF velocityPxPerS, + RemoteAnimationTarget[] targets, View launcherView, PointF velocityPxPerS, RectF closingWindowStartRect, float startWindowCornerRadius) { FloatingIconView floatingIconView = null; FloatingWidgetView floatingWidget = null; RectF targetRect = new RectF(); - RemoteAnimationTargetCompat runningTaskTarget = null; + RemoteAnimationTarget runningTaskTarget = null; boolean isTransluscent = false; - for (RemoteAnimationTargetCompat target : targets) { + for (RemoteAnimationTarget target : targets) { if (target.mode == MODE_CLOSING) { runningTaskTarget = target; isTransluscent = runningTaskTarget.isTranslucent; @@ -1426,7 +1426,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener /** * Closing window animator that moves the window down and offscreen. */ - private Animator getFallbackClosingWindowAnimators(RemoteAnimationTargetCompat[] appTargets) { + private Animator getFallbackClosingWindowAnimators(RemoteAnimationTarget[] appTargets) { final int rotationChange = getRotationChange(appTargets); SurfaceTransactionApplier surfaceApplier = new SurfaceTransactionApplier(mDragLayer); Matrix matrix = new Matrix(); @@ -1449,7 +1449,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener public void onUpdate(float percent, boolean initOnly) { SurfaceTransaction transaction = new SurfaceTransaction(); for (int i = appTargets.length - 1; i >= 0; i--) { - RemoteAnimationTargetCompat target = appTargets[i]; + RemoteAnimationTarget target = appTargets[i]; SurfaceProperties builder = transaction.forSurface(target.leash); if (target.localBounds != null) { @@ -1548,8 +1548,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener * the transition. */ public Pair createWallpaperOpenAnimations( - RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets, + RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets, boolean fromUnlock, RectF startRect, float startWindowCornerRadius) { @@ -1658,9 +1658,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener @Override public void onCreateAnimation(int transit, - RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets, - RemoteAnimationTargetCompat[] nonAppTargets, + RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets, + RemoteAnimationTarget[] nonAppTargets, LauncherAnimationRunner.AnimationResult result) { if (mLauncher.isDestroyed()) { AnimatorSet anim = new AnimatorSet(); @@ -1699,9 +1699,9 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener @Override public void onCreateAnimation(int transit, - RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets, - RemoteAnimationTargetCompat[] nonAppTargets, + RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets, + RemoteAnimationTarget[] nonAppTargets, LauncherAnimationRunner.AnimationResult result) { AnimatorSet anim = new AnimatorSet(); boolean launcherClosing = @@ -1828,7 +1828,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener * RectFSpringAnim update listener to be used for app to home animation. */ private class SpringAnimRunner implements RectFSpringAnim.OnUpdateListener { - private final RemoteAnimationTargetCompat[] mAppTargets; + private final RemoteAnimationTarget[] mAppTargets; private final Matrix mMatrix = new Matrix(); private final Point mTmpPos = new Point(); private final Rect mCurrentRect = new Rect(); @@ -1839,7 +1839,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener private final Rect mTmpRect = new Rect(); - SpringAnimRunner(RemoteAnimationTargetCompat[] appTargets, RectF targetRect, + SpringAnimRunner(RemoteAnimationTarget[] appTargets, RectF targetRect, Rect windowTargetBounds, float startWindowCornerRadius) { mAppTargets = appTargets; mStartRadius = startWindowCornerRadius; @@ -1856,7 +1856,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener public void onUpdate(RectF currentRectF, float progress) { SurfaceTransaction transaction = new SurfaceTransaction(); for (int i = mAppTargets.length - 1; i >= 0; i--) { - RemoteAnimationTargetCompat target = mAppTargets[i]; + RemoteAnimationTarget target = mAppTargets[i]; SurfaceProperties builder = transaction.forSurface(target.leash); if (target.localBounds != null) { diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 3203f44ce2..c2c7f6f6b7 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -65,6 +65,7 @@ import android.os.IBinder; import android.os.SystemProperties; import android.view.Display; import android.view.HapticFeedbackConstants; +import android.view.RemoteAnimationTarget; import android.view.View; import android.view.WindowManagerGlobal; import android.window.SplashScreen; @@ -139,7 +140,6 @@ import com.android.quickstep.views.OverviewActionsView; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.unfold.UnfoldSharedComponent; import com.android.systemui.unfold.UnfoldTransitionFactory; import com.android.systemui.unfold.UnfoldTransitionProgressProvider; @@ -761,8 +761,8 @@ public class QuickstepLauncher extends Launcher { QuickstepTransitionManager appTransitionManager = getAppTransitionManager(); appTransitionManager.setRemoteAnimationProvider(new RemoteAnimationProvider() { @Override - public AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets) { + public AnimatorSet createWindowAnimation(RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets) { // On the first call clear the reference. signal.cancel(); diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index d728b7539b..f5dc03af9e 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -15,6 +15,7 @@ */ package com.android.quickstep; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; import static android.view.Surface.ROTATION_0; import static android.view.Surface.ROTATION_270; import static android.view.Surface.ROTATION_90; @@ -52,7 +53,6 @@ import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent import static com.android.quickstep.util.VibratorWrapper.OVERVIEW_HAPTIC; 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; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -73,6 +73,7 @@ import android.os.IBinder; import android.os.SystemClock; import android.util.Log; import android.view.MotionEvent; +import android.view.RemoteAnimationTarget; import android.view.View; import android.view.View.OnApplyWindowInsetsListener; import android.view.ViewGroup; @@ -128,7 +129,6 @@ import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputConsumerController; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.wm.shell.common.TransactionPool; @@ -683,7 +683,7 @@ public abstract class AbsSwipeUpHandler, if (!mDeviceState.isFullyGesturalNavMode() || mRecentsView == null) { return; } - RemoteAnimationTargetCompat runningTaskTarget = mRecentsAnimationTargets != null + RemoteAnimationTarget runningTaskTarget = mRecentsAnimationTargets != null ? mRecentsAnimationTargets.findTask(mGestureState.getRunningTaskId()) : null; final boolean recentsAttachedToAppWindow; @@ -867,7 +867,7 @@ public abstract class AbsSwipeUpHandler, // Only initialize the device profile, if it has not been initialized before, as in some // configurations targets.homeContentInsets may not be correct. if (mActivity == null) { - RemoteAnimationTargetCompat primaryTaskTarget = targets.apps[0]; + RemoteAnimationTarget primaryTaskTarget = targets.apps[0]; // orientation state is independent of which remote target handle we use since both // should be pointing to the same one. Just choose index 0 for now since that works for // both split and non-split @@ -1076,7 +1076,7 @@ public abstract class AbsSwipeUpHandler, } /** @return Whether this was the task we were waiting to appear, and thus handled it. */ - protected boolean handleTaskAppeared(RemoteAnimationTargetCompat[] appearedTaskTarget) { + protected boolean handleTaskAppeared(RemoteAnimationTarget[] appearedTaskTarget) { if (mStateCallback.hasStates(STATE_HANDLER_INVALIDATED)) { return false; } @@ -1315,7 +1315,7 @@ public abstract class AbsSwipeUpHandler, protected abstract HomeAnimationFactory createHomeAnimationFactory( ArrayList launchCookies, long duration, boolean isTargetTranslucent, - boolean appCanEnterPip, RemoteAnimationTargetCompat runningTaskTarget); + boolean appCanEnterPip, RemoteAnimationTarget runningTaskTarget); private final TaskStackChangeListener mActivityRestartListener = new TaskStackChangeListener() { @Override @@ -1362,7 +1362,7 @@ public abstract class AbsSwipeUpHandler, if (mGestureState.getEndTarget() == HOME) { getOrientationHandler().adjustFloatingIconStartVelocity(velocityPxPerMs); - final RemoteAnimationTargetCompat runningTaskTarget = mRecentsAnimationTargets != null + final RemoteAnimationTarget runningTaskTarget = mRecentsAnimationTargets != null ? mRecentsAnimationTargets.findTask(mGestureState.getRunningTaskId()) : null; final ArrayList cookies = runningTaskTarget != null @@ -1472,7 +1472,7 @@ public abstract class AbsSwipeUpHandler, } } - private int calculateWindowRotation(RemoteAnimationTargetCompat runningTaskTarget, + private int calculateWindowRotation(RemoteAnimationTarget runningTaskTarget, RecentsOrientedState orientationState) { if (runningTaskTarget.rotationChange != 0 && TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) { @@ -1485,7 +1485,7 @@ public abstract class AbsSwipeUpHandler, @Nullable private SwipePipToHomeAnimator createWindowAnimationToPip(HomeAnimationFactory homeAnimFactory, - RemoteAnimationTargetCompat runningTaskTarget, float startProgress) { + RemoteAnimationTarget runningTaskTarget, float startProgress) { // Directly animate the app to PiP (picture-in-picture) mode final ActivityManager.RunningTaskInfo taskInfo = runningTaskTarget.taskInfo; final RecentsOrientedState orientationState = mRemoteTargetHandles[0].getTaskViewSimulator() @@ -1959,9 +1959,9 @@ public abstract class AbsSwipeUpHandler, reset(); } - private static boolean isNotInRecents(RemoteAnimationTargetCompat app) { + private static boolean isNotInRecents(RemoteAnimationTarget app) { return app.isNotInRecents - || app.activityType == ACTIVITY_TYPE_HOME; + || app.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME; } /** @@ -2084,10 +2084,10 @@ public abstract class AbsSwipeUpHandler, } @Override - public void onTasksAppeared(RemoteAnimationTargetCompat[] appearedTaskTargets) { + public void onTasksAppeared(RemoteAnimationTarget[] appearedTaskTargets) { if (mRecentsAnimationController != null) { if (handleTaskAppeared(appearedTaskTargets)) { - Optional taskTargetOptional = + Optional taskTargetOptional = Arrays.stream(appearedTaskTargets) .filter(targetCompat -> targetCompat.taskId == mGestureState.getLastStartedTaskId()) @@ -2096,7 +2096,7 @@ public abstract class AbsSwipeUpHandler, finishRecentsAnimationOnTasksAppeared(); return; } - RemoteAnimationTargetCompat taskTarget = taskTargetOptional.get(); + RemoteAnimationTarget taskTarget = taskTargetOptional.get(); TaskView taskView = mRecentsView.getTaskViewByTaskId(taskTarget.taskId); if (taskView == null || !taskView.getThumbnail().shouldShowSplashView()) { finishRecentsAnimationOnTasksAppeared(); @@ -2110,7 +2110,7 @@ public abstract class AbsSwipeUpHandler, SurfaceTransactionApplier surfaceApplier = new SurfaceTransactionApplier(splashView); SurfaceTransaction transaction = new SurfaceTransaction(); - for (RemoteAnimationTargetCompat target : appearedTaskTargets) { + for (RemoteAnimationTarget target : appearedTaskTargets) { transaction.forSurface(target.leash).setAlpha(1).setLayer(-1); } surfaceApplier.scheduleApply(transaction); diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java index d4320043b0..cf640b5c09 100644 --- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java +++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java @@ -40,6 +40,7 @@ import android.graphics.Rect; import android.os.Build; import android.view.Gravity; import android.view.MotionEvent; +import android.view.RemoteAnimationTarget; import android.view.View; import androidx.annotation.Nullable; @@ -62,7 +63,6 @@ import com.android.quickstep.util.ActivityInitListener; import com.android.quickstep.util.AnimatorControllerWithResistance; import com.android.quickstep.views.RecentsView; import com.android.systemui.shared.recents.model.ThumbnailData; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.util.HashMap; import java.util.Optional; @@ -162,7 +162,7 @@ public abstract class BaseActivityInterface launchCookies, long duration, boolean isTargetTranslucent, boolean appCanEnterPip, - RemoteAnimationTargetCompat runningTaskTarget) { + RemoteAnimationTarget runningTaskTarget) { mAppCanEnterPip = appCanEnterPip; if (appCanEnterPip) { return new FallbackPipToHomeAnimationFactory(); @@ -154,7 +154,7 @@ public class FallbackSwipeHandler extends private void startHomeIntent( @Nullable FallbackHomeAnimationFactory gestureContractAnimationFactory, - @Nullable RemoteAnimationTargetCompat runningTaskTarget) { + @Nullable RemoteAnimationTarget runningTaskTarget) { ActivityOptions options = ActivityOptions.makeCustomAnimation(mContext, 0, 0); Intent intent = new Intent(mGestureState.getHomeIntent()); if (gestureContractAnimationFactory != null && runningTaskTarget != null) { @@ -164,7 +164,7 @@ public class FallbackSwipeHandler extends } @Override - protected boolean handleTaskAppeared(RemoteAnimationTargetCompat[] appearedTaskTarget) { + protected boolean handleTaskAppeared(RemoteAnimationTarget[] appearedTaskTarget) { if (mActiveAnimationFactory != null && mActiveAnimationFactory.handleHomeTaskAppeared(appearedTaskTarget)) { mActiveAnimationFactory = null; @@ -280,12 +280,12 @@ public class FallbackSwipeHandler extends } private void updateRecentsActivityTransformDuringHomeAnim(SurfaceProperties builder, - RemoteAnimationTargetCompat app, TransformParams params) { + RemoteAnimationTarget app, TransformParams params) { builder.setAlpha(mRecentsAlpha.value); } private void updateHomeActivityTransformDuringHomeAnim(SurfaceProperties builder, - RemoteAnimationTargetCompat app, TransformParams params) { + RemoteAnimationTarget app, TransformParams params) { setHomeScaleAndAlpha(builder, app, mVerticalShiftForScale.value, mHomeAlpha.value); } @@ -304,12 +304,12 @@ public class FallbackSwipeHandler extends } } - public boolean handleHomeTaskAppeared(RemoteAnimationTargetCompat[] appearedTaskTargets) { - RemoteAnimationTargetCompat appearedTaskTarget = appearedTaskTargets[0]; - if (appearedTaskTarget.activityType == ACTIVITY_TYPE_HOME) { + public boolean handleHomeTaskAppeared(RemoteAnimationTarget[] appearedTaskTargets) { + RemoteAnimationTarget appearedTaskTarget = appearedTaskTargets[0]; + if (appearedTaskTarget.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME) { RemoteAnimationTargets targets = new RemoteAnimationTargets( - new RemoteAnimationTargetCompat[] {appearedTaskTarget}, - new RemoteAnimationTargetCompat[0], new RemoteAnimationTargetCompat[0], + new RemoteAnimationTarget[] {appearedTaskTarget}, + new RemoteAnimationTarget[0], new RemoteAnimationTarget[0], appearedTaskTarget.mode); mHomeAlphaParams.setTargetSet(targets); updateHomeAlpha(); diff --git a/quickstep/src/com/android/quickstep/GestureState.java b/quickstep/src/com/android/quickstep/GestureState.java index bcd96878e3..3c4ee75aae 100644 --- a/quickstep/src/com/android/quickstep/GestureState.java +++ b/quickstep/src/com/android/quickstep/GestureState.java @@ -28,6 +28,7 @@ import android.annotation.Nullable; import android.annotation.TargetApi; import android.content.Intent; import android.os.Build; +import android.view.RemoteAnimationTarget; import com.android.launcher3.statemanager.BaseState; import com.android.launcher3.statemanager.StatefulActivity; @@ -37,7 +38,6 @@ import com.android.quickstep.TopTaskTracker.CachedTaskInfo; import com.android.quickstep.util.ActiveGestureErrorDetector; import com.android.quickstep.util.ActiveGestureLog; import com.android.systemui.shared.recents.model.ThumbnailData; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.io.PrintWriter; import java.util.ArrayList; @@ -143,7 +143,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL private CachedTaskInfo mRunningTask; private GestureEndTarget mEndTarget; - private RemoteAnimationTargetCompat mLastAppearedTaskTarget; + private RemoteAnimationTarget mLastAppearedTaskTarget; private Set mPreviouslyAppearedTaskIds = new HashSet<>(); private int mLastStartedTaskId = -1; private RecentsAnimationController mRecentsAnimationController; @@ -272,7 +272,7 @@ public class GestureState implements RecentsAnimationCallbacks.RecentsAnimationL /** * Updates the last task that appeared during this gesture. */ - public void updateLastAppearedTaskTarget(RemoteAnimationTargetCompat lastAppearedTaskTarget) { + public void updateLastAppearedTaskTarget(RemoteAnimationTarget lastAppearedTaskTarget) { mLastAppearedTaskTarget = lastAppearedTaskTarget; if (lastAppearedTaskTarget != null) { mPreviouslyAppearedTaskIds.add(lastAppearedTaskTarget.taskId); diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java index 8522a87ba7..686c0e4fb3 100644 --- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java +++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java @@ -28,6 +28,7 @@ import android.animation.AnimatorSet; import android.content.Context; import android.graphics.Rect; import android.view.MotionEvent; +import android.view.RemoteAnimationTarget; import androidx.annotation.Nullable; import androidx.annotation.UiThread; @@ -51,7 +52,6 @@ import com.android.quickstep.util.AnimatorControllerWithResistance; import com.android.quickstep.util.LayoutUtils; import com.android.quickstep.views.RecentsView; import com.android.systemui.plugins.shared.LauncherOverlayManager; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.util.function.Consumer; import java.util.function.Predicate; @@ -252,7 +252,7 @@ public final class LauncherActivityInterface extends } @Override - public Rect getOverviewWindowBounds(Rect homeBounds, RemoteAnimationTargetCompat target) { + public Rect getOverviewWindowBounds(Rect homeBounds, RemoteAnimationTarget target) { return homeBounds; } diff --git a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java index ee3b0752b9..42b12552bd 100644 --- a/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java +++ b/quickstep/src/com/android/quickstep/LauncherBackAnimationController.java @@ -45,7 +45,6 @@ import com.android.launcher3.Utilities; import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.quickstep.util.RectFSpringAnim; import com.android.systemui.shared.system.QuickStepContract; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; /** * Controls the animation of swiping back and returning to launcher. @@ -83,7 +82,7 @@ public class LauncherBackAnimationController { private final Interpolator mCancelInterpolator; private final PointF mInitialTouchPos = new PointF(); - private RemoteAnimationTargetCompat mBackTarget; + private RemoteAnimationTarget mBackTarget; private SurfaceControl.Transaction mTransaction = new SurfaceControl.Transaction(); private boolean mSpringAnimationInProgress = false; private boolean mAnimatorSetInProgress = false; @@ -182,7 +181,7 @@ public class LauncherBackAnimationController { mTransaction.show(appTarget.leash).apply(); mTransaction.setAnimationTransaction(); - mBackTarget = new RemoteAnimationTargetCompat(appTarget); + mBackTarget = appTarget; mInitialTouchPos.set(backEvent.getTouchX(), backEvent.getTouchY()); // TODO(b/218916755): Offset start rectangle in multiwindow mode. @@ -280,8 +279,8 @@ public class LauncherBackAnimationController { mBackProgress, mWindowScaleStartCornerRadius, mWindowScaleEndCornerRadius); Pair pair = mQuickstepTransitionManager.createWallpaperOpenAnimations( - new RemoteAnimationTargetCompat[]{mBackTarget}, - new RemoteAnimationTargetCompat[]{}, + new RemoteAnimationTarget[]{mBackTarget}, + new RemoteAnimationTarget[0], false /* fromUnlock */, mCurrentRect, cornerRadius); diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java index d1533f0347..bb781c82b7 100644 --- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java +++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java @@ -30,6 +30,7 @@ import android.graphics.RectF; import android.os.IBinder; import android.os.UserHandle; import android.util.Size; +import android.view.RemoteAnimationTarget; import android.view.View; import androidx.annotation.NonNull; @@ -49,7 +50,6 @@ import com.android.quickstep.views.FloatingWidgetView; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.system.InputConsumerController; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.util.ArrayList; @@ -70,7 +70,7 @@ public class LauncherSwipeHandlerV2 extends @Override protected HomeAnimationFactory createHomeAnimationFactory(ArrayList launchCookies, long duration, boolean isTargetTranslucent, boolean appCanEnterPip, - RemoteAnimationTargetCompat runningTaskTarget) { + RemoteAnimationTarget runningTaskTarget) { if (mActivity == null) { mStateCallback.addChangeListener(STATE_LAUNCHER_PRESENT | STATE_HANDLER_INVALIDATED, isPresent -> mRecentsView.startHome()); @@ -144,7 +144,7 @@ public class LauncherSwipeHandlerV2 extends private HomeAnimationFactory createWidgetHomeAnimationFactory( LauncherAppWidgetHostView hostView, boolean isTargetTranslucent, - RemoteAnimationTargetCompat runningTaskTarget) { + RemoteAnimationTarget runningTaskTarget) { final float floatingWidgetAlpha = isTargetTranslucent ? 0 : 1; RectF backgroundLocation = new RectF(); Rect crop = new Rect(); diff --git a/quickstep/src/com/android/quickstep/RecentsActivity.java b/quickstep/src/com/android/quickstep/RecentsActivity.java index 4f5e216336..97ce30fda7 100644 --- a/quickstep/src/com/android/quickstep/RecentsActivity.java +++ b/quickstep/src/com/android/quickstep/RecentsActivity.java @@ -15,6 +15,9 @@ */ package com.android.quickstep; +import static android.view.RemoteAnimationTarget.MODE_CLOSING; +import static android.view.RemoteAnimationTarget.MODE_OPENING; + import static com.android.launcher3.QuickstepTransitionManager.RECENTS_LAUNCH_DURATION; import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_DURATION; import static com.android.launcher3.QuickstepTransitionManager.STATUS_BAR_TRANSITION_PRE_DELAY; @@ -23,8 +26,6 @@ import static com.android.launcher3.testing.shared.TestProtocol.OVERVIEW_STATE_O import static com.android.quickstep.OverviewComponentObserver.startHomeIntentSafely; import static com.android.quickstep.TaskUtils.taskIsATargetWithMode; import static com.android.quickstep.TaskViewUtils.createRecentsWindowAnimator; -import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; -import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -36,6 +37,7 @@ import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.view.Display; +import android.view.RemoteAnimationTarget; import android.view.SurfaceControl.Transaction; import android.view.View; import android.window.SplashScreen; @@ -78,7 +80,6 @@ import com.android.quickstep.views.OverviewActionsView; import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import com.android.systemui.shared.system.RemoteAnimationAdapterCompat; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.io.FileDescriptor; import java.io.PrintWriter; @@ -238,9 +239,9 @@ public final class RecentsActivity extends StatefulActivity { mActivityLaunchAnimationRunner = new RemoteAnimationFactory() { @Override - public void onCreateAnimation(int transit, RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets, - RemoteAnimationTargetCompat[] nonAppTargets, AnimationResult result) { + public void onCreateAnimation(int transit, RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets, + RemoteAnimationTarget[] nonAppTargets, AnimationResult result) { mHandler.removeCallbacks(mAnimationStartTimeoutRunnable); AnimatorSet anim = composeRecentsLaunchAnimator(taskView, appTargets, wallpaperTargets, nonAppTargets); @@ -279,9 +280,9 @@ public final class RecentsActivity extends StatefulActivity { * Composes the animations for a launch from the recents list if possible. */ private AnimatorSet composeRecentsLaunchAnimator(TaskView taskView, - RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets, - RemoteAnimationTargetCompat[] nonAppTargets) { + RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets, + RemoteAnimationTarget[] nonAppTargets) { AnimatorSet target = new AnimatorSet(); boolean activityClosing = taskIsATargetWithMode(appTargets, getTaskId(), MODE_CLOSING); PendingAnimation pa = new PendingAnimation(RECENTS_LAUNCH_DURATION); @@ -412,16 +413,16 @@ public final class RecentsActivity extends StatefulActivity { private final RemoteAnimationFactory mAnimationToHomeFactory = new RemoteAnimationFactory() { @Override - public void onCreateAnimation(int transit, RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets, - RemoteAnimationTargetCompat[] nonAppTargets, AnimationResult result) { + public void onCreateAnimation(int transit, RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets, + RemoteAnimationTarget[] nonAppTargets, AnimationResult result) { AnimatorPlaybackController controller = getStateManager() .createAnimationToNewWorkspace(RecentsState.BG_LAUNCHER, HOME_APPEAR_DURATION); controller.dispatchOnStart(); RemoteAnimationTargets targets = new RemoteAnimationTargets( appTargets, wallpaperTargets, nonAppTargets, MODE_OPENING); - for (RemoteAnimationTargetCompat app : targets.apps) { + for (RemoteAnimationTarget app : targets.apps) { new Transaction().setAlpha(app.leash, 1).apply(); } AnimatorSet anim = new AnimatorSet(); diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java index b233521ff2..2451ad813b 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java @@ -33,9 +33,7 @@ import com.android.quickstep.util.ActiveGestureErrorDetector; import com.android.quickstep.util.ActiveGestureLog; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.RecentsAnimationControllerCompat; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; -import java.util.Arrays; import java.util.HashMap; import java.util.Set; @@ -88,17 +86,17 @@ public class RecentsAnimationCallbacks implements @BinderThread @Deprecated public final void onAnimationStart(RecentsAnimationControllerCompat controller, - RemoteAnimationTargetCompat[] appTargets, Rect homeContentInsets, + RemoteAnimationTarget[] appTargets, Rect homeContentInsets, Rect minimizedHomeBounds) { - onAnimationStart(controller, appTargets, new RemoteAnimationTargetCompat[0], + onAnimationStart(controller, appTargets, new RemoteAnimationTarget[0], homeContentInsets, minimizedHomeBounds); } // Called only in R+ platform @BinderThread public final void onAnimationStart(RecentsAnimationControllerCompat animationController, - RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets, + RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets, Rect homeContentInsets, Rect minimizedHomeBounds) { mController = new RecentsAnimationController(animationController, mAllowMinimizeSplitScreen, this::onAnimationFinished); @@ -107,12 +105,13 @@ public class RecentsAnimationCallbacks implements Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), mController::finishAnimationToApp); } else { - final RemoteAnimationTarget[] nonAppTargets = mSystemUiProxy.onGoingToRecentsLegacy( - Arrays.stream(appTargets).map(RemoteAnimationTargetCompat::unwrap) - .toArray(RemoteAnimationTarget[]::new)); + RemoteAnimationTarget[] nonAppTargets = + mSystemUiProxy.onGoingToRecentsLegacy(appTargets); + if (nonAppTargets == null) { + nonAppTargets = new RemoteAnimationTarget[0]; + } final RecentsAnimationTargets targets = new RecentsAnimationTargets(appTargets, - wallpaperTargets, RemoteAnimationTargetCompat.wrap(nonAppTargets), - homeContentInsets, minimizedHomeBounds); + wallpaperTargets, nonAppTargets, homeContentInsets, minimizedHomeBounds); Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> { ActiveGestureLog.INSTANCE.addLog( @@ -141,7 +140,7 @@ public class RecentsAnimationCallbacks implements @BinderThread @Override - public void onTasksAppeared(RemoteAnimationTargetCompat[] apps) { + public void onTasksAppeared(RemoteAnimationTarget[] apps) { Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(), () -> { ActiveGestureLog.INSTANCE.addLog("onTasksAppeared", ActiveGestureErrorDetector.GestureEvent.TASK_APPEARED); @@ -197,7 +196,7 @@ public class RecentsAnimationCallbacks implements /** * Callback made when a task started from the recents is ready for an app transition. */ - default void onTasksAppeared(@NonNull RemoteAnimationTargetCompat[] appearedTaskTarget) {} + default void onTasksAppeared(@NonNull RemoteAnimationTarget[] appearedTaskTarget) {} /** * @return whether this will call onFinished or not (onFinished should only be called once). diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java index 542c0d4b21..81e3782142 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java @@ -23,6 +23,7 @@ import android.content.Context; import android.os.RemoteException; import android.util.Log; import android.view.IRecentsAnimationController; +import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.WindowManagerGlobal; import android.window.PictureInPictureSurfaceTransaction; @@ -37,7 +38,6 @@ import com.android.quickstep.util.ActiveGestureLog; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import com.android.systemui.shared.system.RecentsAnimationControllerCompat; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.util.function.Consumer; @@ -114,7 +114,7 @@ public class RecentsAnimationController { * {@link RecentsAnimationCallbacks#onTasksAppeared}}. */ @UiThread - public void removeTaskTarget(@NonNull RemoteAnimationTargetCompat target) { + public void removeTaskTarget(@NonNull RemoteAnimationTarget target) { UI_HELPER_EXECUTOR.execute(() -> mController.removeTask(target.taskId)); } diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java b/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java index b6d9016727..388e1256d8 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationTargets.java @@ -15,11 +15,10 @@ */ package com.android.quickstep; -import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; +import static android.view.RemoteAnimationTarget.MODE_CLOSING; import android.graphics.Rect; - -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; +import android.view.RemoteAnimationTarget; /** * Extension of {@link RemoteAnimationTargets} with additional information about swipe @@ -30,8 +29,8 @@ public class RecentsAnimationTargets extends RemoteAnimationTargets { public final Rect homeContentInsets; public final Rect minimizedHomeBounds; - public RecentsAnimationTargets(RemoteAnimationTargetCompat[] apps, - RemoteAnimationTargetCompat[] wallpapers, RemoteAnimationTargetCompat[] nonApps, + public RecentsAnimationTargets(RemoteAnimationTarget[] apps, + RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, Rect homeContentInsets, Rect minimizedHomeBounds) { super(apps, wallpapers, nonApps, MODE_CLOSING); this.homeContentInsets = homeContentInsets; diff --git a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java index 1bd808d13d..80aaad0dd9 100644 --- a/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java +++ b/quickstep/src/com/android/quickstep/RemoteAnimationTargets.java @@ -15,9 +15,11 @@ */ package com.android.quickstep; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; +import android.view.RemoteAnimationTarget; import java.util.ArrayList; import java.util.concurrent.CopyOnWriteArrayList; @@ -29,41 +31,40 @@ public class RemoteAnimationTargets { private final CopyOnWriteArrayList mReleaseChecks = new CopyOnWriteArrayList<>(); - public final RemoteAnimationTargetCompat[] unfilteredApps; - public final RemoteAnimationTargetCompat[] apps; - public final RemoteAnimationTargetCompat[] wallpapers; - public final RemoteAnimationTargetCompat[] nonApps; + public final RemoteAnimationTarget[] unfilteredApps; + public final RemoteAnimationTarget[] apps; + public final RemoteAnimationTarget[] wallpapers; + public final RemoteAnimationTarget[] nonApps; public final int targetMode; public final boolean hasRecents; private boolean mReleased = false; - public RemoteAnimationTargets(RemoteAnimationTargetCompat[] apps, - RemoteAnimationTargetCompat[] wallpapers, RemoteAnimationTargetCompat[] nonApps, + public RemoteAnimationTargets(RemoteAnimationTarget[] apps, + RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, int targetMode) { - ArrayList filteredApps = new ArrayList<>(); + ArrayList filteredApps = new ArrayList<>(); boolean hasRecents = false; if (apps != null) { - for (RemoteAnimationTargetCompat target : apps) { + for (RemoteAnimationTarget target : apps) { if (target.mode == targetMode) { filteredApps.add(target); } - hasRecents |= target.activityType == - RemoteAnimationTargetCompat.ACTIVITY_TYPE_RECENTS; + hasRecents |= target.windowConfiguration.getActivityType() == ACTIVITY_TYPE_RECENTS; } } this.unfilteredApps = apps; - this.apps = filteredApps.toArray(new RemoteAnimationTargetCompat[filteredApps.size()]); + this.apps = filteredApps.toArray(new RemoteAnimationTarget[filteredApps.size()]); this.wallpapers = wallpapers; this.targetMode = targetMode; this.hasRecents = hasRecents; this.nonApps = nonApps; } - public RemoteAnimationTargetCompat findTask(int taskId) { - for (RemoteAnimationTargetCompat target : apps) { + public RemoteAnimationTarget findTask(int taskId) { + for (RemoteAnimationTarget target : apps) { if (target.taskId == taskId) { return target; } @@ -74,12 +75,12 @@ public class RemoteAnimationTargets { /** * Gets the navigation bar remote animation target if exists. */ - public RemoteAnimationTargetCompat getNavBarRemoteAnimationTarget() { + public RemoteAnimationTarget getNavBarRemoteAnimationTarget() { return getNonAppTargetOfType(TYPE_NAVIGATION_BAR); } - public RemoteAnimationTargetCompat getNonAppTargetOfType(int type) { - for (RemoteAnimationTargetCompat target : nonApps) { + public RemoteAnimationTarget getNonAppTargetOfType(int type) { + for (RemoteAnimationTarget target : nonApps) { if (target.windowType == type) { return target; } @@ -88,19 +89,19 @@ public class RemoteAnimationTargets { } /** Returns the first opening app target. */ - public RemoteAnimationTargetCompat getFirstAppTarget() { + public RemoteAnimationTarget getFirstAppTarget() { return apps.length > 0 ? apps[0] : null; } /** Returns the task id of the first opening app target, or -1 if none is found. */ public int getFirstAppTargetTaskId() { - RemoteAnimationTargetCompat target = getFirstAppTarget(); + RemoteAnimationTarget target = getFirstAppTarget(); return target == null ? -1 : target.taskId; } public boolean isAnimatingHome() { - for (RemoteAnimationTargetCompat target : unfilteredApps) { - if (target.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) { + for (RemoteAnimationTarget target : unfilteredApps) { + if (target.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME) { return true; } } @@ -123,15 +124,19 @@ public class RemoteAnimationTargets { } mReleaseChecks.clear(); mReleased = true; + release(unfilteredApps); + release(wallpapers); + release(nonApps); + } - for (RemoteAnimationTargetCompat target : unfilteredApps) { - target.release(); - } - for (RemoteAnimationTargetCompat target : wallpapers) { - target.release(); - } - for (RemoteAnimationTargetCompat target : nonApps) { - target.release(); + private static void release(RemoteAnimationTarget[] targets) { + for (RemoteAnimationTarget target : targets) { + if (target.leash != null) { + target.leash.release(); + } + if (target.startLeash != null) { + target.startLeash.release(); + } } } diff --git a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java index 7183c49ca2..4c41bef26a 100644 --- a/quickstep/src/com/android/quickstep/RemoteTargetGluer.java +++ b/quickstep/src/com/android/quickstep/RemoteTargetGluer.java @@ -17,6 +17,8 @@ package com.android.quickstep; import android.content.Context; +import android.graphics.Rect; +import android.view.RemoteAnimationTarget; import androidx.annotation.Nullable; @@ -24,7 +26,6 @@ import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds; import com.android.quickstep.util.AnimatorControllerWithResistance; import com.android.quickstep.util.TaskViewSimulator; import com.android.quickstep.util.TransformParams; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.util.ArrayList; @@ -75,7 +76,7 @@ public class RemoteTargetGluer { */ public RemoteTargetHandle[] assignTargets(RemoteAnimationTargets targets) { for (int i = 0; i < mRemoteTargetHandles.length; i++) { - RemoteAnimationTargetCompat primaryTaskTarget = targets.apps[i]; + RemoteAnimationTarget primaryTaskTarget = targets.apps[i]; mRemoteTargetHandles[i].mTransformParams.setTargetSet( createRemoteAnimationTargetsForTarget(targets, null)); mRemoteTargetHandles[i].mTaskViewSimulator.setPreview(primaryTaskTarget, null); @@ -100,8 +101,8 @@ public class RemoteTargetGluer { */ public RemoteTargetHandle[] assignTargetsForSplitScreen(RemoteAnimationTargets targets, int[] splitIds) { - RemoteAnimationTargetCompat topLeftTarget; // only one set if single/fullscreen task - RemoteAnimationTargetCompat bottomRightTarget; + RemoteAnimationTarget topLeftTarget; // only one set if single/fullscreen task + RemoteAnimationTarget bottomRightTarget; if (mRemoteTargetHandles.length == 1) { // If we're not in split screen, the splitIds count doesn't really matter since we // should always hit this case. @@ -119,8 +120,8 @@ public class RemoteTargetGluer { // remoteTargetHandle[0] denotes topLeft task, so we pass in the bottomRight to exclude, // vice versa mSplitBounds = new SplitBounds( - topLeftTarget.startScreenSpaceBounds, - bottomRightTarget.startScreenSpaceBounds, splitIds[0], splitIds[1]); + getStartBounds(topLeftTarget), + getStartBounds(bottomRightTarget), splitIds[0], splitIds[1]); mRemoteTargetHandles[0].mTransformParams.setTargetSet( createRemoteAnimationTargetsForTarget(targets, bottomRightTarget)); mRemoteTargetHandles[0].mTaskViewSimulator.setPreview(topLeftTarget, @@ -134,6 +135,10 @@ public class RemoteTargetGluer { return mRemoteTargetHandles; } + private Rect getStartBounds(RemoteAnimationTarget target) { + return target.startBounds == null ? target.screenSpaceBounds : target.startBounds; + } + /** * Ensures that we aren't excluding ancillary targets such as home/recents * @@ -144,11 +149,10 @@ public class RemoteTargetGluer { */ private RemoteAnimationTargets createRemoteAnimationTargetsForTarget( RemoteAnimationTargets targets, - RemoteAnimationTargetCompat targetToExclude) { - ArrayList targetsWithoutExcluded = - new ArrayList(); + RemoteAnimationTarget targetToExclude) { + ArrayList targetsWithoutExcluded = new ArrayList<>(); - for (RemoteAnimationTargetCompat targetCompat : targets.unfilteredApps) { + for (RemoteAnimationTarget targetCompat : targets.unfilteredApps) { if (targetCompat == targetToExclude) { continue; } @@ -162,9 +166,8 @@ public class RemoteTargetGluer { targetsWithoutExcluded.add(targetCompat); } - final RemoteAnimationTargetCompat[] filteredApps = - targetsWithoutExcluded.toArray( - new RemoteAnimationTargetCompat[targetsWithoutExcluded.size()]); + final RemoteAnimationTarget[] filteredApps = targetsWithoutExcluded.toArray( + new RemoteAnimationTarget[targetsWithoutExcluded.size()]); return new RemoteAnimationTargets( filteredApps, targets.wallpapers, targets.nonApps, targets.targetMode); } diff --git a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java index 71e8a774f7..f591a1cff6 100644 --- a/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java +++ b/quickstep/src/com/android/quickstep/SwipeUpAnimationLogic.java @@ -24,6 +24,7 @@ import android.graphics.Matrix; import android.graphics.Matrix.ScaleToFit; import android.graphics.Rect; import android.graphics.RectF; +import android.view.RemoteAnimationTarget; import androidx.annotation.NonNull; import androidx.annotation.UiThread; @@ -41,7 +42,6 @@ import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties; import com.android.quickstep.util.TaskViewSimulator; import com.android.quickstep.util.TransformParams; import com.android.quickstep.util.TransformParams.BuilderProxy; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.util.Arrays; import java.util.function.Consumer; @@ -335,7 +335,7 @@ public abstract class SwipeUpAnimationLogic implements } @Override - public void onBuildTargetParams(SurfaceProperties builder, RemoteAnimationTargetCompat app, + public void onBuildTargetParams(SurfaceProperties builder, RemoteAnimationTarget app, TransformParams params) { builder.setMatrix(mMatrix) .setWindowCrop(mCropRect) diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index 129b88ebb4..7705a2512a 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -671,6 +671,7 @@ public class SystemUiProxy implements ISystemUiProxy { * * @return RemoteAnimationTargets of windows that need to animate but only exist in shell. */ + @Nullable public RemoteAnimationTarget[] onGoingToRecentsLegacy(RemoteAnimationTarget[] apps) { if (mSplitScreen != null) { try { @@ -682,6 +683,7 @@ public class SystemUiProxy implements ISystemUiProxy { return null; } + @Nullable public RemoteAnimationTarget[] onStartingSplitLegacy(RemoteAnimationTarget[] apps) { if (mSplitScreen != null) { try { diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java index 7f1656500a..30d445fc31 100644 --- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java +++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java @@ -15,11 +15,12 @@ */ package com.android.quickstep; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; + 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.systemui.shared.system.RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME; import android.app.ActivityManager; import android.app.ActivityOptions; @@ -38,12 +39,10 @@ import com.android.quickstep.TopTaskTracker.CachedTaskInfo; import com.android.quickstep.views.RecentsView; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.RemoteTransitionCompat; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; -import java.util.Arrays; import java.util.HashMap; public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAnimationListener { @@ -57,7 +56,7 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn private RecentsAnimationTargets mTargets; // Temporary until we can hook into gesture state events private GestureState mLastGestureState; - private RemoteAnimationTargetCompat mLastAppearedTaskTarget; + private RemoteAnimationTarget mLastAppearedTaskTarget; private Runnable mLiveTileCleanUpHandler; private Context mCtx; @@ -151,12 +150,12 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn } @Override - public void onTasksAppeared(RemoteAnimationTargetCompat[] appearedTaskTargets) { - RemoteAnimationTargetCompat appearedTaskTarget = appearedTaskTargets[0]; + public void onTasksAppeared(RemoteAnimationTarget[] appearedTaskTargets) { + RemoteAnimationTarget appearedTaskTarget = appearedTaskTargets[0]; BaseActivityInterface activityInterface = mLastGestureState.getActivityInterface(); - for (RemoteAnimationTargetCompat compat : appearedTaskTargets) { - if (compat.activityType == ACTIVITY_TYPE_HOME + for (RemoteAnimationTarget compat : appearedTaskTargets) { + if (compat.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME && activityInterface.getCreatedActivity() instanceof RecentsActivity) { // When receive opening home activity while recents is running, enter home // and dismiss recents. @@ -165,11 +164,11 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn } } - RemoteAnimationTarget[] nonAppTargets = SystemUiProxy.INSTANCE.getNoCreate() - .onStartingSplitLegacy(Arrays.stream(appearedTaskTargets) - .map(RemoteAnimationTargetCompat::unwrap) - .toArray(RemoteAnimationTarget[]::new)); - + RemoteAnimationTarget[] nonAppTargets = SystemUiProxy.INSTANCE.get(mCtx) + .onStartingSplitLegacy(appearedTaskTargets); + if (nonAppTargets == null) { + nonAppTargets = new RemoteAnimationTarget[0]; + } if (activityInterface.isInLiveTileMode() && activityInterface.getCreatedActivity() != null) { RecentsView recentsView = @@ -177,13 +176,13 @@ public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAn if (recentsView != null) { recentsView.launchSideTaskInLiveTileMode(appearedTaskTarget.taskId, appearedTaskTargets, - new RemoteAnimationTargetCompat[0] /* wallpaper */, - RemoteAnimationTargetCompat.wrap(nonAppTargets) /* nonApps */); + new RemoteAnimationTarget[0] /* wallpaper */, + nonAppTargets /* nonApps */); return; } - } else if (nonAppTargets != null && nonAppTargets.length > 0) { + } else if (nonAppTargets.length > 0) { TaskViewUtils.createSplitAuxiliarySurfacesAnimator( - RemoteAnimationTargetCompat.wrap(nonAppTargets) /* nonApps */, + nonAppTargets /* nonApps */, true /*shown*/, dividerAnimator -> { dividerAnimator.start(); dividerAnimator.end(); diff --git a/quickstep/src/com/android/quickstep/TaskUtils.java b/quickstep/src/com/android/quickstep/TaskUtils.java index d7227780c6..67360c4cc3 100644 --- a/quickstep/src/com/android/quickstep/TaskUtils.java +++ b/quickstep/src/com/android/quickstep/TaskUtils.java @@ -26,6 +26,7 @@ import android.content.pm.ApplicationInfo; import android.content.pm.PackageManager; import android.os.UserHandle; import android.util.Log; +import android.view.RemoteAnimationTarget; import androidx.annotation.Nullable; @@ -34,7 +35,6 @@ import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.PackageManagerHelper; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.ActivityManagerWrapper; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.util.List; @@ -87,9 +87,9 @@ public final class TaskUtils { } - public static boolean taskIsATargetWithMode(RemoteAnimationTargetCompat[] targets, + public static boolean taskIsATargetWithMode(RemoteAnimationTarget[] targets, int taskId, int mode) { - for (RemoteAnimationTargetCompat target : targets) { + for (RemoteAnimationTarget target : targets) { if (target.mode == mode && target.taskId == taskId) { return true; } diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java index bfebbbcbfa..7d6bbaccd1 100644 --- a/quickstep/src/com/android/quickstep/TaskViewUtils.java +++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java @@ -15,6 +15,8 @@ */ package com.android.quickstep; +import static android.view.RemoteAnimationTarget.MODE_CLOSING; +import static android.view.RemoteAnimationTarget.MODE_OPENING; import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER; import static android.view.WindowManager.TRANSIT_OPEN; import static android.view.WindowManager.TRANSIT_TO_FRONT; @@ -35,8 +37,6 @@ import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR; import static com.android.launcher3.anim.Interpolators.clampToProgress; import static com.android.launcher3.statehandlers.DepthController.STATE_DEPTH; -import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; -import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_OPENING; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -51,6 +51,7 @@ import android.graphics.Matrix.ScaleToFit; import android.graphics.Rect; import android.graphics.RectF; import android.os.Build; +import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.View; import android.window.TransitionInfo; @@ -103,7 +104,7 @@ public final class TaskViewUtils { * opening remote target (which we don't get until onAnimationStart) will resolve to a TaskView. */ public static TaskView findTaskViewToLaunch( - RecentsView recentsView, View v, RemoteAnimationTargetCompat[] targets) { + RecentsView recentsView, View v, RemoteAnimationTarget[] targets) { if (v instanceof TaskView) { TaskView taskView = (TaskView) v; return recentsView.isTaskViewVisible(taskView) ? taskView : null; @@ -133,7 +134,7 @@ public final class TaskViewUtils { } // Resolve the opening task id int openingTaskId = -1; - for (RemoteAnimationTargetCompat target : targets) { + for (RemoteAnimationTarget target : targets) { if (target.mode == MODE_OPENING) { openingTaskId = target.taskId; break; @@ -156,9 +157,9 @@ public final class TaskViewUtils { public static void createRecentsWindowAnimator( @NonNull TaskView v, boolean skipViewChanges, - @NonNull RemoteAnimationTargetCompat[] appTargets, - @NonNull RemoteAnimationTargetCompat[] wallpaperTargets, - @NonNull RemoteAnimationTargetCompat[] nonAppTargets, + @NonNull RemoteAnimationTarget[] appTargets, + @NonNull RemoteAnimationTarget[] wallpaperTargets, + @NonNull RemoteAnimationTarget[] nonAppTargets, @Nullable DepthController depthController, PendingAnimation out) { RecentsView recentsView = v.getRecentsView(); @@ -168,7 +169,7 @@ public final class TaskViewUtils { final RemoteAnimationTargets targets = new RemoteAnimationTargets(appTargets, wallpaperTargets, nonAppTargets, MODE_OPENING); - final RemoteAnimationTargetCompat navBarTarget = targets.getNavBarRemoteAnimationTarget(); + final RemoteAnimationTarget navBarTarget = targets.getNavBarRemoteAnimationTarget(); SurfaceTransactionApplier applier = new SurfaceTransactionApplier(v); targets.addReleaseCheck(applier); @@ -410,12 +411,12 @@ public final class TaskViewUtils { } }); - final RemoteAnimationTargetCompat[] appTargets = + final RemoteAnimationTarget[] appTargets = RemoteAnimationTargetCompat.wrapApps(transitionInfo, t, null /* leashMap */); - final RemoteAnimationTargetCompat[] wallpaperTargets = + final RemoteAnimationTarget[] wallpaperTargets = RemoteAnimationTargetCompat.wrapNonApps( transitionInfo, true /* wallpapers */, t, null /* leashMap */); - final RemoteAnimationTargetCompat[] nonAppTargets = + final RemoteAnimationTarget[] nonAppTargets = RemoteAnimationTargetCompat.wrapNonApps( transitionInfo, false /* wallpapers */, t, null /* leashMap */); final RecentsView recentsView = launchingTaskView.getRecentsView(); @@ -492,9 +493,9 @@ public final class TaskViewUtils { public static void composeRecentsSplitLaunchAnimatorLegacy( @Nullable GroupedTaskView launchingTaskView, int initialTaskId, @Nullable PendingIntent initialTaskPendingIntent, int secondTaskId, - @NonNull RemoteAnimationTargetCompat[] appTargets, - @NonNull RemoteAnimationTargetCompat[] wallpaperTargets, - @NonNull RemoteAnimationTargetCompat[] nonAppTargets, + @NonNull RemoteAnimationTarget[] appTargets, + @NonNull RemoteAnimationTarget[] wallpaperTargets, + @NonNull RemoteAnimationTarget[] nonAppTargets, @NonNull StateManager stateManager, @Nullable DepthController depthController, @NonNull Runnable finishCallback) { @@ -517,7 +518,7 @@ public final class TaskViewUtils { final ArrayList openingTargets = new ArrayList<>(); final ArrayList closingTargets = new ArrayList<>(); - for (RemoteAnimationTargetCompat appTarget : appTargets) { + for (RemoteAnimationTarget appTarget : appTargets) { final int taskId = appTarget.taskInfo != null ? appTarget.taskInfo.taskId : -1; final int mode = appTarget.mode; final SurfaceControl leash = appTarget.leash; @@ -572,9 +573,9 @@ public final class TaskViewUtils { } public static void composeRecentsLaunchAnimator(@NonNull AnimatorSet anim, @NonNull View v, - @NonNull RemoteAnimationTargetCompat[] appTargets, - @NonNull RemoteAnimationTargetCompat[] wallpaperTargets, - @NonNull RemoteAnimationTargetCompat[] nonAppTargets, boolean launcherClosing, + @NonNull RemoteAnimationTarget[] appTargets, + @NonNull RemoteAnimationTarget[] wallpaperTargets, + @NonNull RemoteAnimationTarget[] nonAppTargets, boolean launcherClosing, @NonNull StateManager stateManager, @NonNull RecentsView recentsView, @Nullable DepthController depthController) { boolean skipLauncherChanges = !launcherClosing; @@ -666,7 +667,7 @@ public final class TaskViewUtils { * @return the animator animating the surfaces */ public static ValueAnimator createSplitAuxiliarySurfacesAnimator( - RemoteAnimationTargetCompat[] nonApps, boolean shown, + RemoteAnimationTarget[] nonApps, boolean shown, Consumer animatorHandler) { if (nonApps == null || nonApps.length == 0) { return null; @@ -676,7 +677,7 @@ public final class TaskViewUtils { List auxiliarySurfaces = new ArrayList<>(nonApps.length); boolean hasSurfaceToAnimate = false; for (int i = 0; i < nonApps.length; ++i) { - final RemoteAnimationTargetCompat targ = nonApps[i]; + final RemoteAnimationTarget targ = nonApps[i]; final SurfaceControl leash = targ.leash; if (targ.windowType == TYPE_DOCK_DIVIDER && leash != null && leash.isValid()) { auxiliarySurfaces.add(leash); diff --git a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java index c131c055f6..8410149df6 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java @@ -37,6 +37,7 @@ import android.graphics.Matrix; import android.graphics.Point; import android.graphics.PointF; import android.view.MotionEvent; +import android.view.RemoteAnimationTarget; import android.view.VelocityTracker; import com.android.launcher3.R; @@ -59,7 +60,6 @@ import com.android.quickstep.util.TransformParams.BuilderProxy; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InputMonitorCompat; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import java.util.HashMap; @@ -290,7 +290,7 @@ public class DeviceLockedInputConsumer implements InputConsumer, @Override public void onBuildTargetParams( - SurfaceProperties builder, RemoteAnimationTargetCompat app, TransformParams params) { + SurfaceProperties builder, RemoteAnimationTarget app, TransformParams params) { mMatrix.setTranslate(0, mProgress.value * mMaxTranslationY); builder.setMatrix(mMatrix); } diff --git a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java index ee82ae67df..10f2eaa2f0 100644 --- a/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java +++ b/quickstep/src/com/android/quickstep/util/RemoteAnimationProvider.java @@ -16,23 +16,22 @@ package com.android.quickstep.util; import android.animation.AnimatorSet; - -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; +import android.view.RemoteAnimationTarget; public abstract class RemoteAnimationProvider { - public abstract AnimatorSet createWindowAnimation(RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets); + public abstract AnimatorSet createWindowAnimation(RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets); /** * @return the target with the lowest opaque layer for a certain app animation, or null. */ - public static RemoteAnimationTargetCompat findLowestOpaqueLayerTarget( - RemoteAnimationTargetCompat[] appTargets, int mode) { + public static RemoteAnimationTarget findLowestOpaqueLayerTarget( + RemoteAnimationTarget[] appTargets, int mode) { int lowestLayer = Integer.MAX_VALUE; int lowestLayerIndex = -1; for (int i = appTargets.length - 1; i >= 0; i--) { - RemoteAnimationTargetCompat target = appTargets[i]; + RemoteAnimationTarget target = appTargets[i]; if (target.mode == mode && !target.isTranslucent) { int layer = target.prefixOrderIndex; if (layer < lowestLayer) { diff --git a/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java b/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java index b2e159ee10..382cf79e1e 100644 --- a/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java +++ b/quickstep/src/com/android/quickstep/util/RemoteFadeOutAnimationListener.java @@ -15,14 +15,14 @@ */ package com.android.quickstep.util; -import static com.android.systemui.shared.system.RemoteAnimationTargetCompat.MODE_CLOSING; +import static android.view.RemoteAnimationTarget.MODE_CLOSING; import android.animation.ValueAnimator; import android.animation.ValueAnimator.AnimatorUpdateListener; +import android.view.RemoteAnimationTarget; import android.view.SurfaceControl.Transaction; import com.android.quickstep.RemoteAnimationTargets; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; /** * Animation listener which fades out the closing targets @@ -32,24 +32,24 @@ public class RemoteFadeOutAnimationListener implements AnimatorUpdateListener { private final RemoteAnimationTargets mTarget; private boolean mFirstFrame = true; - public RemoteFadeOutAnimationListener(RemoteAnimationTargetCompat[] appTargets, - RemoteAnimationTargetCompat[] wallpaperTargets) { + public RemoteFadeOutAnimationListener(RemoteAnimationTarget[] appTargets, + RemoteAnimationTarget[] wallpaperTargets) { mTarget = new RemoteAnimationTargets(appTargets, wallpaperTargets, - new RemoteAnimationTargetCompat[0], MODE_CLOSING); + new RemoteAnimationTarget[0], MODE_CLOSING); } @Override public void onAnimationUpdate(ValueAnimator valueAnimator) { Transaction t = new Transaction(); if (mFirstFrame) { - for (RemoteAnimationTargetCompat target : mTarget.unfilteredApps) { + for (RemoteAnimationTarget target : mTarget.unfilteredApps) { t.show(target.leash); } mFirstFrame = false; } float alpha = 1 - valueAnimator.getAnimatedFraction(); - for (RemoteAnimationTargetCompat app : mTarget.apps) { + for (RemoteAnimationTarget app : mTarget.apps) { t.setAlpha(app.leash, alpha); } t.apply(); diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java index f07f9903c2..3119a7714e 100644 --- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java @@ -38,6 +38,7 @@ import android.text.TextUtils; import android.util.Log; import android.util.Pair; import android.view.RemoteAnimationAdapter; +import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.window.TransitionInfo; @@ -61,7 +62,6 @@ import com.android.quickstep.views.TaskView; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.system.RemoteAnimationAdapterCompat; import com.android.systemui.shared.system.RemoteAnimationRunnerCompat; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.RemoteTransitionCompat; import com.android.systemui.shared.system.RemoteTransitionRunner; @@ -359,8 +359,8 @@ public class SplitSelectStateController { } @Override - public void onAnimationStart(int transit, RemoteAnimationTargetCompat[] apps, - RemoteAnimationTargetCompat[] wallpapers, RemoteAnimationTargetCompat[] nonApps, + public void onAnimationStart(int transit, RemoteAnimationTarget[] apps, + RemoteAnimationTarget[] wallpapers, RemoteAnimationTarget[] nonApps, Runnable finishedCallback) { postAsyncCallback(mHandler, () -> TaskViewUtils.composeRecentsSplitLaunchAnimatorLegacy( diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java index ff612f55b7..52f069e7b0 100644 --- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java +++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java @@ -35,6 +35,7 @@ import android.graphics.PointF; import android.graphics.Rect; import android.graphics.RectF; import android.util.Log; +import android.view.RemoteAnimationTarget; import androidx.annotation.NonNull; @@ -50,7 +51,6 @@ import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties; import com.android.quickstep.views.TaskView.FullscreenDrawParams; import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.recents.utilities.PreviewPositionHelper; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; /** * A utility class which emulates the layout behavior of TaskView and RecentsView @@ -171,8 +171,11 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { /** * Sets the targets which the simulator will control */ - public void setPreview(RemoteAnimationTargetCompat runningTarget) { - setPreviewBounds(runningTarget.startScreenSpaceBounds, runningTarget.contentInsets); + public void setPreview(RemoteAnimationTarget runningTarget) { + setPreviewBounds( + runningTarget.startBounds == null + ? runningTarget.screenSpaceBounds : runningTarget.startBounds, + runningTarget.contentInsets); } /** @@ -181,7 +184,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { * * @param splitInfo set to {@code null} when not in staged split mode */ - public void setPreview(RemoteAnimationTargetCompat runningTarget, SplitBounds splitInfo) { + public void setPreview(RemoteAnimationTarget runningTarget, SplitBounds splitInfo) { setPreview(runningTarget); mSplitBounds = splitInfo; if (mSplitBounds == null) { @@ -386,7 +389,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { @Override public void onBuildTargetParams( - SurfaceProperties builder, RemoteAnimationTargetCompat app, TransformParams params) { + SurfaceProperties builder, RemoteAnimationTarget app, TransformParams params) { builder.setMatrix(mMatrix) .setWindowCrop(mTmpCropRect) .setCornerRadius(getCurrentCornerRadius()); diff --git a/quickstep/src/com/android/quickstep/util/TransformParams.java b/quickstep/src/com/android/quickstep/util/TransformParams.java index 3d505c6234..aa9a45bd8b 100644 --- a/quickstep/src/com/android/quickstep/util/TransformParams.java +++ b/quickstep/src/com/android/quickstep/util/TransformParams.java @@ -15,14 +15,18 @@ */ package com.android.quickstep.util; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_ASSISTANT; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME; +import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS; + import android.util.FloatProperty; +import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import com.android.launcher3.Utilities; import com.android.launcher3.anim.Interpolators; import com.android.quickstep.RemoteAnimationTargets; import com.android.quickstep.util.SurfaceTransaction.SurfaceProperties; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; public class TransformParams { @@ -140,16 +144,16 @@ public class TransformParams { mRecentsSurface = getRecentsSurface(targets); for (int i = 0; i < targets.unfilteredApps.length; i++) { - RemoteAnimationTargetCompat app = targets.unfilteredApps[i]; + RemoteAnimationTarget app = targets.unfilteredApps[i]; SurfaceProperties builder = transaction.forSurface(app.leash); if (app.mode == targets.targetMode) { - if (app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_HOME) { + int activityType = app.windowConfiguration.getActivityType(); + if (activityType == ACTIVITY_TYPE_HOME) { mHomeBuilderProxy.onBuildTargetParams(builder, app, this); } else { // Fade out Assistant overlay. - if (app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_ASSISTANT - && app.isNotInRecents) { + if (activityType == ACTIVITY_TYPE_ASSISTANT && app.isNotInRecents) { float progress = Utilities.boundToRange(getProgress(), 0, 1); builder.setAlpha(1 - Interpolators.DEACCEL_2_5.getInterpolation(progress)); } else { @@ -166,7 +170,7 @@ public class TransformParams { // always put wallpaper layer to bottom. final int wallpaperLength = targets.wallpapers != null ? targets.wallpapers.length : 0; for (int i = 0; i < wallpaperLength; i++) { - RemoteAnimationTargetCompat wallpaper = targets.wallpapers[i]; + RemoteAnimationTarget wallpaper = targets.wallpapers[i]; transaction.forSurface(wallpaper.leash).setLayer(Integer.MIN_VALUE); } return transaction; @@ -174,9 +178,9 @@ public class TransformParams { private static SurfaceControl getRecentsSurface(RemoteAnimationTargets targets) { for (int i = 0; i < targets.unfilteredApps.length; i++) { - RemoteAnimationTargetCompat app = targets.unfilteredApps[i]; + RemoteAnimationTarget app = targets.unfilteredApps[i]; if (app.mode == targets.targetMode) { - if (app.activityType == RemoteAnimationTargetCompat.ACTIVITY_TYPE_RECENTS) { + if (app.windowConfiguration.getActivityType() == ACTIVITY_TYPE_RECENTS) { return app.leash; } } else { @@ -223,6 +227,6 @@ public class TransformParams { BuilderProxy ALWAYS_VISIBLE = (builder, app, params) -> builder.setAlpha(1); void onBuildTargetParams(SurfaceProperties builder, - RemoteAnimationTargetCompat app, TransformParams params); + RemoteAnimationTarget app, TransformParams params); } } diff --git a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java index 8a5f42afaf..6431bdf5aa 100644 --- a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java +++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java @@ -25,6 +25,7 @@ import android.os.Build; import android.util.AttributeSet; import android.util.Size; import android.view.GhostView; +import android.view.RemoteAnimationTarget; import android.view.View; import android.view.ViewGroup; import android.view.ViewTreeObserver.OnGlobalLayoutListener; @@ -41,7 +42,6 @@ import com.android.launcher3.views.FloatingView; import com.android.launcher3.views.ListenerView; import com.android.launcher3.widget.LauncherAppWidgetHostView; import com.android.launcher3.widget.RoundedCornerEnforcement; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; /** A view that mimics an App Widget through a launch animation. */ @TargetApi(Build.VERSION_CODES.S) @@ -304,7 +304,7 @@ public class FloatingWidgetView extends FrameLayout implements AnimatorListener, * context's theme background color. */ public static int getDefaultBackgroundColor( - Context context, RemoteAnimationTargetCompat target) { + Context context, RemoteAnimationTarget target) { return (target != null && target.taskInfo.taskDescription != null) ? target.taskInfo.taskDescription.getBackgroundColor() : Themes.getColorBackground(context); diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index ab19487c11..88971e28da 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -104,6 +104,7 @@ import android.view.HapticFeedbackConstants; import android.view.KeyEvent; import android.view.LayoutInflater; import android.view.MotionEvent; +import android.view.RemoteAnimationTarget; import android.view.View; import android.view.ViewDebug; import android.view.ViewGroup; @@ -192,7 +193,6 @@ import com.android.systemui.shared.recents.model.ThumbnailData; import com.android.systemui.shared.system.ActivityManagerWrapper; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import com.android.systemui.shared.system.PackageManagerWrapper; -import com.android.systemui.shared.system.RemoteAnimationTargetCompat; import com.android.systemui.shared.system.TaskStackChangeListener; import com.android.systemui.shared.system.TaskStackChangeListeners; import com.android.wm.shell.pip.IPipAnimationListener; @@ -1064,8 +1064,8 @@ public abstract class RecentsView Date: Mon, 3 Oct 2022 17:55:11 -0700 Subject: [PATCH 114/429] Add transitions to DWB banner when app thumbnail progresses from Overview tile to fullscreen This patch makes it so that the DWB banner transitions out neatly when a user in Overview drags a tile downward to launch the app. Previously, the banner would stick around throughout the transition, creating visual clutter and drawing attention to the corners of the app. Fixed by creating an exit transition in setFullscreenProgress(), similar to other UI elements like Overview action chips. There is another outstanding issue where sometimes the transition can get clipped and jump to the final frame. The cause is still unknown, but issue is tracked at b/250976138 for a future fix. Fixes: 249825524 Test: Manual Change-Id: Iea47a9bc643537f0b716ce11b104803d9ca25fd2 --- .../quickstep/views/DesktopTaskView.java | 2 +- .../quickstep/views/GroupedTaskView.java | 4 ++-- .../com/android/quickstep/views/TaskView.java | 17 ++++++++++++++--- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java index 9874f9644a..485b915de0 100644 --- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java +++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java @@ -434,7 +434,7 @@ public class DesktopTaskView extends TaskView { } @Override - protected void setIconAndDimTransitionProgress(float progress, boolean invert) { + protected void setIconsAndBannersTransitionProgress(float progress, boolean invert) { // no-op } diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java index 71b0c60971..2f8b130dc0 100644 --- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java +++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java @@ -319,8 +319,8 @@ public class GroupedTaskView extends TaskView { } @Override - protected void setIconAndDimTransitionProgress(float progress, boolean invert) { - super.setIconAndDimTransitionProgress(progress, invert); + protected void setIconsAndBannersTransitionProgress(float progress, boolean invert) { + super.setIconsAndBannersTransitionProgress(progress, invert); // Value set by super call float scale = mIconView.getAlpha(); mIconView2.setAlpha(scale); diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index 35f0f5d1df..cd6fa7a181 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -19,6 +19,7 @@ package com.android.quickstep.views; import static android.view.Display.DEFAULT_DISPLAY; import static android.widget.Toast.LENGTH_SHORT; +import static com.android.launcher3.LauncherState.BACKGROUND_APP; import static com.android.launcher3.Utilities.comp; import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor; import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; @@ -171,7 +172,7 @@ public class TaskView extends FrameLayout implements Reusable { new FloatProperty("focusTransition") { @Override public void setValue(TaskView taskView, float v) { - taskView.setIconAndDimTransitionProgress(v, false /* invert */); + taskView.setIconsAndBannersTransitionProgress(v, false /* invert */); } @Override @@ -953,7 +954,11 @@ public class TaskView extends FrameLayout implements Reusable { return deviceProfile.isTablet && !isFocusedTask(); } - protected void setIconAndDimTransitionProgress(float progress, boolean invert) { + /** + * Called to animate a smooth transition when going directly from an app into Overview (and + * vice versa). Icons fade in, and DWB banners slide in with a "shift up" animation. + */ + protected void setIconsAndBannersTransitionProgress(float progress, boolean invert) { if (invert) { progress = 1 - progress; } @@ -997,7 +1002,7 @@ public class TaskView extends FrameLayout implements Reusable { if (mIconAndDimAnimator != null) { mIconAndDimAnimator.cancel(); } - setIconAndDimTransitionProgress(iconScale, invert); + setIconsAndBannersTransitionProgress(iconScale, invert); } protected void resetPersistentViewTransforms() { @@ -1417,6 +1422,12 @@ public class TaskView extends FrameLayout implements Reusable { mIconView.setVisibility(progress < 1 ? VISIBLE : INVISIBLE); mSnapshotView.getTaskOverlay().setFullscreenProgress(progress); + // Animate icons and DWB banners in/out, except in QuickSwitch state, when tiles are + // oversized and banner would look disproportionately large. + if (mActivity.getStateManager().getState() != BACKGROUND_APP) { + setIconsAndBannersTransitionProgress(progress, true); + } + updateSnapshotRadius(); } From 4b87b9e5217fcc2c02ef163354880523d3681ec1 Mon Sep 17 00:00:00 2001 From: Hui Kang Date: Fri, 21 Oct 2022 16:52:47 -0700 Subject: [PATCH 115/429] Fix AddWidgetTest flake Test: ABTD 200 all PASS: https://android-build.googleplex.com/builds/tests/view?invocationId=I20300010100881398 Without this CL, 1/100 FAIL: https://android-build.googleplex.com/builds/abtd/run/L73700000956982533 Change-Id: Ia9d7746144e9838798332f4eea223a9529551713 --- tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java index 561f3ccbf2..1f5590e843 100644 --- a/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/AddWidgetTest.java @@ -54,6 +54,8 @@ public class AddWidgetTest extends AbstractLauncherUiTest { clearHomescreen(); mDevice.pressHome(); + waitForLauncherCondition("Workspace didn't finish loading", l -> !l.isWorkspaceLoading()); + final LauncherAppWidgetProviderInfo widgetInfo = TestViewHelpers.findWidgetProvider(this, false /* hasConfigureScreen */); From d859060860ffa599e66a6884fcbac9834b8eb9f5 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 13 Sep 2022 14:40:48 -0700 Subject: [PATCH 116/429] Merging MultiValueAlpha with MultiPropertyFactory Bug: 246644619 Test: Presubmi Change-Id: Id5abc5f3169544656f1139ae17ca59e34ac65dac --- .../launcher3/QuickstepTransitionManager.java | 16 +- .../statehandlers/DepthController.java | 12 +- .../taskbar/NavbarButtonsViewController.java | 16 +- .../taskbar/StashedHandleViewController.java | 7 +- .../taskbar/TaskbarActivityContext.java | 2 +- ...askbarForceVisibleImmersiveController.java | 29 ++-- .../TaskbarLauncherStateController.java | 39 +++-- .../taskbar/TaskbarStashController.java | 10 +- .../taskbar/TaskbarViewController.java | 7 +- .../VoiceInteractionWindowController.kt | 4 +- .../uioverrides/QuickstepLauncher.java | 6 +- .../RecentsViewStateController.java | 4 +- .../quickstep/LauncherActivityInterface.java | 5 +- .../com/android/quickstep/TaskViewUtils.java | 6 +- .../FallbackRecentsStateController.java | 4 +- .../quickstep/util/BaseDepthController.java | 25 +-- .../quickstep/views/OverviewActionsView.java | 21 ++- .../android/quickstep/views/RecentsView.java | 9 +- .../allapps/AllAppsTransitionController.java | 35 ++--- .../launcher3/util/MultiPropertyFactory.java | 134 ++++++++++++---- .../launcher3/util/MultiValueAlpha.java | 144 ++---------------- .../launcher3/views/BaseDragLayer.java | 11 +- .../util/MultiPropertyFactoryTest.kt | 20 +-- 23 files changed, 253 insertions(+), 313 deletions(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 58b3a83cea..1539769e0e 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -44,7 +44,7 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_SCRIM_FOR_APP_LAU import static com.android.launcher3.config.FeatureFlags.KEYGUARD_ANIMATION; import static com.android.launcher3.config.FeatureFlags.SEPARATE_RECENTS_ACTIVITY; import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID; -import static com.android.launcher3.statehandlers.DepthController.STATE_DEPTH; +import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs; import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION; import static com.android.launcher3.views.FloatingIconView.getFloatingIconView; @@ -388,7 +388,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener @Override public void onAnimationStart(Animator animation) { mLauncher.addOnResumeCallback(() -> - ObjectAnimator.ofFloat(mLauncher.getDepthController(), STATE_DEPTH, + ObjectAnimator.ofFloat(mLauncher.getDepthController().stateDepth, + MULTI_PROPERTY_VALUE, mLauncher.getStateManager().getState().getDepth( mLauncher)).start()); } @@ -412,7 +413,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener @Override public void onAnimationStart(Animator animation) { mLauncher.addOnResumeCallback(() -> - ObjectAnimator.ofFloat(mLauncher.getDepthController(), STATE_DEPTH, + ObjectAnimator.ofFloat(mLauncher.getDepthController().stateDepth, + MULTI_PROPERTY_VALUE, mLauncher.getStateManager().getState().getDepth( mLauncher)).start()); } @@ -1050,8 +1052,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener && BlurUtils.supportsBlursOnWindows(); MyDepthController depthController = new MyDepthController(mLauncher); - ObjectAnimator backgroundRadiusAnim = ObjectAnimator.ofFloat(depthController, STATE_DEPTH, - BACKGROUND_APP.getDepth(mLauncher)) + ObjectAnimator backgroundRadiusAnim = ObjectAnimator.ofFloat(depthController.stateDepth, + MULTI_PROPERTY_VALUE, BACKGROUND_APP.getDepth(mLauncher)) .setDuration(APP_LAUNCH_DURATION); if (allowBlurringLauncher) { @@ -1591,8 +1593,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener true /* animateOverviewScrim */, launcherView).getAnimators()); if (!areAllTargetsTranslucent(appTargets)) { - anim.play(ObjectAnimator.ofFloat(mLauncher.getDepthController(), - STATE_DEPTH, + anim.play(ObjectAnimator.ofFloat(mLauncher.getDepthController().stateDepth, + MULTI_PROPERTY_VALUE, BACKGROUND_APP.getDepth(mLauncher), NORMAL.getDepth(mLauncher))); } diff --git a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java index 2a78bdf197..867e168dd2 100644 --- a/quickstep/src/com/android/launcher3/statehandlers/DepthController.java +++ b/quickstep/src/com/android/launcher3/statehandlers/DepthController.java @@ -19,6 +19,7 @@ package com.android.launcher3.statehandlers; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.states.StateAnimationConfig.ANIM_DEPTH; import static com.android.launcher3.states.StateAnimationConfig.SKIP_DEPTH_CONTROLLER; +import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -112,7 +113,7 @@ public class DepthController extends BaseDepthController implements StateHandler return; } - STATE_DEPTH.set(this, toState.getDepth(mLauncher)); + stateDepth.setValue(toState.getDepth(mLauncher)); if (toState == LauncherState.BACKGROUND_APP) { mLauncher.getDragLayer().getViewTreeObserver().addOnDrawListener(mOnDrawListener); } @@ -127,7 +128,8 @@ public class DepthController extends BaseDepthController implements StateHandler } float toDepth = toState.getDepth(mLauncher); - animation.setFloat(this, STATE_DEPTH, toDepth, config.getInterpolator(ANIM_DEPTH, LINEAR)); + animation.setFloat(stateDepth, MULTI_PROPERTY_VALUE, toDepth, + config.getInterpolator(ANIM_DEPTH, LINEAR)); } @Override @@ -140,7 +142,7 @@ public class DepthController extends BaseDepthController implements StateHandler public void onMultiWindowModeChanged(boolean isInMultiWindowMode) { mIgnoreStateChangesDuringMultiWindowAnimation = true; - ObjectAnimator mwAnimation = ObjectAnimator.ofFloat(this, STATE_DEPTH, + ObjectAnimator mwAnimation = ObjectAnimator.ofFloat(stateDepth, MULTI_PROPERTY_VALUE, mLauncher.getStateManager().getState().getDepth(mLauncher, isInMultiWindowMode)) .setDuration(300); mwAnimation.addListener(new AnimatorListenerAdapter() { @@ -158,8 +160,8 @@ public class DepthController extends BaseDepthController implements StateHandler writer.println(prefix + "\tmMaxBlurRadius=" + mMaxBlurRadius); writer.println(prefix + "\tmCrossWindowBlursEnabled=" + mCrossWindowBlursEnabled); writer.println(prefix + "\tmSurface=" + mSurface); - writer.println(prefix + "\tmStateDepth=" + STATE_DEPTH.get(this)); - writer.println(prefix + "\tmWidgetDepth=" + WIDGET_DEPTH.get(this)); + writer.println(prefix + "\tmStateDepth=" + stateDepth.getValue()); + writer.println(prefix + "\tmWidgetDepth=" + widgetDepth.getValue()); writer.println(prefix + "\tmCurrentBlur=" + mCurrentBlur); writer.println(prefix + "\tmInEarlyWakeUp=" + mInEarlyWakeUp); writer.println(prefix + "\tmIgnoreStateChangesDuringMultiWindowAnimation=" diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index 026fa2311b..875327dc8a 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -31,6 +31,7 @@ import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_RE import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_KEYGUARD; import static com.android.launcher3.taskbar.TaskbarViewController.ALPHA_INDEX_SMALL_SCREEN; import static com.android.launcher3.taskbar.Utilities.appendFlag; +import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_CLICKABLE; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BACK_DISABLED; @@ -84,6 +85,7 @@ import com.android.launcher3.taskbar.TaskbarNavButtonController.TaskbarButton; import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory; import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter; import com.android.launcher3.util.DimensionUtils; +import com.android.launcher3.util.MultiPropertyFactory.MultiProperty; import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.TouchController; import com.android.launcher3.views.BaseDragLayer; @@ -227,13 +229,13 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT mPropertyHolders.add(new StatePropertyHolder( mControllers.taskbarViewController.getTaskbarIconAlpha() - .getProperty(ALPHA_INDEX_KEYGUARD), + .get(ALPHA_INDEX_KEYGUARD), flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0 && (flags & FLAG_SCREEN_PINNING_ACTIVE) == 0)); mPropertyHolders.add(new StatePropertyHolder( mControllers.taskbarViewController.getTaskbarIconAlpha() - .getProperty(ALPHA_INDEX_SMALL_SCREEN), + .get(ALPHA_INDEX_SMALL_SCREEN), flags -> (flags & FLAG_SMALL_SCREEN) == 0)); mPropertyHolders.add(new StatePropertyHolder(mControllers.taskbarDragLayerController @@ -340,7 +342,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT mBackButtonAlpha = new MultiValueAlpha(mBackButton, NUM_ALPHA_CHANNELS); mBackButtonAlpha.setUpdateVisibility(true); mPropertyHolders.add(new StatePropertyHolder( - mBackButtonAlpha.getProperty(ALPHA_INDEX_KEYGUARD_OR_DISABLE), + mBackButtonAlpha.get(ALPHA_INDEX_KEYGUARD_OR_DISABLE), flags -> { // Show only if not disabled, and if not on the keyguard or otherwise only when // the bouncer or a lockscreen app is showing above the keyguard @@ -368,7 +370,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT mHomeButtonAlpha = new MultiValueAlpha(mHomeButton, NUM_ALPHA_CHANNELS); mHomeButtonAlpha.setUpdateVisibility(true); mPropertyHolders.add( - new StatePropertyHolder(mHomeButtonAlpha.getProperty( + new StatePropertyHolder(mHomeButtonAlpha.get( ALPHA_INDEX_KEYGUARD_OR_DISABLE), flags -> (flags & FLAG_KEYGUARD_VISIBLE) == 0 && (flags & FLAG_DISABLE_HOME) == 0)); @@ -720,7 +722,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT // Hide back button in SUW if keyboard is showing (IME draws its own back). mPropertyHolders.add(new StatePropertyHolder( - mBackButtonAlpha.getProperty(ALPHA_INDEX_SUW), + mBackButtonAlpha.get(ALPHA_INDEX_SUW), flags -> (flags & FLAG_IME_VISIBLE) == 0)); // TODO(b/210906568) Dark intensity is currently not propagated during setup, so set @@ -1046,9 +1048,9 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT mAnimator.addListener(new AlphaUpdateListener(view)); } - StatePropertyHolder(MultiValueAlpha.AlphaProperty alphaProperty, + StatePropertyHolder(MultiProperty alphaProperty, IntPredicate enableCondition) { - this(alphaProperty, enableCondition, MultiValueAlpha.VALUE, 1, 0); + this(alphaProperty, enableCondition, MULTI_PROPERTY_VALUE, 1, 0); } StatePropertyHolder(AnimatedFloat animatedFloat, IntPredicate enableCondition) { diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java index e23e27ed0f..12dbcb3902 100644 --- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java @@ -31,6 +31,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.RevealOutlineAnimation; import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; import com.android.launcher3.util.Executors; +import com.android.launcher3.util.MultiPropertyFactory; import com.android.launcher3.util.MultiValueAlpha; import com.android.quickstep.AnimatedFloat; import com.android.systemui.shared.navigationbar.RegionSamplingHelper; @@ -105,7 +106,7 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT .getDimensionPixelSize(R.dimen.taskbar_stashed_handle_width); } - mTaskbarStashedHandleAlpha.getProperty(ALPHA_INDEX_STASHED).setValue( + mTaskbarStashedHandleAlpha.get(ALPHA_INDEX_STASHED).setValue( isPhoneGestureNavMode(deviceProfile) ? 1 : 0); mTaskbarStashedHandleHintScale.updateValue(1f); @@ -166,7 +167,7 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT return TaskbarManager.isPhoneMode(deviceProfile) && !mActivity.isThreeButtonNav(); } - public MultiValueAlpha getStashedHandleAlpha() { + public MultiPropertyFactory getStashedHandleAlpha() { return mTaskbarStashedHandleAlpha; } @@ -222,7 +223,7 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT * Should be called when the home button is disabled, so we can hide this handle as well. */ public void setIsHomeButtonDisabled(boolean homeDisabled) { - mTaskbarStashedHandleAlpha.getProperty(ALPHA_INDEX_HOME_DISABLED).setValue( + mTaskbarStashedHandleAlpha.get(ALPHA_INDEX_HOME_DISABLED).setValue( homeDisabled ? 0 : 1); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 4c5e0bea8c..237d1efbf6 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -523,7 +523,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { private void onNotificationShadeExpandChanged(boolean isExpanded, boolean skipAnim) { float alpha = isExpanded ? 0 : 1; AnimatorSet anim = new AnimatorSet(); - anim.play(mControllers.taskbarViewController.getTaskbarIconAlpha().getProperty( + anim.play(mControllers.taskbarViewController.getTaskbarIconAlpha().get( TaskbarViewController.ALPHA_INDEX_NOTIFICATION_EXPANDED).animateToValue(alpha)); if (!isThreeButtonNav()) { anim.play(mControllers.taskbarDragLayerController.getNotificationShadeBgTaskbar() diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java index 6c793a6119..f7aafe0d05 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarForceVisibleImmersiveController.java @@ -31,13 +31,10 @@ import android.view.MotionEvent; import android.view.View; import com.android.launcher3.compat.AccessibilityManagerCompat; -import com.android.launcher3.util.MultiValueAlpha; +import com.android.launcher3.util.MultiPropertyFactory; import com.android.launcher3.util.TouchController; import com.android.quickstep.AnimatedFloat; -import java.util.Optional; -import java.util.function.Consumer; - /** * Controller for taskbar when force visible in immersive mode is set. */ @@ -54,8 +51,6 @@ public class TaskbarForceVisibleImmersiveController implements TouchController { private final Runnable mUndimmingRunnable = this::undimIcons; private final AnimatedFloat mIconAlphaForDimming = new AnimatedFloat( this::updateIconDimmingAlpha); - private final Consumer mImmersiveModeAlphaUpdater = alpha -> alpha.getProperty( - ALPHA_INDEX_IMMERSIVE_MODE).setValue(mIconAlphaForDimming.value); private final View.AccessibilityDelegate mKidsModeAccessibilityDelegate = new View.AccessibilityDelegate() { @Override @@ -145,22 +140,20 @@ public class TaskbarForceVisibleImmersiveController implements TouchController { } private void updateIconDimmingAlpha() { - getBackButtonAlphaOptional().ifPresent(mImmersiveModeAlphaUpdater); - getHomeButtonAlphaOptional().ifPresent(mImmersiveModeAlphaUpdater); - } - - private Optional getBackButtonAlphaOptional() { if (mControllers == null || mControllers.navbarButtonsViewController == null) { - return Optional.empty(); + return; } - return Optional.ofNullable(mControllers.navbarButtonsViewController.getBackButtonAlpha()); - } - private Optional getHomeButtonAlphaOptional() { - if (mControllers == null || mControllers.navbarButtonsViewController == null) { - return Optional.empty(); + MultiPropertyFactory ba = + mControllers.navbarButtonsViewController.getBackButtonAlpha(); + if (ba != null) { + ba.get(ALPHA_INDEX_IMMERSIVE_MODE).setValue(mIconAlphaForDimming.value); + } + MultiPropertyFactory ha = + mControllers.navbarButtonsViewController.getHomeButtonAlpha(); + if (ba != null) { + ha.get(ALPHA_INDEX_IMMERSIVE_MODE).setValue(mIconAlphaForDimming.value); } - return Optional.ofNullable(mControllers.navbarButtonsViewController.getHomeButtonAlpha()); } @Override diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index de37b70632..63f1486729 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -38,7 +38,7 @@ import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.statemanager.StateManager; import com.android.launcher3.uioverrides.QuickstepLauncher; -import com.android.launcher3.util.MultiValueAlpha; +import com.android.launcher3.util.MultiPropertyFactory.MultiProperty; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.RecentsAnimationCallbacks; import com.android.quickstep.RecentsAnimationController; @@ -49,7 +49,6 @@ import com.android.systemui.shared.recents.model.ThumbnailData; import java.io.PrintWriter; import java.util.HashMap; import java.util.StringJoiner; -import java.util.function.Consumer; /** * Track LauncherState, RecentsAnimation, resumed state for task bar in one place here and animate @@ -73,7 +72,7 @@ import java.util.function.Consumer; private TaskbarControllers mControllers; private AnimatedFloat mTaskbarBackgroundAlpha; - private MultiValueAlpha.AlphaProperty mIconAlphaForHome; + private MultiProperty mIconAlphaForHome; private QuickstepLauncher mLauncher; private Integer mPrevState; @@ -89,18 +88,8 @@ import java.util.function.Consumer; // We skip any view synchronizations during init/destroy. private boolean mCanSyncViews; - private final Consumer mIconAlphaForHomeConsumer = alpha -> { - /* - * Hide Launcher Hotseat icons when Taskbar icons have opacity. Both icon sets - * should not be visible at the same time. - */ - mLauncher.getHotseat().setIconsAlpha(alpha > 0 ? 0 : 1); - mLauncher.getHotseat().setQsbAlpha( - mLauncher.getDeviceProfile().isQsbInline && alpha > 0 ? 0 : 1); - }; - private final DeviceProfile.OnDeviceProfileChangeListener mOnDeviceProfileChangeListener = - dp -> mIconAlphaForHomeConsumer.accept(mIconAlphaForHome.getValue()); + dp -> updateIconAlphaForHome(mIconAlphaForHome.getValue()); private final StateManager.StateListener mStateListener = new StateManager.StateListener() { @@ -139,9 +128,8 @@ import java.util.function.Consumer; mTaskbarBackgroundAlpha = mControllers.taskbarDragLayerController .getTaskbarBackgroundAlpha(); - MultiValueAlpha taskbarIconAlpha = mControllers.taskbarViewController.getTaskbarIconAlpha(); - mIconAlphaForHome = taskbarIconAlpha.getProperty(ALPHA_INDEX_HOME); - mIconAlphaForHome.setConsumer(mIconAlphaForHomeConsumer); + mIconAlphaForHome = mControllers.taskbarViewController + .getTaskbarIconAlpha().get(ALPHA_INDEX_HOME); mIconAlignment.finishAnimation(); onIconAlignmentRatioChanged(); @@ -162,7 +150,6 @@ import java.util.function.Consumer; mIconAlignment.finishAnimation(); - mIconAlphaForHome.setConsumer(null); mLauncher.getHotseat().setIconsAlpha(1f); mLauncher.getStateManager().removeStateListener(mStateListener); @@ -383,7 +370,7 @@ import java.util.function.Consumer; @Override public void onAnimationStart(Animator animation) { if (mLauncher.getHotseat().getIconsAlpha() > 0) { - mIconAlphaForHome.setValue(mLauncher.getHotseat().getIconsAlpha()); + updateIconAlphaForHome(mLauncher.getHotseat().getIconsAlpha()); } } }); @@ -405,7 +392,7 @@ import java.util.function.Consumer; mIconAlignment.value, mIconAlignment.getEndValue(), mLauncher.getDeviceProfile()); mControllers.navbarButtonsViewController.updateTaskbarAlignment(mIconAlignment.value); // Switch taskbar and hotseat in last frame - mIconAlphaForHome.setValue(taskbarWillBeVisible ? 1 : 0); + updateIconAlphaForHome(taskbarWillBeVisible ? 1 : 0); // Sync the first frame where we swap taskbar and hotseat. if (firstFrameVisChanged && mCanSyncViews && !Utilities.IS_RUNNING_IN_TEST_HARNESS) { @@ -415,6 +402,18 @@ import java.util.function.Consumer; } } + private void updateIconAlphaForHome(float alpha) { + mIconAlphaForHome.setValue(alpha); + + /* + * Hide Launcher Hotseat icons when Taskbar icons have opacity. Both icon sets + * should not be visible at the same time. + */ + mLauncher.getHotseat().setIconsAlpha(alpha > 0 ? 0 : 1); + mLauncher.getHotseat().setQsbAlpha( + mLauncher.getDeviceProfile().isQsbInline && alpha > 0 ? 0 : 1); + } + private final class TaskBarRecentsAnimationListener implements RecentsAnimationCallbacks.RecentsAnimationListener { private final RecentsAnimationCallbacks mCallbacks; diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index c5e1b8fdcd..64eb99e7d1 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -44,7 +44,7 @@ import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorListeners; import com.android.launcher3.testing.shared.TestProtocol; -import com.android.launcher3.util.MultiValueAlpha.AlphaProperty; +import com.android.launcher3.util.MultiPropertyFactory.MultiProperty; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.SystemUiProxy; @@ -144,11 +144,11 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba private AnimatedFloat mTaskbarBackgroundOffset; private AnimatedFloat mTaskbarImeBgAlpha; // TaskbarView icon properties. - private AlphaProperty mIconAlphaForStash; + private MultiProperty mIconAlphaForStash; private AnimatedFloat mIconScaleForStash; private AnimatedFloat mIconTranslationYForStash; // Stashed handle properties. - private AlphaProperty mTaskbarStashedHandleAlpha; + private MultiProperty mTaskbarStashedHandleAlpha; private AnimatedFloat mTaskbarStashedHandleHintScale; /** Whether we are currently visually stashed (might change based on launcher state). */ @@ -199,14 +199,14 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba mTaskbarImeBgAlpha = dragLayerController.getImeBgTaskbar(); TaskbarViewController taskbarViewController = controllers.taskbarViewController; - mIconAlphaForStash = taskbarViewController.getTaskbarIconAlpha().getProperty( + mIconAlphaForStash = taskbarViewController.getTaskbarIconAlpha().get( TaskbarViewController.ALPHA_INDEX_STASH); mIconScaleForStash = taskbarViewController.getTaskbarIconScaleForStash(); mIconTranslationYForStash = taskbarViewController.getTaskbarIconTranslationYForStash(); StashedHandleViewController stashedHandleController = controllers.stashedHandleViewController; - mTaskbarStashedHandleAlpha = stashedHandleController.getStashedHandleAlpha().getProperty( + mTaskbarStashedHandleAlpha = stashedHandleController.getStashedHandleAlpha().get( StashedHandleViewController.ALPHA_INDEX_STASHED); mTaskbarStashedHandleHintScale = stashedHandleController.getStashedHandleHintScale(); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 16dd90db29..a88c05deb6 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -50,6 +50,7 @@ import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.util.HorizontalInsettableView; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.LauncherBindableItemsContainer; +import com.android.launcher3.util.MultiPropertyFactory; import com.android.launcher3.util.MultiValueAlpha; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.SystemUiProxy; @@ -146,7 +147,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar return mTaskbarView.areIconsVisible(); } - public MultiValueAlpha getTaskbarIconAlpha() { + public MultiPropertyFactory getTaskbarIconAlpha() { return mTaskbarIconAlpha; } @@ -161,7 +162,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar * Should be called when the IME switcher visibility changes. */ public void setIsImeSwitcherVisible(boolean isImeSwitcherVisible) { - mTaskbarIconAlpha.getProperty(ALPHA_INDEX_IME_BUTTON_NAV).setValue( + mTaskbarIconAlpha.get(ALPHA_INDEX_IME_BUTTON_NAV).setValue( isImeSwitcherVisible ? 0 : 1); } @@ -170,7 +171,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar */ public void setRecentsButtonDisabled(boolean isDisabled) { // TODO: check TaskbarStashController#supportsStashing(), to stash instead of setting alpha. - mTaskbarIconAlpha.getProperty(ALPHA_INDEX_RECENTS_DISABLED).setValue(isDisabled ? 0 : 1); + mTaskbarIconAlpha.get(ALPHA_INDEX_RECENTS_DISABLED).setValue(isDisabled ? 0 : 1); } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt b/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt index 076900cd39..837af589bd 100644 --- a/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/VoiceInteractionWindowController.kt @@ -63,11 +63,11 @@ class VoiceInteractionWindowController(val context: TaskbarActivityContext) // Fade out taskbar icons and stashed handle. val taskbarIconAlpha = if (isVoiceInteractionWindowVisible) 0f else 1f val fadeTaskbarIcons = controllers.taskbarViewController.taskbarIconAlpha - .getProperty(TaskbarViewController.ALPHA_INDEX_ASSISTANT_INVOKED) + .get(TaskbarViewController.ALPHA_INDEX_ASSISTANT_INVOKED) .animateToValue(taskbarIconAlpha) .setDuration(TASKBAR_ICONS_FADE_DURATION) val fadeStashedHandle = controllers.stashedHandleViewController.stashedHandleAlpha - .getProperty(StashedHandleViewController.ALPHA_INDEX_ASSISTANT_INVOKED) + .get(StashedHandleViewController.ALPHA_INDEX_ASSISTANT_INVOKED) .animateToValue(taskbarIconAlpha) .setDuration(STASHED_HANDLE_FADE_DURATION) fadeTaskbarIcons.start() diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 2bf6f123a0..c962de22c8 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -45,7 +45,6 @@ import static com.android.launcher3.util.DisplayController.CHANGE_ACTIVE_SCREEN; import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE; import static com.android.launcher3.util.Executors.THREAD_POOL_EXECUTOR; import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR; -import static com.android.quickstep.util.BaseDepthController.WIDGET_DEPTH; import static com.android.systemui.shared.system.ActivityManagerWrapper.CLOSE_SYSTEM_WINDOWS_REASON_HOME_KEY; import android.animation.AnimatorSet; @@ -596,9 +595,8 @@ public class QuickstepLauncher extends Launcher { super.onWidgetsTransition(progress); onTaskbarInAppDisplayProgressUpdate(progress, WIDGETS_PAGE_PROGRESS_INDEX); if (mEnableWidgetDepth) { - WIDGET_DEPTH.set(getDepthController(), - Utilities.mapToRange(progress, 0f, 1f, 0f, getDeviceProfile().bottomSheetDepth, - EMPHASIZED)); + getDepthController().widgetDepth.setValue(Utilities.mapToRange( + progress, 0f, 1f, 0f, getDeviceProfile().bottomSheetDepth, EMPHASIZED)); } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java index 0e1120ba05..e8e83288cd 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/RecentsViewStateController.java @@ -20,6 +20,7 @@ import static com.android.launcher3.LauncherState.OVERVIEW_ACTIONS; import static com.android.launcher3.LauncherState.OVERVIEW_SPLIT_SELECT; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.states.StateAnimationConfig.ANIM_OVERVIEW_ACTIONS_FADE; +import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; 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; @@ -43,7 +44,6 @@ import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.states.StateAnimationConfig; import com.android.launcher3.touch.PagedOrientationHandler; -import com.android.launcher3.util.MultiValueAlpha; import com.android.quickstep.util.AnimUtils; import com.android.quickstep.util.SplitAnimationTimings; import com.android.quickstep.views.ClearAllButton; @@ -164,7 +164,7 @@ public final class RecentsViewStateController extends clearAllButtonAlpha, LINEAR); float overviewButtonAlpha = state.areElementsVisible(mLauncher, OVERVIEW_ACTIONS) ? 1 : 0; propertySetter.setFloat(mLauncher.getActionsView().getVisibilityAlpha(), - MultiValueAlpha.VALUE, overviewButtonAlpha, config.getInterpolator( + MULTI_PROPERTY_VALUE, overviewButtonAlpha, config.getInterpolator( ANIM_OVERVIEW_ACTIONS_FADE, LINEAR)); } diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java index 0a7d226da1..ecb37474e6 100644 --- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java +++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java @@ -22,6 +22,7 @@ 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.util.Executors.MAIN_EXECUTOR; +import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import android.animation.Animator; import android.animation.AnimatorSet; @@ -129,9 +130,9 @@ public final class LauncherActivityInterface extends // Animate the blur and wallpaper zoom float fromDepthRatio = BACKGROUND_APP.getDepth(activity); float toDepthRatio = OVERVIEW.getDepth(activity); - pa.addFloat(getDepthController(), + pa.addFloat(getDepthController().stateDepth, new LauncherAnimUtils.ClampedProperty<>( - DepthController.STATE_DEPTH, fromDepthRatio, toDepthRatio), + MULTI_PROPERTY_VALUE, fromDepthRatio, toDepthRatio), fromDepthRatio, toDepthRatio, LINEAR); } }; diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java index 7d6bbaccd1..9d5e7c362c 100644 --- a/quickstep/src/com/android/quickstep/TaskViewUtils.java +++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java @@ -36,7 +36,7 @@ import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncest import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.TOUCH_RESPONSE_INTERPOLATOR; import static com.android.launcher3.anim.Interpolators.clampToProgress; -import static com.android.launcher3.statehandlers.DepthController.STATE_DEPTH; +import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -376,8 +376,8 @@ public final class TaskViewUtils { }); if (depthController != null) { - out.setFloat(depthController, STATE_DEPTH, BACKGROUND_APP.getDepth(baseActivity), - TOUCH_RESPONSE_INTERPOLATOR); + out.setFloat(depthController.stateDepth, MULTI_PROPERTY_VALUE, + BACKGROUND_APP.getDepth(baseActivity), TOUCH_RESPONSE_INTERPOLATOR); } } diff --git a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java index 19a6c38901..062e50e30b 100644 --- a/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java +++ b/quickstep/src/com/android/quickstep/fallback/FallbackRecentsStateController.java @@ -45,7 +45,7 @@ import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.anim.PropertySetter; import com.android.launcher3.statemanager.StateManager.StateHandler; import com.android.launcher3.states.StateAnimationConfig; -import com.android.launcher3.util.MultiValueAlpha; +import com.android.launcher3.util.MultiPropertyFactory; import com.android.quickstep.RecentsActivity; import com.android.quickstep.views.ClearAllButton; @@ -95,7 +95,7 @@ public class FallbackRecentsStateController implements StateHandler DEPTH_PROPERTY_FACTORY = - new MultiPropertyFactory<>("depthProperty", DEPTH, Float::max); - - private static final int DEPTH_INDEX_STATE_TRANSITION = 1; - private static final int DEPTH_INDEX_WIDGET = 2; - - /** Property to set the depth for state transition. */ - public static final FloatProperty STATE_DEPTH = - DEPTH_PROPERTY_FACTORY.get(DEPTH_INDEX_STATE_TRANSITION); - /** Property to set the depth for widget picker. */ - public static final FloatProperty WIDGET_DEPTH = - DEPTH_PROPERTY_FACTORY.get(DEPTH_INDEX_WIDGET); + private static final int DEPTH_INDEX_STATE_TRANSITION = 0; + private static final int DEPTH_INDEX_WIDGET = 1; + private static final int DEPTH_INDEX_COUNT = 2; protected final Launcher mLauncher; + /** Property to set the depth for state transition. */ + public final MultiProperty stateDepth; + /** Property to set the depth for widget picker. */ + public final MultiProperty widgetDepth; /** * Blur radius when completely zoomed out, in pixels. @@ -92,6 +88,11 @@ public class BaseDepthController { mLauncher = activity; mMaxBlurRadius = activity.getResources().getInteger(R.integer.max_depth_blur_radius); mWallpaperManager = activity.getSystemService(WallpaperManager.class); + + MultiPropertyFactory depthProperty = + new MultiPropertyFactory<>(this, DEPTH, DEPTH_INDEX_COUNT, Float::max); + stateDepth = depthProperty.get(DEPTH_INDEX_STATE_TRANSITION); + widgetDepth = depthProperty.get(DEPTH_INDEX_WIDGET); } protected void setCrossWindowBlursEnabled(boolean isEnabled) { diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java index 514d5b98bf..a16ff8fca1 100644 --- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java +++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java @@ -33,8 +33,8 @@ import com.android.launcher3.Insettable; import com.android.launcher3.R; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.util.DisplayController; +import com.android.launcher3.util.MultiPropertyFactory.MultiProperty; import com.android.launcher3.util.MultiValueAlpha; -import com.android.launcher3.util.MultiValueAlpha.AlphaProperty; import com.android.launcher3.util.NavigationMode; import com.android.quickstep.TaskOverlayFactory.OverlayUICallbacks; import com.android.quickstep.util.LayoutUtils; @@ -130,7 +130,6 @@ public class OverviewActionsView extends FrameLayo mMultiValueAlpha.setUpdateVisibility(true); findViewById(R.id.action_screenshot).setOnClickListener(this); - mSplitButton = findViewById(R.id.action_split); mSplitButton.setOnClickListener(this); } @@ -177,7 +176,7 @@ public class OverviewActionsView extends FrameLayo mHiddenFlags &= ~visibilityFlags; } boolean isHidden = mHiddenFlags != 0; - mMultiValueAlpha.getProperty(INDEX_HIDDEN_FLAGS_ALPHA).setValue(isHidden ? 0 : 1); + mMultiValueAlpha.get(INDEX_HIDDEN_FLAGS_ALPHA).setValue(isHidden ? 0 : 1); } /** @@ -232,20 +231,20 @@ public class OverviewActionsView extends FrameLayo updateSplitButtonEnabledState(); } - public AlphaProperty getContentAlpha() { - return mMultiValueAlpha.getProperty(INDEX_CONTENT_ALPHA); + public MultiProperty getContentAlpha() { + return mMultiValueAlpha.get(INDEX_CONTENT_ALPHA); } - public AlphaProperty getVisibilityAlpha() { - return mMultiValueAlpha.getProperty(INDEX_VISIBILITY_ALPHA); + public MultiProperty getVisibilityAlpha() { + return mMultiValueAlpha.get(INDEX_VISIBILITY_ALPHA); } - public AlphaProperty getFullscreenAlpha() { - return mMultiValueAlpha.getProperty(INDEX_FULLSCREEN_ALPHA); + public MultiProperty getFullscreenAlpha() { + return mMultiValueAlpha.get(INDEX_FULLSCREEN_ALPHA); } - public AlphaProperty getShareTargetAlpha() { - return mMultiValueAlpha.getProperty(INDEX_SHARE_TARGET_ALPHA); + public MultiProperty getShareTargetAlpha() { + return mMultiValueAlpha.get(INDEX_SHARE_TARGET_ALPHA); } /** diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 72467e6cd3..ce96b7168e 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -45,10 +45,10 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH 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; -import static com.android.launcher3.statehandlers.DepthController.STATE_DEPTH; import static com.android.launcher3.touch.PagedOrientationHandler.CANVAS_TRANSLATE; 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.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT; import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT; import static com.android.launcher3.util.SystemUiController.UI_STATE_FULLSCREEN_TASK; @@ -147,7 +147,6 @@ import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.DynamicResource; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.IntSet; -import com.android.launcher3.util.MultiValueAlpha; import com.android.launcher3.util.ResourceBasedOverride.Overrides; import com.android.launcher3.util.RunnableList; import com.android.launcher3.util.SplitConfigurationOptions.SplitBounds; @@ -1897,7 +1896,7 @@ public abstract class RecentsView - mAppsViewTranslationYPropertyFactory = new MultiPropertyFactory<>( - "appsViewTranslationY", View.TRANSLATION_Y, Float::sum); private MultiValueAlpha mAppsViewAlpha; + private MultiPropertyFactory mAppsViewTranslationY; private boolean mIsTablet; @@ -184,7 +182,7 @@ public class AllAppsTransitionController */ public void setProgress(float progress) { mProgress = progress; - getAppsViewProgressTranslationY().set(mAppsView, mProgress * mShiftRange); + getAppsViewProgressTranslationY().setValue(mProgress * mShiftRange); mLauncher.onAllAppsTransition(1 - progress); } @@ -192,20 +190,20 @@ public class AllAppsTransitionController return mProgress; } - private FloatProperty getAppsViewProgressTranslationY() { - return mAppsViewTranslationYPropertyFactory.get(INDEX_APPS_VIEW_PROGRESS); + private MultiProperty getAppsViewProgressTranslationY() { + return mAppsViewTranslationY.get(INDEX_APPS_VIEW_PROGRESS); } - private FloatProperty getAppsViewPullbackTranslationY() { - return mAppsViewTranslationYPropertyFactory.get(INDEX_APPS_VIEW_PULLBACK); + private MultiProperty getAppsViewPullbackTranslationY() { + return mAppsViewTranslationY.get(INDEX_APPS_VIEW_PULLBACK); } - private MultiValueAlpha.AlphaProperty getAppsViewProgressAlpha() { - return mAppsViewAlpha.getProperty(INDEX_APPS_VIEW_PROGRESS); + private MultiProperty getAppsViewProgressAlpha() { + return mAppsViewAlpha.get(INDEX_APPS_VIEW_PROGRESS); } - private MultiValueAlpha.AlphaProperty getAppsViewPullbackAlpha() { - return mAppsViewAlpha.getProperty(INDEX_APPS_VIEW_PULLBACK); + private MultiProperty getAppsViewPullbackAlpha() { + return mAppsViewAlpha.get(INDEX_APPS_VIEW_PULLBACK); } /** @@ -283,7 +281,7 @@ public class AllAppsTransitionController boolean hasAllAppsContent = (visibleElements & ALL_APPS_CONTENT) != 0; Interpolator allAppsFade = config.getInterpolator(ANIM_ALL_APPS_FADE, LINEAR); - setter.setFloat(getAppsViewProgressAlpha(), MultiValueAlpha.VALUE, + setter.setFloat(getAppsViewProgressAlpha(), MultiPropertyFactory.MULTI_PROPERTY_VALUE, hasAllAppsContent ? 1 : 0, allAppsFade); boolean shouldProtectHeader = @@ -302,8 +300,11 @@ public class AllAppsTransitionController mScrimView = scrimView; mAppsView = appsView; mAppsView.setScrimView(scrimView); + mAppsViewAlpha = new MultiValueAlpha(mAppsView, APPS_VIEW_INDEX_COUNT); mAppsViewAlpha.setUpdateVisibility(true); + mAppsViewTranslationY = new MultiPropertyFactory<>( + mAppsView, VIEW_TRANSLATE_Y, APPS_VIEW_INDEX_COUNT, Float::sum); } /** diff --git a/src/com/android/launcher3/util/MultiPropertyFactory.java b/src/com/android/launcher3/util/MultiPropertyFactory.java index 43daf087ee..f34c4c2451 100644 --- a/src/com/android/launcher3/util/MultiPropertyFactory.java +++ b/src/com/android/launcher3/util/MultiPropertyFactory.java @@ -16,10 +16,13 @@ package com.android.launcher3.util; -import android.util.ArrayMap; +import android.animation.Animator; +import android.animation.ObjectAnimator; import android.util.FloatProperty; import android.util.Log; -import android.util.Property; + +import java.io.PrintWriter; +import java.util.Arrays; /** * Allows to combine multiple values set by several sources. @@ -35,15 +38,30 @@ import android.util.Property; */ public class MultiPropertyFactory { + public static final FloatProperty.MultiProperty> MULTI_PROPERTY_VALUE = + new FloatProperty.MultiProperty>("value") { + + @Override + public Float get(MultiPropertyFactory.MultiProperty property) { + return property.mValue; + } + + @Override + public void setValue(MultiPropertyFactory.MultiProperty property, float value) { + property.setValue(value); + } + }; + private static final boolean DEBUG = false; private static final String TAG = "MultiPropertyFactory"; - private final String mName; - private final ArrayMap mProperties = new ArrayMap<>(); + private final MultiPropertyFactory.MultiProperty[] mProperties; // This is an optimization for cases when set is called repeatedly with the same setterIndex. private float mAggregationOfOthers = 0f; - private Integer mLastIndexSet = -1; - private final Property mProperty; + private int mLastIndexSet = -1; + + protected final T mTarget; + private final FloatProperty mProperty; private final FloatBiFunction mAggregator; /** @@ -56,59 +74,99 @@ public class MultiPropertyFactory { float apply(float a, float b); } - public MultiPropertyFactory(String name, Property property, + public MultiPropertyFactory(T target, FloatProperty property, int size, FloatBiFunction aggregator) { - mName = name; + this(target, property, size, aggregator, 0); + } + + public MultiPropertyFactory(T target, FloatProperty property, int size, + FloatBiFunction aggregator, float defaultPropertyValue) { + mTarget = target; mProperty = property; mAggregator = aggregator; + + mProperties = new MultiPropertyFactory.MultiProperty[size]; + for (int i = 0; i < size; i++) { + mProperties[i] = new MultiProperty(i, defaultPropertyValue); + } } /** Returns the [MultiFloatProperty] associated with [inx], creating it if not present. */ - public MultiProperty get(Integer index) { - return mProperties.computeIfAbsent(index, - (k) -> new MultiProperty(index, mName + "_" + index)); + public MultiProperty get(int index) { + return (MultiProperty) mProperties[index]; + } + + @Override + public String toString() { + return Arrays.deepToString(mProperties); + } + + /** + * Dumps the alpha channel values to the given PrintWriter + * + * @param prefix String to be used before every line + * @param pw PrintWriter where the logs should be dumped + * @param label String used to help identify this object + * @param alphaIndexLabels Strings that represent each alpha channel, these should be entered + * in the order of the indexes they represent, starting from 0. + */ + public void dump(String prefix, PrintWriter pw, String label, String... alphaIndexLabels) { + pw.println(prefix + label); + + String innerPrefix = prefix + '\t'; + for (int i = 0; i < alphaIndexLabels.length; i++) { + if (i >= mProperties.length) { + pw.println(innerPrefix + alphaIndexLabels[i] + " given for alpha index " + i + + " however there are only " + mProperties.length + " alpha channels."); + continue; + } + pw.println(innerPrefix + alphaIndexLabels[i] + "=" + get(i).getValue()); + } } /** * Each [setValue] will be aggregated with the other properties values created by the * corresponding factory. */ - class MultiProperty extends FloatProperty { - private final int mInx; - private float mValue = 0f; + public class MultiProperty { - MultiProperty(int inx, String name) { - super(name); + private final int mInx; + private final float mDefaultValue; + private float mValue; + + MultiProperty(int inx, float defaultValue) { mInx = inx; + mDefaultValue = defaultValue; + mValue = defaultValue; } - @Override - public void setValue(T obj, float newValue) { + public void setValue(float newValue) { if (mLastIndexSet != mInx) { - mAggregationOfOthers = 0f; - mProperties.forEach((key, property) -> { - if (key != mInx) { + mAggregationOfOthers = mDefaultValue; + for (MultiPropertyFactory.MultiProperty other : mProperties) { + if (other.mInx != mInx) { mAggregationOfOthers = - mAggregator.apply(mAggregationOfOthers, property.mValue); + mAggregator.apply(mAggregationOfOthers, other.mValue); } - }); + } + mLastIndexSet = mInx; } float lastAggregatedValue = mAggregator.apply(mAggregationOfOthers, newValue); mValue = newValue; - apply(obj, lastAggregatedValue); + apply(lastAggregatedValue); if (DEBUG) { - Log.d(TAG, "name=" + mName - + " newValue=" + newValue + " mInx=" + mInx - + " aggregated=" + lastAggregatedValue + " others= " + mProperties); + Log.d(TAG, "name=" + mProperty.getName() + + " target=" + mTarget.getClass() + + " newValue=" + newValue + + " mInx=" + mInx + + " aggregated=" + lastAggregatedValue + + " others= " + Arrays.deepToString(mProperties)); } } - @Override - public Float get(T object) { - // Callers of MultiProperty should only care about the sub-property that it sets. If - // the overall value is needed, mProperty.get should be called directly. + public float getValue() { return mValue; } @@ -116,9 +174,19 @@ public class MultiPropertyFactory { public String toString() { return String.valueOf(mValue); } + + /** + * Creates and returns an Animator from the current value to the given value. Future + * animator on the same target automatically cancels the previous one. + */ + public Animator animateToValue(float value) { + ObjectAnimator animator = ObjectAnimator.ofFloat(this, MULTI_PROPERTY_VALUE, value); + animator.setAutoCancel(true); + return animator; + } } - protected void apply(T object, float value) { - mProperty.set(object, value); + protected void apply(float value) { + mProperty.set(mTarget, value); } } diff --git a/src/com/android/launcher3/util/MultiValueAlpha.java b/src/com/android/launcher3/util/MultiValueAlpha.java index 4b46a0a04c..ac016a8595 100644 --- a/src/com/android/launcher3/util/MultiValueAlpha.java +++ b/src/com/android/launcher3/util/MultiValueAlpha.java @@ -16,62 +16,24 @@ package com.android.launcher3.util; -import android.animation.Animator; -import android.animation.ObjectAnimator; -import android.util.FloatProperty; +import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA; + import android.view.View; import com.android.launcher3.anim.AlphaUpdateListener; -import java.io.PrintWriter; -import java.util.Arrays; -import java.util.function.Consumer; - /** * Utility class to handle separating a single value as a factor of multiple values */ -public class MultiValueAlpha { +public class MultiValueAlpha extends MultiPropertyFactory { - public static final FloatProperty VALUE = - new FloatProperty("value") { + private static final FloatBiFunction ALPHA_AGGREGATOR = (a, b) -> a * b; - @Override - public Float get(AlphaProperty alphaProperty) { - return alphaProperty.mValue; - } - - @Override - public void setValue(AlphaProperty object, float value) { - object.setValue(value); - } - }; - - private final View mView; - private final AlphaProperty[] mMyProperties; - - private int mValidMask; // Whether we should change from INVISIBLE to VISIBLE and vice versa at low alpha values. private boolean mUpdateVisibility; public MultiValueAlpha(View view, int size) { - mView = view; - mMyProperties = new AlphaProperty[size]; - - mValidMask = 0; - for (int i = 0; i < size; i++) { - int myMask = 1 << i; - mValidMask |= myMask; - mMyProperties[i] = new AlphaProperty(myMask); - } - } - - @Override - public String toString() { - return Arrays.toString(mMyProperties); - } - - public AlphaProperty getProperty(int index) { - return mMyProperties[index]; + super(view, VIEW_ALPHA, size, ALPHA_AGGREGATOR, 1f); } /** Sets whether we should update between INVISIBLE and VISIBLE based on alpha. */ @@ -79,97 +41,11 @@ public class MultiValueAlpha { mUpdateVisibility = updateVisibility; } - /** - * Dumps the alpha channel values to the given PrintWriter - * - * @param prefix String to be used before every line - * @param pw PrintWriter where the logs should be dumped - * @param label String used to help identify this object - * @param alphaIndexLabels Strings that represent each alpha channel, these should be entered - * in the order of the indexes they represent, starting from 0. - */ - public void dump(String prefix, PrintWriter pw, String label, String... alphaIndexLabels) { - pw.println(prefix + label); - - String innerPrefix = prefix + '\t'; - for (int i = 0; i < alphaIndexLabels.length; i++) { - if (i >= mMyProperties.length) { - pw.println(innerPrefix + alphaIndexLabels[i] + " given for alpha index " + i - + " however there are only " + mMyProperties.length + " alpha channels."); - continue; - } - pw.println(innerPrefix + alphaIndexLabels[i] + "=" + getProperty(i).getValue()); - } - } - - public class AlphaProperty { - - private final int mMyMask; - - private float mValue = 1; - // Factor of all other alpha channels, only valid if mMyMask is present in mValidMask. - private float mOthers = 1; - - private Consumer mConsumer; - - AlphaProperty(int myMask) { - mMyMask = myMask; - } - - public void setValue(float value) { - if (mValue == value) { - return; - } - - if ((mValidMask & mMyMask) == 0) { - // Our cache value is not correct, recompute it. - mOthers = 1; - for (AlphaProperty prop : mMyProperties) { - if (prop != this) { - mOthers *= prop.mValue; - } - } - } - - // Since we have changed our value, all other caches except our own need to be - // recomputed. Change mValidMask to indicate the new valid caches (only our own). - mValidMask = mMyMask; - mValue = value; - - final float alpha = mOthers * mValue; - mView.setAlpha(alpha); - if (mUpdateVisibility) { - AlphaUpdateListener.updateVisibility(mView); - } - if (mConsumer != null) { - mConsumer.accept(mValue); - } - } - - public float getValue() { - return mValue; - } - - public void setConsumer(Consumer consumer) { - mConsumer = consumer; - if (mConsumer != null) { - mConsumer.accept(mValue); - } - } - - @Override - public String toString() { - return Float.toString(mValue); - } - - /** - * Creates and returns an Animator from the current value to the given value. Future - * animator on the same target automatically cancels the previous one. - */ - public Animator animateToValue(float value) { - ObjectAnimator animator = ObjectAnimator.ofFloat(this, VALUE, value); - animator.setAutoCancel(true); - return animator; + @Override + protected void apply(float value) { + super.apply(value); + if (mUpdateVisibility) { + AlphaUpdateListener.updateVisibility(mTarget); } } } diff --git a/src/com/android/launcher3/views/BaseDragLayer.java b/src/com/android/launcher3/views/BaseDragLayer.java index 1e154a2dfb..77992a2e89 100644 --- a/src/com/android/launcher3/views/BaseDragLayer.java +++ b/src/com/android/launcher3/views/BaseDragLayer.java @@ -22,7 +22,6 @@ import static android.view.MotionEvent.ACTION_UP; import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs; -import android.app.WallpaperManager; import android.content.Context; import android.graphics.Insets; import android.graphics.Rect; @@ -41,8 +40,8 @@ import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.DeviceProfile; import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.Utilities; +import com.android.launcher3.util.MultiPropertyFactory.MultiProperty; import com.android.launcher3.util.MultiValueAlpha; -import com.android.launcher3.util.MultiValueAlpha.AlphaProperty; import com.android.launcher3.util.TouchController; import java.io.PrintWriter; @@ -108,7 +107,6 @@ public abstract class BaseDragLayer protected final T mActivity; private final MultiValueAlpha mMultiValueAlpha; - private final WallpaperManager mWallpaperManager; // All the touch controllers for the view protected TouchController[] mControllers; @@ -121,9 +119,8 @@ public abstract class BaseDragLayer public BaseDragLayer(Context context, AttributeSet attrs, int alphaChannelCount) { super(context, attrs); - mActivity = (T) ActivityContext.lookupContext(context); + mActivity = ActivityContext.lookupContext(context); mMultiValueAlpha = new MultiValueAlpha(this, alphaChannelCount); - mWallpaperManager = context.getSystemService(WallpaperManager.class); } /** @@ -508,8 +505,8 @@ public abstract class BaseDragLayer return new LayoutParams(p); } - public AlphaProperty getAlphaProperty(int index) { - return mMultiValueAlpha.getProperty(index); + public MultiProperty getAlphaProperty(int index) { + return mMultiValueAlpha.get(index); } public void dump(String prefix, PrintWriter writer) { diff --git a/tests/src/com/android/launcher3/util/MultiPropertyFactoryTest.kt b/tests/src/com/android/launcher3/util/MultiPropertyFactoryTest.kt index a4f189c6b3..bf3a092adb 100644 --- a/tests/src/com/android/launcher3/util/MultiPropertyFactoryTest.kt +++ b/tests/src/com/android/launcher3/util/MultiPropertyFactoryTest.kt @@ -39,21 +39,21 @@ class MultiPropertyFactoryTest { } } - private val factory = MultiPropertyFactory("depth_property", receiveProperty) { + private val factory = MultiPropertyFactory(null, receiveProperty, 3) { x: Float, y: Float -> x + y } - private val p1 = factory.get(1) - private val p2 = factory.get(2) - private val p3 = factory.get(3) + private val p1 = factory.get(0) + private val p2 = factory.get(1) + private val p3 = factory.get(2) @Test fun set_sameIndexes_allApplied() { val v1 = 50f val v2 = 100f - p1.set(null, v1) - p1.set(null, v1) - p1.set(null, v2) + p1.value = v1 + p1.value = v1 + p1.value = v2 assertThat(received).containsExactly(v1, v1, v2) } @@ -63,9 +63,9 @@ class MultiPropertyFactoryTest { val v1 = 50f val v2 = 100f val v3 = 150f - p1.set(null, v1) - p2.set(null, v2) - p3.set(null, v3) + p1.value = v1 + p2.value = v2 + p3.value = v3 assertThat(received).containsExactly(v1, v1 + v2, v1 + v2 + v3) } From 8ca56fe1cd8867624323c1461b8fd93fd5286f88 Mon Sep 17 00:00:00 2001 From: Sihua Ma Date: Mon, 24 Oct 2022 14:28:19 -0700 Subject: [PATCH 117/429] Get rid of setInteractionHandler call to the host in launcher Bug: 235358918 Test: N/A Change-Id: I0defac1831825bf0a13a601dd1502b4ca022bc2e --- .../launcher3/uioverrides/ApiWrapper.java | 20 ++++++++++++++++++- .../QuickstepInteractionHandler.java | 4 +++- .../uioverrides/QuickstepLauncher.java | 3 ++- .../widget/LauncherAppWidgetHost.java | 20 +++++++++++++++++++ .../launcher3/uioverrides/ApiWrapper.java | 20 ++++++++++++++++++- 5 files changed, 63 insertions(+), 4 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java index f450496b3b..729eea9834 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java +++ b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java @@ -17,10 +17,18 @@ package com.android.launcher3.uioverrides; import android.app.Person; +import android.appwidget.AppWidgetHost; import android.content.pm.ShortcutInfo; -import com.android.launcher3.Utilities; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.android.launcher3.Utilities; +import com.android.launcher3.widget.LauncherAppWidgetHost; + +/** + * A wrapper for the hidden API calls + */ public class ApiWrapper { public static final boolean TASKBAR_DRAWN_IN_PROCESS = true; @@ -29,4 +37,14 @@ public class ApiWrapper { Person[] persons = si.getPersons(); return persons == null ? Utilities.EMPTY_PERSON_ARRAY : persons; } + + /** + * Set the interaction handler for the host + * @param host AppWidgetHost that needs the interaction handler + * @param handler InteractionHandler for the views in the host + */ + public static void setHostInteractionHandler(@NonNull AppWidgetHost host, + @Nullable LauncherAppWidgetHost.LauncherWidgetInteractionHandler handler) { + host.setInteractionHandler(handler::onInteraction); + } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java index 08d147f7cf..2dde6b6148 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java @@ -33,10 +33,12 @@ import com.android.launcher3.Utilities; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.util.ActivityOptionsWrapper; +import com.android.launcher3.widget.LauncherAppWidgetHost; import com.android.launcher3.widget.LauncherAppWidgetHostView; /** Provides a Quickstep specific animation when launching an activity from an app widget. */ -class QuickstepInteractionHandler implements RemoteViews.InteractionHandler { +class QuickstepInteractionHandler implements + LauncherAppWidgetHost.LauncherWidgetInteractionHandler { private static final String TAG = "QuickstepInteractionHandler"; diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 3203f44ce2..fbbb1a2c22 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -487,7 +487,8 @@ public class QuickstepLauncher extends Launcher { protected LauncherAppWidgetHost createAppWidgetHost() { LauncherAppWidgetHost appWidgetHost = super.createAppWidgetHost(); - appWidgetHost.setInteractionHandler(new QuickstepInteractionHandler(this)); + ApiWrapper.setHostInteractionHandler(appWidgetHost, + new QuickstepInteractionHandler(this)); return appWidgetHost; } diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHost.java b/src/com/android/launcher3/widget/LauncherAppWidgetHost.java index 3e80699f59..fff8fbb12a 100644 --- a/src/com/android/launcher3/widget/LauncherAppWidgetHost.java +++ b/src/com/android/launcher3/widget/LauncherAppWidgetHost.java @@ -18,6 +18,7 @@ package com.android.launcher3.widget; import static android.app.Activity.RESULT_CANCELED; +import android.app.PendingIntent; import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetManager; @@ -28,6 +29,7 @@ import android.content.Intent; import android.os.Bundle; import android.os.Handler; import android.util.SparseArray; +import android.view.View; import android.widget.RemoteViews; import android.widget.Toast; @@ -80,6 +82,24 @@ public class LauncherAppWidgetHost extends AppWidgetHost { private IntConsumer mAppWidgetRemovedCallback = null; + /** + * This serves for the purpose of getting rid of the hidden API calling of InteractionHandler + */ + public interface LauncherWidgetInteractionHandler { + /** + * Invoked when the user performs an interaction on the View. + * + * @param view the View with which the user interacted + * @param pendingIntent the base PendingIntent associated with the view + * @param response the response to the interaction, which knows how to fill in the + * attached PendingIntent + */ + boolean onInteraction( + View view, + PendingIntent pendingIntent, + RemoteViews.RemoteResponse response); + } + public LauncherAppWidgetHost(Context context) { this(context, null); } diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java b/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java index c8b5e2fa37..ea0f5a3c5d 100644 --- a/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java +++ b/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java @@ -17,10 +17,18 @@ package com.android.launcher3.uioverrides; import android.app.Person; +import android.appwidget.AppWidgetHost; import android.content.pm.ShortcutInfo; -import com.android.launcher3.Utilities; +import androidx.annotation.NonNull; +import androidx.annotation.Nullable; +import com.android.launcher3.Utilities; +import com.android.launcher3.widget.LauncherAppWidgetHost; + +/** + * A wrapper for the hidden API calls + */ public class ApiWrapper { public static final boolean TASKBAR_DRAWN_IN_PROCESS = false; @@ -28,4 +36,14 @@ public class ApiWrapper { public static Person[] getPersons(ShortcutInfo si) { return Utilities.EMPTY_PERSON_ARRAY; } + + /** + * Set the interaction handler for the host + * @param host AppWidgetHost that needs the interaction handler + * @param handler InteractionHandler for the views in the host + */ + public static void setHostInteractionHandler(@NonNull AppWidgetHost host, + @Nullable LauncherAppWidgetHost.LauncherWidgetInteractionHandler handler) { + // No-op + } } From 96cad794d75d284930391084d8f47c68e861c95b Mon Sep 17 00:00:00 2001 From: Saumya Prakash Date: Tue, 11 Oct 2022 00:25:59 +0000 Subject: [PATCH 118/429] Removed disabled overview actions at end of scroll Updated visibility of the overview action bar so that when viewing the clear all button at the end of the tasks it becomes hidden. Previously, the overview actions were disabled so they were not usable anyways. Updated the corresponding tests because expected behavior was changed. Test: Manual Fix: 230508197 Change-Id: I17628f1fa3869b575ec404a2a630a6927e3c1d14 --- .../quickstep/views/ClearAllButton.java | 4 +++ .../quickstep/views/OverviewActionsView.java | 8 ++++- .../android/quickstep/views/RecentsView.java | 3 ++ .../android/launcher3/tapl/BaseOverview.java | 32 ++++++++----------- 4 files changed, 28 insertions(+), 19 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/ClearAllButton.java b/quickstep/src/com/android/quickstep/views/ClearAllButton.java index 50be5ea565..d098ffc2fb 100644 --- a/quickstep/src/com/android/quickstep/views/ClearAllButton.java +++ b/quickstep/src/com/android/quickstep/views/ClearAllButton.java @@ -99,6 +99,10 @@ public class ClearAllButton extends Button { return false; } + public float getScrollAlpha() { + return mScrollAlpha; + } + public void setContentAlpha(float alpha) { if (mContentAlpha != alpha) { mContentAlpha = alpha; diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java index abace7cd7d..997200b746 100644 --- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java +++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java @@ -81,6 +81,8 @@ public class OverviewActionsView extends FrameLayo private static final int INDEX_FULLSCREEN_ALPHA = 2; private static final int INDEX_HIDDEN_FLAGS_ALPHA = 3; private static final int INDEX_SHARE_TARGET_ALPHA = 4; + private static final int INDEX_SCROLL_ALPHA = 5; + private static final int NUM_ALPHAS = 6; public @interface SplitButtonHiddenFlags { } public static final int FLAG_IS_NOT_TABLET = 1 << 0; @@ -125,7 +127,7 @@ public class OverviewActionsView extends FrameLayo @Override protected void onFinishInflate() { super.onFinishInflate(); - mMultiValueAlpha = new MultiValueAlpha(findViewById(R.id.action_buttons), 5); + mMultiValueAlpha = new MultiValueAlpha(findViewById(R.id.action_buttons), NUM_ALPHAS); mMultiValueAlpha.setUpdateVisibility(true); findViewById(R.id.action_screenshot).setOnClickListener(this); @@ -247,6 +249,10 @@ public class OverviewActionsView extends FrameLayo return mMultiValueAlpha.getProperty(INDEX_SHARE_TARGET_ALPHA); } + public AlphaProperty getIndexScrollAlpha() { + return mMultiValueAlpha.getProperty(INDEX_SCROLL_ALPHA); + } + /** * Offsets OverviewActionsView horizontal position based on 3 button nav container in taskbar. */ diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 68b80c26f6..64e8295237 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -1890,6 +1890,9 @@ public abstract class RecentsView= 1) { + return false; + } + // Overview actions aren't visible for split screen tasks. return !task.isTaskSplit(); } private void verifyActionsViewVisibility() { - if (!hasTasks() || !isActionsViewVisible()) { - return; - } try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "want to assert overview actions view visibility")) { - if (mLauncher.isTablet() && !isOverviewSnappedToFocusedTaskForTablet()) { - mLauncher.waitUntilOverviewObjectGone("action_buttons"); - } else { + if (isActionsViewVisible()) { mLauncher.waitForOverviewObject("action_buttons"); + } else { + mLauncher.waitUntilOverviewObjectGone("action_buttons"); } } } - /** - * Returns if focused task is currently snapped task in tablet grid overview. - */ - private boolean isOverviewSnappedToFocusedTaskForTablet() { - OverviewTask focusedTask = getFocusedTaskForTablet(); - if (focusedTask == null) { - return false; - } - return Math.abs(focusedTask.getExactCenterX() - mLauncher.getExactScreenCenterX()) < 1; - } - /** * Returns Overview focused task if it exists. * From 97ae16e80c54d5935c63803d9945b40a813c84db Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Mon, 24 Oct 2022 15:49:27 -0700 Subject: [PATCH 119/429] Updating AIDL interface and removing unused methods Bug: 193244407 Test: Presubmit Change-Id: If87ef08e16e541921cde4e7a15a675b07c388fef --- .../com/android/quickstep/AbsSwipeUpHandler.java | 1 - .../src/com/android/quickstep/SystemUiProxy.java | 11 ----------- .../android/quickstep/TouchInteractionService.java | 14 ++++---------- 3 files changed, 4 insertions(+), 22 deletions(-) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 267593a2e7..df08596c5a 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -951,7 +951,6 @@ public abstract class AbsSwipeUpHandler, new ActiveGestureLog.CompoundString("on gesture started (animate=false)")); mStateCallback.setStateOnUiThread(STATE_GESTURE_STARTED); mGestureStarted = true; - SystemUiProxy.INSTANCE.get(mContext).notifySwipeUpGestureStarted(); } /** diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index 7705a2512a..256e68992c 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -346,17 +346,6 @@ public class SystemUiProxy implements ISystemUiProxy { } } - @Override - public void notifySwipeUpGestureStarted() { - if (mSystemUiProxy != null) { - try { - mSystemUiProxy.notifySwipeUpGestureStarted(); - } catch (RemoteException e) { - Log.w(TAG, "Failed call notifySwipeUpGestureStarted", e); - } - } - } - @Override public void notifyPrioritizedRotation(int rotation) { if (mSystemUiProxy != null) { diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 80db362b09..239b3fc70f 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -60,6 +60,7 @@ import android.util.Log; import android.view.Choreographer; import android.view.InputEvent; import android.view.MotionEvent; +import android.view.SurfaceControl; import android.view.accessibility.AccessibilityManager; import androidx.annotation.BinderThread; @@ -230,12 +231,6 @@ public class TouchInteractionService extends Service } } - @BinderThread - @Override - public void onTip(int actionType, int viewType) { - // Please delete this method from the interface - } - @BinderThread @Override public void onAssistantAvailable(boolean available) { @@ -254,10 +249,9 @@ public class TouchInteractionService extends Service }); } - @BinderThread - public void onBackAction(boolean completed, int downX, int downY, boolean isButton, - boolean gestureSwipeLeft) { - // Remove this method from the interface + @Override + public void onNavigationBarSurface(SurfaceControl surface) { + // TODO: implement } @BinderThread From fb65436faebee0f12e18b3f479e982471633c509 Mon Sep 17 00:00:00 2001 From: Andras Kloczl Date: Tue, 13 Sep 2022 17:48:21 +0200 Subject: [PATCH 120/429] Improve All Set page UI for large screens Test: manual Screenrecordings: https://drive.google.com/drive/folders/1S6kjenZn0kP-W2tPpUemre2x0368ACyr?usp=sharing Bug: 233610579 Change-Id: I9a33efe193a96e752766feb1e91cf0ac9b30246f --- .../allset_navigation_and_hint.xml | 43 ++++++++++++++ .../allset_navigation_and_hint.xml | 44 +++++++++++++++ quickstep/res/layout/activity_allset.xml | 38 +------------ .../res/layout/allset_navigation_and_hint.xml | 56 +++++++++++++++++++ .../res/raw-sw600dp-land/all_set_page_bg.json | 1 + .../res/raw-sw600dp/all_set_page_bg.json | 1 + .../res}/raw/all_set_page_bg.json | 2 +- quickstep/res/values-sw600dp-land/dimens.xml | 5 ++ quickstep/res/values-sw600dp/dimens.xml | 7 +++ quickstep/res/values-sw720dp-land/dimens.xml | 3 + quickstep/res/values-sw720dp/dimens.xml | 5 ++ quickstep/res/values/dimens.xml | 4 ++ quickstep/res/values/styles.xml | 1 + .../quickstep/interaction/AllSetActivity.java | 5 ++ 14 files changed, 177 insertions(+), 38 deletions(-) create mode 100644 quickstep/res/layout-sw600dp-land/allset_navigation_and_hint.xml create mode 100644 quickstep/res/layout-sw600dp/allset_navigation_and_hint.xml create mode 100644 quickstep/res/layout/allset_navigation_and_hint.xml create mode 100644 quickstep/res/raw-sw600dp-land/all_set_page_bg.json create mode 100644 quickstep/res/raw-sw600dp/all_set_page_bg.json rename {res => quickstep/res}/raw/all_set_page_bg.json (98%) diff --git a/quickstep/res/layout-sw600dp-land/allset_navigation_and_hint.xml b/quickstep/res/layout-sw600dp-land/allset_navigation_and_hint.xml new file mode 100644 index 0000000000..3bfa6da49d --- /dev/null +++ b/quickstep/res/layout-sw600dp-land/allset_navigation_and_hint.xml @@ -0,0 +1,43 @@ + + + + + + + + + \ No newline at end of file diff --git a/quickstep/res/layout-sw600dp/allset_navigation_and_hint.xml b/quickstep/res/layout-sw600dp/allset_navigation_and_hint.xml new file mode 100644 index 0000000000..9559072f8f --- /dev/null +++ b/quickstep/res/layout-sw600dp/allset_navigation_and_hint.xml @@ -0,0 +1,44 @@ + + + + + + + + + \ No newline at end of file diff --git a/quickstep/res/layout/activity_allset.xml b/quickstep/res/layout/activity_allset.xml index 56e1d16281..f08cabe13e 100644 --- a/quickstep/res/layout/activity_allset.xml +++ b/quickstep/res/layout/activity_allset.xml @@ -34,8 +34,6 @@ android:layout_height="match_parent" android:gravity="center" android:scaleType="centerCrop" - - app:lottie_rawRes="@raw/all_set_page_bg" app:lottie_autoPlay="true" app:lottie_loop="true" /> @@ -79,42 +77,8 @@ app:layout_constraintStart_toStartOf="parent" android:gravity="start"/> - + - - - - - diff --git a/quickstep/res/layout/allset_navigation_and_hint.xml b/quickstep/res/layout/allset_navigation_and_hint.xml new file mode 100644 index 0000000000..4d5cf01eaa --- /dev/null +++ b/quickstep/res/layout/allset_navigation_and_hint.xml @@ -0,0 +1,56 @@ + + + + + + + + + + + + + \ No newline at end of file diff --git a/quickstep/res/raw-sw600dp-land/all_set_page_bg.json b/quickstep/res/raw-sw600dp-land/all_set_page_bg.json new file mode 100644 index 0000000000..0863c31f61 --- /dev/null +++ b/quickstep/res/raw-sw600dp-land/all_set_page_bg.json @@ -0,0 +1 @@ +{"v":"5.9.0","fr":60,"ip":0,"op":180,"w":1280,"h":800,"nm":"3Second_MainWelcomeScreen_Tablet_Landscape_V02","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[288,540,0],"ix":2,"l":2},"a":{"a":0,"k":[50,50,0],"ix":1,"l":2},"s":{"a":0,"k":[25,25,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":600,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"colorAccentPrimaryVariant","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":180,"s":[56]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.07,"y":0.986},"o":{"x":0.167,"y":0.167},"t":0,"s":[231.832,-1174.545,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.773,"y":0.01},"t":95,"s":[231.832,-1979,0],"to":[0,0,0],"ti":[0,0,0]},{"t":180,"s":[231.832,-1174.545,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-3514.717,-358.642,0],"ix":1,"l":2},"s":{"a":0,"k":[110,110,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[75.615,-96.908],[89.338,-70.276],[111.99,-50.668],[111.764,-20.709],[122.709,7.18],[108.586,33.602],[105.316,63.383],[80.533,80.216],[63.797,105.066],[34.03,108.453],[7.663,122.679],[-20.269,111.845],[-50.226,112.189],[-69.924,89.614],[-96.61,75.997],[-103.56,46.854],[-120.861,22.395],[-113.472,-6.639],[-117.425,-36.337],[-97.389,-58.612],[-87.087,-86.745],[-58.996,-97.158],[-36.8,-117.281],[-7.086,-113.445],[21.918,-120.948],[46.446,-103.744]],"o":[[-75.615,96.909],[-89.338,70.276],[-111.99,50.668],[-111.764,20.709],[-122.709,-7.18],[-108.586,-33.602],[-105.316,-63.383],[-80.533,-80.216],[-63.797,-105.066],[-34.03,-108.453],[-7.663,-122.679],[20.269,-111.845],[50.226,-112.188],[69.924,-89.614],[96.61,-75.997],[103.56,-46.854],[120.861,-22.395],[113.472,6.64],[117.425,36.337],[97.389,58.612],[87.088,86.745],[58.995,97.158],[36.8,117.281],[7.087,113.445],[-21.918,120.948],[-46.446,103.744]],"v":[[733.209,572.105],[531.711,675.932],[383.354,847.313],[156.685,845.606],[-54.323,928.412],[-254.235,821.562],[-479.555,796.823],[-606.913,609.309],[-794.927,482.691],[-820.554,257.47],[-928.191,57.981],[-846.217,-153.353],[-848.817,-380.013],[-678.021,-529.044],[-574.99,-730.949],[-354.499,-783.537],[-169.439,-914.435],[50.234,-858.532],[274.928,-888.434],[443.46,-736.847],[656.313,-658.903],[735.094,-446.359],[887.344,-278.426],[858.327,-53.616],[915.095,165.835],[784.928,351.409]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.839215686275,0.439215686275,0.388235294118,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-3509.952,-363.731],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":720,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"colorAccentPrimary","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.248]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[-56]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.172]},"t":95,"s":[-38]},{"t":180,"s":[-56]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.032]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[138]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.022]},"t":95,"s":[-38]},{"t":180,"s":[138]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.034]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[1535]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.024]},"t":95,"s":[1338]},{"t":180,"s":[1535]}],"ix":4}},"a":{"a":0,"k":[164.438,1433.781,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3079.125,4685.989],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.305882352941,0.309803921569,0.321568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.438,1481.781],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/quickstep/res/raw-sw600dp/all_set_page_bg.json b/quickstep/res/raw-sw600dp/all_set_page_bg.json new file mode 100644 index 0000000000..14e8933da8 --- /dev/null +++ b/quickstep/res/raw-sw600dp/all_set_page_bg.json @@ -0,0 +1 @@ +{"v":"5.9.0","fr":60,"ip":0,"op":180,"w":800,"h":1280,"nm":"3Second_MainWelcomeScreen_Tablet_Portrait_V02","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":1,"nm":"Null 5","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[288,528,0],"ix":2,"l":2},"a":{"a":0,"k":[50,50,0],"ix":1,"l":2},"s":{"a":0,"k":[25,25,100],"ix":6,"l":2}},"ao":0,"sw":100,"sh":100,"sc":"#ffffff","ip":600,"op":600,"st":0,"bm":0,"hidden":0},{"ddd":0,"ind":2,"ty":4,"nm":".colorAccentPrimaryVariant","cl":"colorAccentPrimaryVariant","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":180,"s":[56]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.07,"y":0.986},"o":{"x":0.167,"y":0.167},"t":0,"s":[375.832,-1366.545,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.773,"y":0.01},"t":95,"s":[375.832,-2171,0],"to":[0,0,0],"ti":[0,0,0]},{"t":180,"s":[375.832,-1366.545,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-3514.717,-358.642,0],"ix":1,"l":2},"s":{"a":0,"k":[135,135,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[75.615,-96.908],[89.338,-70.276],[111.99,-50.668],[111.764,-20.709],[122.709,7.18],[108.586,33.602],[105.316,63.383],[80.533,80.216],[63.797,105.066],[34.03,108.453],[7.663,122.679],[-20.269,111.845],[-50.226,112.189],[-69.924,89.614],[-96.61,75.997],[-103.56,46.854],[-120.861,22.395],[-113.472,-6.639],[-117.425,-36.337],[-97.389,-58.612],[-87.087,-86.745],[-58.996,-97.158],[-36.8,-117.281],[-7.086,-113.445],[21.918,-120.948],[46.446,-103.744]],"o":[[-75.615,96.909],[-89.338,70.276],[-111.99,50.668],[-111.764,20.709],[-122.709,-7.18],[-108.586,-33.602],[-105.316,-63.383],[-80.533,-80.216],[-63.797,-105.066],[-34.03,-108.453],[-7.663,-122.679],[20.269,-111.845],[50.226,-112.188],[69.924,-89.614],[96.61,-75.997],[103.56,-46.854],[120.861,-22.395],[113.472,6.64],[117.425,36.337],[97.389,58.612],[87.088,86.745],[58.995,97.158],[36.8,117.281],[7.087,113.445],[-21.918,120.948],[-46.446,103.744]],"v":[[733.209,572.105],[531.711,675.932],[383.354,847.313],[156.685,845.606],[-54.323,928.412],[-254.235,821.562],[-479.555,796.823],[-606.913,609.309],[-794.927,482.691],[-820.554,257.47],[-928.191,57.981],[-846.217,-153.353],[-848.817,-380.013],[-678.021,-529.044],[-574.99,-730.949],[-354.499,-783.537],[-169.439,-914.435],[50.234,-858.532],[274.928,-888.434],[443.46,-736.847],[656.313,-658.903],[735.094,-446.359],[887.344,-278.426],[858.327,-53.616],[915.095,165.835],[784.928,351.409]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.839215686275,0.439215686275,0.388235294118,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-3509.952,-363.731],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":720,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":".colorAccentPrimary","cl":"colorAccentPrimary","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.248]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[-56]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.172]},"t":95,"s":[-38]},{"t":180,"s":[-56]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.032]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[138]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.022]},"t":95,"s":[-38]},{"t":180,"s":[138]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.034]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[1535]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.024]},"t":95,"s":[1338]},{"t":180,"s":[1535]}],"ix":4}},"a":{"a":0,"k":[164.438,1433.781,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3079.125,4685.989],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.305882352941,0.309803921569,0.321568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":10,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[164.438,1481.781],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":600,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/res/raw/all_set_page_bg.json b/quickstep/res/raw/all_set_page_bg.json similarity index 98% rename from res/raw/all_set_page_bg.json rename to quickstep/res/raw/all_set_page_bg.json index 9705837912..859d3567a2 100644 --- a/res/raw/all_set_page_bg.json +++ b/quickstep/res/raw/all_set_page_bg.json @@ -1 +1 @@ -{"v":"5.7.8","fr":24,"ip":0,"op":72,"w":2472,"h":5352,"nm":"3Second_MAIN_Welcome","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 60","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1508,1364,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":240,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"PinkFlower","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":72,"s":[56]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.07,"y":0.986},"o":{"x":0.167,"y":0.167},"t":0,"s":[1505.832,1379.455,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.773,"y":0.01},"t":38,"s":[1505.832,575,0],"to":[0,0,0],"ti":[0,0,0]},{"t":72,"s":[1505.832,1379.455,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-3514.717,-358.642,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[75.615,-96.908],[89.338,-70.276],[111.99,-50.668],[111.764,-20.709],[122.709,7.18],[108.586,33.602],[105.316,63.383],[80.533,80.216],[63.797,105.066],[34.03,108.453],[7.663,122.679],[-20.269,111.845],[-50.226,112.189],[-69.924,89.614],[-96.61,75.997],[-103.56,46.854],[-120.861,22.395],[-113.472,-6.639],[-117.425,-36.337],[-97.389,-58.612],[-87.087,-86.745],[-58.996,-97.158],[-36.8,-117.281],[-7.086,-113.445],[21.918,-120.948],[46.446,-103.744]],"o":[[-75.615,96.909],[-89.338,70.276],[-111.99,50.668],[-111.764,20.709],[-122.709,-7.18],[-108.586,-33.602],[-105.316,-63.383],[-80.533,-80.216],[-63.797,-105.066],[-34.03,-108.453],[-7.663,-122.679],[20.269,-111.845],[50.226,-112.188],[69.924,-89.614],[96.61,-75.997],[103.56,-46.854],[120.861,-22.395],[113.472,6.64],[117.425,36.337],[97.389,58.612],[87.088,86.745],[58.995,97.158],[36.8,117.281],[7.087,113.445],[-21.918,120.948],[-46.446,103.744]],"v":[[733.209,572.105],[531.711,675.932],[383.354,847.313],[156.685,845.606],[-54.323,928.412],[-254.235,821.562],[-479.555,796.823],[-606.913,609.309],[-794.927,482.691],[-820.554,257.47],[-928.191,57.981],[-846.217,-153.353],[-848.817,-380.013],[-678.021,-529.044],[-574.99,-730.949],[-354.499,-783.537],[-169.439,-914.435],[50.234,-858.532],[274.928,-888.434],[443.46,-736.847],[656.313,-658.903],[735.094,-446.359],[887.344,-278.426],[858.327,-53.616],[915.095,165.835],[784.928,351.409]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.839215686275,0.439215686275,0.388235294118,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.839215746113,0.439215716194,0.388235324037,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[-3509.952,-363.731],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":288,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Ellipse_Bottom","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.248]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[-56]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.172]},"t":38,"s":[-38]},{"t":72,"s":[-56]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.032]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[1720]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.022]},"t":38,"s":[1544]},{"t":72,"s":[1720]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.034]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[4069]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.024]},"t":38,"s":[3872]},{"t":72,"s":[4069]}],"ix":4}},"a":{"a":0,"k":[164.438,1433.781,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3079.125,4685.989],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.305882352941,0.309803921569,0.321568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.882353001015,0.894118006089,0.886274988511,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[164.438,1481.781],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":240,"st":0,"bm":0}],"markers":[]} +{"v":"5.7.8","fr":24,"ip":0,"op":72,"w":2472,"h":5352,"nm":"3Second_MAIN_Welcome","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 60","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[1508,1364,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":240,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"PinkFlower","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[0]},{"t":72,"s":[56]}],"ix":10},"p":{"a":1,"k":[{"i":{"x":0.07,"y":0.986},"o":{"x":0.167,"y":0.167},"t":0,"s":[1505.832,1379.455,0],"to":[0,0,0],"ti":[0,0,0]},{"i":{"x":0.833,"y":0.833},"o":{"x":0.773,"y":0.01},"t":38,"s":[1505.832,575,0],"to":[0,0,0],"ti":[0,0,0]},{"t":72,"s":[1505.832,1379.455,0]}],"ix":2,"l":2},"a":{"a":0,"k":[-3514.717,-358.642,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[75.615,-96.908],[89.338,-70.276],[111.99,-50.668],[111.764,-20.709],[122.709,7.18],[108.586,33.602],[105.316,63.383],[80.533,80.216],[63.797,105.066],[34.03,108.453],[7.663,122.679],[-20.269,111.845],[-50.226,112.189],[-69.924,89.614],[-96.61,75.997],[-103.56,46.854],[-120.861,22.395],[-113.472,-6.639],[-117.425,-36.337],[-97.389,-58.612],[-87.087,-86.745],[-58.996,-97.158],[-36.8,-117.281],[-7.086,-113.445],[21.918,-120.948],[46.446,-103.744]],"o":[[-75.615,96.909],[-89.338,70.276],[-111.99,50.668],[-111.764,20.709],[-122.709,-7.18],[-108.586,-33.602],[-105.316,-63.383],[-80.533,-80.216],[-63.797,-105.066],[-34.03,-108.453],[-7.663,-122.679],[20.269,-111.845],[50.226,-112.188],[69.924,-89.614],[96.61,-75.997],[103.56,-46.854],[120.861,-22.395],[113.472,6.64],[117.425,36.337],[97.389,58.612],[87.088,86.745],[58.995,97.158],[36.8,117.281],[7.087,113.445],[-21.918,120.948],[-46.446,103.744]],"v":[[733.209,572.105],[531.711,675.932],[383.354,847.313],[156.685,845.606],[-54.323,928.412],[-254.235,821.562],[-479.555,796.823],[-606.913,609.309],[-794.927,482.691],[-820.554,257.47],[-928.191,57.981],[-846.217,-153.353],[-848.817,-380.013],[-678.021,-529.044],[-574.99,-730.949],[-354.499,-783.537],[-169.439,-914.435],[50.234,-858.532],[274.928,-888.434],[443.46,-736.847],[656.313,-658.903],[735.094,-446.359],[887.344,-278.426],[858.327,-53.616],[915.095,165.835],[784.928,351.409]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.839215686275,0.439215686275,0.388235294118,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.839215746113,0.439215716194,0.388235324037,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[-3509.952,-363.731],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Polystar 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":288,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"Ellipse_Bottom","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.248]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[-56]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.172]},"t":38,"s":[-38]},{"t":72,"s":[-56]}],"ix":10},"p":{"s":true,"x":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.032]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[1720]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.022]},"t":38,"s":[1544]},{"t":72,"s":[1720]}],"ix":3},"y":{"a":1,"k":[{"i":{"x":[0.07],"y":[1.034]},"o":{"x":[0.167],"y":[0.167]},"t":0,"s":[4069]},{"i":{"x":[0.833],"y":[0.833]},"o":{"x":[0.719],"y":[0.024]},"t":38,"s":[3872]},{"t":72,"s":[4069]}],"ix":4}},"a":{"a":0,"k":[164.438,1433.781,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"d":1,"ty":"el","s":{"a":0,"k":[3079.125,4685.989],"ix":2},"p":{"a":0,"k":[0,0],"ix":3},"nm":"Ellipse Path 1","mn":"ADBE Vector Shape - Ellipse","hd":false},{"ty":"st","c":{"a":0,"k":[0.305882352941,0.309803921569,0.321568627451,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":4,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"fl","c":{"a":0,"k":[0.882353001015,0.894118006089,0.886274988511,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":true},{"ty":"tr","p":{"a":0,"k":[164.438,1481.781],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Ellipse 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":240,"st":0,"bm":0}],"markers":[]} \ No newline at end of file diff --git a/quickstep/res/values-sw600dp-land/dimens.xml b/quickstep/res/values-sw600dp-land/dimens.xml index 0cd9b2b700..5507fcfbd2 100644 --- a/quickstep/res/values-sw600dp-land/dimens.xml +++ b/quickstep/res/values-sw600dp-land/dimens.xml @@ -17,4 +17,9 @@ 12dp + + + 48dp + 24dp + diff --git a/quickstep/res/values-sw600dp/dimens.xml b/quickstep/res/values-sw600dp/dimens.xml index cfbbf8dbf3..c96ad11e8b 100644 --- a/quickstep/res/values-sw600dp/dimens.xml +++ b/quickstep/res/values-sw600dp/dimens.xml @@ -33,4 +33,11 @@ 36dp 64dp + + + 120dp + 24dp + 38sp + 15sp + diff --git a/quickstep/res/values-sw720dp-land/dimens.xml b/quickstep/res/values-sw720dp-land/dimens.xml index 02d11892dd..4bc8bf3c03 100644 --- a/quickstep/res/values-sw720dp-land/dimens.xml +++ b/quickstep/res/values-sw720dp-land/dimens.xml @@ -17,4 +17,7 @@ 20dp + + + 24dp diff --git a/quickstep/res/values-sw720dp/dimens.xml b/quickstep/res/values-sw720dp/dimens.xml index 284ce11582..a84b9394b1 100644 --- a/quickstep/res/values-sw720dp/dimens.xml +++ b/quickstep/res/values-sw720dp/dimens.xml @@ -33,4 +33,9 @@ 44dp 64dp + + + 0dp + 42sp + 16sp diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index fb78ef76f5..1e90031d9b 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -202,6 +202,10 @@ 40dp + 0dp + 36sp + 14sp + 24dp 32dp 24dp diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml index 7225220876..868d38bd81 100644 --- a/quickstep/res/values/styles.xml +++ b/quickstep/res/values/styles.xml @@ -51,6 +51,7 @@ parent="TextAppearance.GestureTutorial.Feedback.Title"> 0.03 44sp + @dimen/allset_page_allset_text_size + + + diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index e66d441912..6777080a9a 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -373,7 +373,8 @@ public class CellLayout extends ViewGroup { private void resetCellSizeInternal(DeviceProfile deviceProfile) { switch (mContainerType) { case FOLDER: - mBorderSpace = new Point(deviceProfile.folderCellLayoutBorderSpacePx); + mBorderSpace = new Point(deviceProfile.folderCellLayoutBorderSpacePx, + deviceProfile.folderCellLayoutBorderSpacePx); break; case HOTSEAT: mBorderSpace = new Point(deviceProfile.hotseatBorderSpace, diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index edd809c39b..1616ae94a2 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -25,12 +25,14 @@ import static com.android.launcher3.Utilities.pxFromSp; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.folder.ClippedFolderIconLayoutRule.ICON_OVERLAP_FACTOR; import static com.android.launcher3.icons.GraphicsUtils.getShapePath; +import static com.android.launcher3.testing.shared.ResourceUtils.INVALID_RESOURCE_HANDLE; import static com.android.launcher3.testing.shared.ResourceUtils.pxFromDp; import android.annotation.SuppressLint; import android.content.Context; import android.content.res.Configuration; import android.content.res.Resources; +import android.content.res.TypedArray; import android.graphics.Point; import android.graphics.PointF; import android.graphics.Rect; @@ -61,6 +63,7 @@ public class DeviceProfile { private static final int DEFAULT_DOT_SIZE = 100; private static final float ALL_APPS_TABLET_MAX_ROWS = 5.5f; + private static final float MIN_FOLDER_TEXT_SIZE_SP = 16f; public static final PointF DEFAULT_SCALE = new PointF(1.0f, 1.0f); public static final ViewScaleProvider DEFAULT_PROVIDER = itemInfo -> DEFAULT_SCALE; @@ -147,11 +150,12 @@ public class DeviceProfile { // Folder public float folderLabelTextScale; public int folderLabelTextSizePx; + public int folderFooterHeightPx; public int folderIconSizePx; public int folderIconOffsetYPx; // Folder content - public Point folderCellLayoutBorderSpacePx; + public int folderCellLayoutBorderSpacePx; public int folderContentPaddingLeftRight; public int folderContentPaddingTop; @@ -348,17 +352,34 @@ public class DeviceProfile { } folderLabelTextScale = res.getFloat(R.dimen.folder_label_text_scale); - folderContentPaddingLeftRight = - res.getDimensionPixelSize(R.dimen.folder_content_padding_left_right); - folderContentPaddingTop = res.getDimensionPixelSize(R.dimen.folder_content_padding_top); + + if (inv.folderStyle != INVALID_RESOURCE_HANDLE) { + TypedArray folderStyle = context.obtainStyledAttributes(inv.folderStyle, + R.styleable.FolderDisplayStyle); + // These are re-set in #updateFolderCellSize if the grid is not scalable + folderCellHeightPx = folderStyle.getDimensionPixelSize( + R.styleable.FolderDisplayStyle_folderCellHeight, 0); + folderCellWidthPx = folderStyle.getDimensionPixelSize( + R.styleable.FolderDisplayStyle_folderCellWidth, 0); + + folderContentPaddingTop = folderStyle.getDimensionPixelSize( + R.styleable.FolderDisplayStyle_folderTopPadding, 0); + folderCellLayoutBorderSpacePx = folderStyle.getDimensionPixelSize( + R.styleable.FolderDisplayStyle_folderBorderSpace, 0); + folderFooterHeightPx = folderStyle.getDimensionPixelSize( + R.styleable.FolderDisplayStyle_folderFooterHeight, 0); + folderStyle.recycle(); + } else { + folderCellLayoutBorderSpacePx = 0; + folderFooterHeightPx = 0; + folderContentPaddingTop = res.getDimensionPixelSize(R.dimen.folder_top_padding_default); + } cellLayoutBorderSpacePx = getCellLayoutBorderSpace(inv); + cellLayoutBorderSpaceOriginalPx = new Point(cellLayoutBorderSpacePx); allAppsBorderSpacePx = new Point( pxFromDp(inv.allAppsBorderSpaces[mTypeIndex].x, mMetrics), pxFromDp(inv.allAppsBorderSpaces[mTypeIndex].y, mMetrics)); - cellLayoutBorderSpaceOriginalPx = new Point(cellLayoutBorderSpacePx); - folderCellLayoutBorderSpacePx = new Point(pxFromDp(inv.folderBorderSpaces.x, mMetrics), - pxFromDp(inv.folderBorderSpaces.y, mMetrics)); workspacePageIndicatorHeight = res.getDimensionPixelSize( R.dimen.workspace_page_indicator_height); @@ -927,22 +948,20 @@ public class DeviceProfile { private void updateAvailableFolderCellDimensions(Resources res) { updateFolderCellSize(1f, res); - final int folderBottomPanelSize = res.getDimensionPixelSize(R.dimen.folder_label_height); - // Don't let the folder get too close to the edges of the screen. int folderMargin = edgeMarginPx * 2; Point totalWorkspacePadding = getTotalWorkspacePadding(); // Check if the icons fit within the available height. float contentUsedHeight = folderCellHeightPx * inv.numFolderRows - + ((inv.numFolderRows - 1) * folderCellLayoutBorderSpacePx.y); - int contentMaxHeight = availableHeightPx - totalWorkspacePadding.y - folderBottomPanelSize + + ((inv.numFolderRows - 1) * folderCellLayoutBorderSpacePx); + int contentMaxHeight = availableHeightPx - totalWorkspacePadding.y - folderFooterHeightPx - folderMargin - folderContentPaddingTop; float scaleY = contentMaxHeight / contentUsedHeight; // Check if the icons fit within the available width. float contentUsedWidth = folderCellWidthPx * inv.numFolderColumns - + ((inv.numFolderColumns - 1) * folderCellLayoutBorderSpacePx.x); + + ((inv.numFolderColumns - 1) * folderCellLayoutBorderSpacePx); int contentMaxWidth = availableWidthPx - totalWorkspacePadding.x - folderMargin - folderContentPaddingLeftRight * 2; float scaleX = contentMaxWidth / contentUsedWidth; @@ -960,19 +979,18 @@ public class DeviceProfile { folderChildIconSizePx = Math.max(1, pxFromDp(invIconSizeDp, mMetrics, scale)); folderChildTextSizePx = pxFromSp(inv.iconTextSize[INDEX_DEFAULT], mMetrics, scale); - folderLabelTextSizePx = (int) (folderChildTextSizePx * folderLabelTextScale); + folderLabelTextSizePx = Math.max(pxFromSp(MIN_FOLDER_TEXT_SIZE_SP, mMetrics), + (int) (folderChildTextSizePx * folderLabelTextScale)); int textHeight = Utilities.calculateTextHeight(folderChildTextSizePx); if (isScalableGrid) { - folderCellWidthPx = pxFromDp(inv.folderCellSize.x, mMetrics, scale); - folderCellHeightPx = pxFromDp(inv.folderCellSize.y, mMetrics, scale); + if (inv.folderStyle == INVALID_RESOURCE_HANDLE) { + folderCellWidthPx = pxFromDp(getCellSize().x, mMetrics, scale); + folderCellHeightPx = pxFromDp(getCellSize().y, mMetrics, scale); + } - folderCellLayoutBorderSpacePx = new Point( - pxFromDp(inv.folderBorderSpaces.x, mMetrics, scale), - pxFromDp(inv.folderBorderSpaces.y, mMetrics, scale)); - folderContentPaddingLeftRight = folderCellLayoutBorderSpacePx.x; - folderContentPaddingTop = pxFromDp(inv.folderTopPadding, mMetrics, scale); + folderContentPaddingLeftRight = folderCellLayoutBorderSpacePx; } else { int cellPaddingX = (int) (res.getDimensionPixelSize(R.dimen.folder_cell_x_padding) * scale); @@ -981,6 +999,10 @@ public class DeviceProfile { folderCellWidthPx = folderChildIconSizePx + 2 * cellPaddingX; folderCellHeightPx = folderChildIconSizePx + 2 * cellPaddingY + textHeight; + folderContentPaddingLeftRight = + res.getDimensionPixelSize(R.dimen.folder_content_padding_left_right); + folderFooterHeightPx = + res.getDimensionPixelSize(R.dimen.folder_footer_height_default); } folderChildDrawablePaddingPx = Math.max(0, @@ -1464,13 +1486,12 @@ public class DeviceProfile { writer.println(prefix + pxToDpStr("folderChildTextSizePx", folderChildTextSizePx)); writer.println(prefix + pxToDpStr("folderChildDrawablePaddingPx", folderChildDrawablePaddingPx)); - writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpacePx Horizontal", - folderCellLayoutBorderSpacePx.x)); - writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpacePx Vertical", - folderCellLayoutBorderSpacePx.y)); + writer.println(prefix + pxToDpStr("folderCellLayoutBorderSpacePx", + folderCellLayoutBorderSpacePx)); writer.println(prefix + pxToDpStr("folderContentPaddingLeftRight", folderContentPaddingLeftRight)); writer.println(prefix + pxToDpStr("folderTopPadding", folderContentPaddingTop)); + writer.println(prefix + pxToDpStr("folderFooterHeight", folderFooterHeightPx)); writer.println(prefix + pxToDpStr("bottomSheetTopPadding", bottomSheetTopPadding)); writer.println(prefix + "\tbottomSheetOpenDuration: " + bottomSheetOpenDuration); diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 635f4007cb..0c6f340cb1 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -18,6 +18,7 @@ package com.android.launcher3; import static com.android.launcher3.Utilities.dpiFromPx; import static com.android.launcher3.config.FeatureFlags.ENABLE_TWO_PANEL_HOME; +import static com.android.launcher3.testing.shared.ResourceUtils.INVALID_RESOURCE_HANDLE; import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY; import static com.android.launcher3.util.DisplayController.CHANGE_NAVIGATION_MODE; import static com.android.launcher3.util.DisplayController.CHANGE_SUPPORTED_BOUNDS; @@ -43,8 +44,10 @@ import android.util.TypedValue; import android.util.Xml; import android.view.Display; +import androidx.annotation.DimenRes; import androidx.annotation.IntDef; import androidx.annotation.Nullable; +import androidx.annotation.StyleRes; import androidx.annotation.VisibleForTesting; import androidx.core.content.res.ResourcesCompat; @@ -129,11 +132,9 @@ public class InvariantDeviceProfile { public PointF[] minCellSize; public PointF[] borderSpaces; - public int inlineNavButtonsEndSpacing; + public @DimenRes int inlineNavButtonsEndSpacing; - public PointF folderBorderSpaces; - public PointF folderCellSize; - public float folderTopPadding; + public @StyleRes int folderStyle; public float[] horizontalMargin; @@ -333,8 +334,11 @@ public class InvariantDeviceProfile { dbFile = closestProfile.dbFile; defaultLayoutId = closestProfile.defaultLayoutId; demoModeLayoutId = closestProfile.demoModeLayoutId; + numFolderRows = closestProfile.numFolderRows; numFolderColumns = closestProfile.numFolderColumns; + folderStyle = closestProfile.folderStyle; + isScalable = closestProfile.isScalable; devicePaddingId = closestProfile.devicePaddingId; this.deviceType = deviceType; @@ -357,10 +361,6 @@ public class InvariantDeviceProfile { borderSpaces = displayOption.borderSpaces; - folderBorderSpaces = displayOption.folderBorderSpaces; - folderCellSize = displayOption.folderCellSize; - folderTopPadding = displayOption.folderTopPadding; - horizontalMargin = displayOption.horizontalMargin; numShownHotseatIcons = closestProfile.numHotseatIcons; @@ -749,6 +749,7 @@ public class InvariantDeviceProfile { private final int numFolderRows; private final int numFolderColumns; + private final @StyleRes int folderStyle; private final int numAllAppsColumns; private final int numDatabaseAllAppsColumns; @@ -759,7 +760,7 @@ public class InvariantDeviceProfile { private final boolean[] inlineQsb = new boolean[COUNT_SIZES]; - private int inlineNavButtonsEndSpacing; + private @DimenRes int inlineNavButtonsEndSpacing; private final String dbFile; private final int defaultLayoutId; @@ -811,11 +812,15 @@ public class InvariantDeviceProfile { inlineNavButtonsEndSpacing = a.getResourceId(R.styleable.GridDisplayOption_inlineNavButtonsEndSpacing, R.dimen.taskbar_button_margin_default); + numFolderRows = a.getInt( R.styleable.GridDisplayOption_numFolderRows, numRows); numFolderColumns = a.getInt( R.styleable.GridDisplayOption_numFolderColumns, numColumns); + folderStyle = a.getResourceId(R.styleable.GridDisplayOption_folderStyle, + INVALID_RESOURCE_HANDLE); + isScalable = a.getBoolean( R.styleable.GridDisplayOption_isScalable, false); devicePaddingId = a.getResourceId( @@ -860,10 +865,6 @@ public class InvariantDeviceProfile { private final PointF[] minCellSize = new PointF[COUNT_SIZES]; - private final PointF folderCellSize; - private final PointF folderBorderSpaces; - private float folderTopPadding; - private final PointF[] borderSpaces = new PointF[COUNT_SIZES]; private final float[] horizontalMargin = new float[COUNT_SIZES]; private final float[] hotseatBarBottomSpace = new float[COUNT_SIZES]; @@ -946,21 +947,6 @@ public class InvariantDeviceProfile { borderSpaceTwoPanelLandscape); borderSpaces[INDEX_TWO_PANEL_LANDSCAPE] = new PointF(x, y); - x = a.getFloat(R.styleable.ProfileDisplayOption_folderCellWidth, - minCellSize[INDEX_DEFAULT].x); - y = a.getFloat(R.styleable.ProfileDisplayOption_folderCellHeight, - minCellSize[INDEX_DEFAULT].y); - folderCellSize = new PointF(x, y); - - float folderBorderSpace = a.getFloat(R.styleable.ProfileDisplayOption_folderBorderSpace, - borderSpace); - - x = y = folderBorderSpace; - folderBorderSpaces = new PointF(x, y); - - folderTopPadding = a.getFloat(R.styleable.ProfileDisplayOption_folderTopPadding, - folderBorderSpaces.y); - x = a.getFloat(R.styleable.ProfileDisplayOption_allAppsCellWidth, minCellSize[INDEX_DEFAULT].x); y = a.getFloat(R.styleable.ProfileDisplayOption_allAppsCellHeight, @@ -1133,9 +1119,6 @@ public class InvariantDeviceProfile { allAppsIconTextSizes[i] = 0; allAppsBorderSpaces[i] = new PointF(); } - folderBorderSpaces = new PointF(); - folderCellSize = new PointF(); - folderTopPadding = 0f; } private DisplayOption multiply(float w) { @@ -1156,11 +1139,6 @@ public class InvariantDeviceProfile { allAppsBorderSpaces[i].x *= w; allAppsBorderSpaces[i].y *= w; } - folderBorderSpaces.x *= w; - folderBorderSpaces.y *= w; - folderCellSize.x *= w; - folderCellSize.y *= w; - folderTopPadding *= w; return this; } @@ -1183,11 +1161,6 @@ public class InvariantDeviceProfile { allAppsBorderSpaces[i].x += p.allAppsBorderSpaces[i].x; allAppsBorderSpaces[i].y += p.allAppsBorderSpaces[i].y; } - folderBorderSpaces.x += p.folderBorderSpaces.x; - folderBorderSpaces.y += p.folderBorderSpaces.y; - folderCellSize.x += p.folderCellSize.x; - folderCellSize.y += p.folderCellSize.y; - folderTopPadding += p.folderTopPadding; return this; } diff --git a/src/com/android/launcher3/ShortcutAndWidgetContainer.java b/src/com/android/launcher3/ShortcutAndWidgetContainer.java index 8b342ea3ee..7a74d7ed1b 100644 --- a/src/com/android/launcher3/ShortcutAndWidgetContainer.java +++ b/src/com/android/launcher3/ShortcutAndWidgetContainer.java @@ -152,7 +152,7 @@ public class ShortcutAndWidgetContainer extends ViewGroup implements FolderIcon. // No need to add padding when cell layout border spacing is present. boolean noPaddingX = (dp.cellLayoutBorderSpacePx.x > 0 && mContainerType == WORKSPACE) - || (dp.folderCellLayoutBorderSpacePx.x > 0 && mContainerType == FOLDER) + || (dp.folderCellLayoutBorderSpacePx > 0 && mContainerType == FOLDER) || (dp.hotseatBorderSpace > 0 && mContainerType == HOTSEAT); int cellPaddingX = noPaddingX ? 0 diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index 7e1491287f..99822da4a4 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -292,7 +292,7 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo mFolderName.forceDisableSuggestions(true); mFooter = findViewById(R.id.folder_footer); - mFooterHeight = getResources().getDimensionPixelSize(R.dimen.folder_label_height); + mFooterHeight = dp.folderFooterHeightPx; if (Utilities.ATLEAST_R) { mKeyboardInsetAnimationCallback = new KeyboardInsetAnimationCallback(this); @@ -1167,14 +1167,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo mContent.setFixedSize(contentWidth, contentHeight); mContent.measure(contentAreaWidthSpec, contentAreaHeightSpec); - if (mContent.getChildCount() > 0) { - int cellIconGap = (mContent.getPageAt(0).getCellWidth() - - mActivityContext.getDeviceProfile().iconSizePx) / 2; - mFooter.setPadding(mContent.getPaddingLeft() + cellIconGap, - mFooter.getPaddingTop(), - mContent.getPaddingRight() + cellIconGap, - mFooter.getPaddingBottom()); - } mFooter.measure(contentAreaWidthSpec, MeasureSpec.makeMeasureSpec(mFooterHeight, MeasureSpec.EXACTLY)); diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java index d5ef9df111..4829c4275e 100644 --- a/src/com/android/launcher3/folder/FolderAnimationManager.java +++ b/src/com/android/launcher3/folder/FolderAnimationManager.java @@ -234,9 +234,9 @@ public class FolderAnimationManager { mFolder, startRect, endRect, finalRadius, !mIsOpening)); // Create reveal animator for the folder content (capture the top 4 icons 2x2) - int width = mDeviceProfile.folderCellLayoutBorderSpacePx.x + int width = mDeviceProfile.folderCellLayoutBorderSpacePx + mDeviceProfile.folderCellWidthPx * 2; - int height = mDeviceProfile.folderCellLayoutBorderSpacePx.y + int height = mDeviceProfile.folderCellLayoutBorderSpacePx + mDeviceProfile.folderCellHeightPx * 2; int page = mIsOpening ? mContent.getCurrentPage() : mContent.getDestinationPage(); int left = mContent.getPaddingLeft() + page * lp.width; diff --git a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt index 2c1cbdf0ce..fe30fdc81d 100644 --- a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt +++ b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt @@ -16,11 +16,12 @@ package com.android.launcher3 import android.content.Context +import android.graphics.Point import android.graphics.PointF import android.graphics.Rect import android.util.SparseArray import androidx.test.core.app.ApplicationProvider -import com.android.launcher3.DeviceProfile.DEFAULT_PROVIDER; +import com.android.launcher3.DeviceProfile.DEFAULT_PROVIDER import com.android.launcher3.util.DisplayController.Info import com.android.launcher3.util.WindowBounds import org.junit.Before @@ -116,10 +117,7 @@ abstract class DeviceProfileBaseTest { numFolderRows = 3 numFolderColumns = 3 - folderBorderSpaces = PointF(16f, 16f) - folderTopPadding = 24f - folderCellSize = PointF(80f, 94f) - + folderStyle = R.style.FolderDefaultStyle inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_4_5 @@ -207,9 +205,7 @@ abstract class DeviceProfileBaseTest { numFolderRows = 3 numFolderColumns = 3 - folderBorderSpaces = PointF(16f, 16f) - folderTopPadding = 24f - folderCellSize = PointF(120f, 104f) + folderStyle = R.style.FolderDefaultStyle inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_6_5 @@ -241,7 +237,7 @@ abstract class DeviceProfileBaseTest { numAllAppsColumns = 6 isScalable = true - devicePaddingId = 2132148242 // "@xml/paddings_6x5" + devicePaddingId = R.xml.paddings_6x5 inlineQsb = booleanArrayOf( false, @@ -305,9 +301,7 @@ abstract class DeviceProfileBaseTest { numFolderRows = 3 numFolderColumns = 3 - folderBorderSpaces = PointF(16f, 16f) - folderTopPadding = 24f - folderCellSize = PointF(80f, 94f) + folderStyle = R.style.FolderDefaultStyle inlineNavButtonsEndSpacing = R.dimen.taskbar_button_margin_4_4 From b0523697c61c0813b86230da9b41a59386b9e646 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Fri, 4 Nov 2022 14:36:36 -0700 Subject: [PATCH 187/429] Stash taskbar if user touch down above the gesture height. Bug: 252905206 Test: open taskbar, tap in gesture area, confirm no stash open taskbar, tap on taskbar item, confirm no stash open taskbar, tap to the side above gesture area, confirm stash Change-Id: Ide030840440b5f0541d0ccfb055b8a8a7e851657 --- .../taskbar/LauncherTaskbarUIController.java | 10 ----- .../launcher3/taskbar/TaskbarControllers.java | 1 + .../launcher3/taskbar/TaskbarDragLayer.java | 12 +++++- .../taskbar/TaskbarDragLayerController.java | 42 +++++++++++++++++-- 4 files changed, 50 insertions(+), 15 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index 317f6a4884..89f0f987f5 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -26,7 +26,6 @@ import android.annotation.ColorInt; import android.os.RemoteException; import android.util.Log; import android.util.SparseArray; -import android.view.MotionEvent; import android.view.TaskTransitionSpec; import android.view.WindowManagerGlobal; @@ -196,15 +195,6 @@ public class LauncherTaskbarUIController extends TaskbarUIController { return mTaskbarLauncherStateController.createAnimToLauncher(toState, callbacks, duration); } - /** - * @param ev MotionEvent in screen coordinates. - * @return Whether any Taskbar item could handle the given MotionEvent if given the chance. - */ - public boolean isEventOverAnyTaskbarItem(MotionEvent ev) { - return mControllers.taskbarViewController.isEventOverAnyItem(ev) - || mControllers.navbarButtonsViewController.isEventOverAnyItem(ev); - } - public boolean isDraggingItem() { return mControllers.taskbarDragController.isDragging(); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java index 9c2d21ef8c..772cf18b63 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java @@ -164,6 +164,7 @@ public class TaskbarControllers { public void onConfigurationChanged(@Config int configChanges) { navbarButtonsViewController.onConfigurationChanged(configChanges); + taskbarDragLayerController.onConfigurationChanged(); } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java index 7c9a13c5dc..ffb3622ac0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java @@ -115,10 +115,18 @@ public class TaskbarDragLayer extends BaseDragLayer { return true; } + @Override + public boolean onInterceptTouchEvent(MotionEvent ev) { + if (mControllerCallbacks != null) { + mControllerCallbacks.tryStashBasedOnMotionEvent(ev); + } + return super.onInterceptTouchEvent(ev); + } + @Override public boolean onTouchEvent(MotionEvent ev) { - if (mControllerCallbacks != null && ev.getAction() == MotionEvent.ACTION_OUTSIDE) { - mControllerCallbacks.onActionOutsideEvent(); + if (mControllerCallbacks != null) { + mControllerCallbacks.tryStashBasedOnMotionEvent(ev); } return super.onTouchEvent(ev); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java index 13ecf81a7d..fe8a04ce81 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java @@ -18,10 +18,12 @@ package com.android.launcher3.taskbar; import android.content.res.Resources; import android.graphics.Point; import android.graphics.Rect; +import android.view.MotionEvent; import android.view.ViewTreeObserver; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; +import com.android.launcher3.testing.shared.ResourceUtils; import com.android.launcher3.util.DimensionUtils; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.TouchController; @@ -37,6 +39,7 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa private final TaskbarActivityContext mActivity; private final TaskbarDragLayer mTaskbarDragLayer; private final int mFolderMargin; + private float mGestureHeightYThreshold; // Alpha properties for taskbar background. private final AnimatedFloat mBgTaskbar = new AnimatedFloat(this::updateBackgroundAlpha); @@ -63,6 +66,7 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa mTaskbarDragLayer = taskbarDragLayer; final Resources resources = mTaskbarDragLayer.getResources(); mFolderMargin = resources.getDimensionPixelSize(R.dimen.taskbar_folder_margin); + updateGestureHeight(); } public void init(TaskbarControllers controllers) { @@ -122,6 +126,19 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa return mBgOffset; } + private void updateGestureHeight() { + int gestureHeight = ResourceUtils.getNavbarSize(ResourceUtils.NAVBAR_BOTTOM_GESTURE_SIZE, + mActivity.getResources()); + mGestureHeightYThreshold = mActivity.getDeviceProfile().heightPx - gestureHeight; + } + + /** + * Make updates when configuration changes. + */ + public void onConfigurationChanged() { + updateGestureHeight(); + } + private void updateBackgroundAlpha() { final float bgNavbar = mBgNavbar.value; final float bgTaskbar = mBgTaskbar.value * mKeyguardBgTaskbar.value @@ -158,6 +175,8 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa */ public class TaskbarDragLayerCallbacks { + private final int[] mTempOutLocation = new int[2]; + /** * Called to update the touchable insets. * @see ViewTreeObserver.InternalInsetsInfo#setTouchableInsets(int) @@ -167,9 +186,9 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa } /** - * Called whenever TaskbarDragLayer receives an ACTION_OUTSIDE event. + * Listens to TaskbarDragLayer touch events and responds accordingly. */ - public void onActionOutsideEvent() { + public void tryStashBasedOnMotionEvent(MotionEvent ev) { if (!DisplayController.isTransientTaskbar(mActivity)) { return; } @@ -177,7 +196,24 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa return; } - mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true); + boolean stashTaskbar = false; + + MotionEvent screenCoordinates = MotionEvent.obtain(ev); + if (ev.getAction() == MotionEvent.ACTION_OUTSIDE) { + stashTaskbar = true; + } else if (ev.getAction() == MotionEvent.ACTION_DOWN) { + mTaskbarDragLayer.getLocationOnScreen(mTempOutLocation); + screenCoordinates.offsetLocation(mTempOutLocation[0], mTempOutLocation[1]); + + if (!mControllers.taskbarViewController.isEventOverAnyItem(screenCoordinates) + && screenCoordinates.getY() < mGestureHeightYThreshold) { + stashTaskbar = true; + } + } + + if (stashTaskbar) { + mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true); + } } /** From d5a6b5f688f45f3f98cb22170f574495214d3f4f Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Fri, 4 Nov 2022 15:58:47 -0700 Subject: [PATCH 188/429] Add TaskbarModeSwitchRule to test both transient/persistent taskbar. - Lays the foundation for transient taskbar tests. - Does not add flags that would add ACTION_OUTSIDE in tests. We can address testing this functionality in a separate CL Bug: 257549303 Test: TaplTestsTaskbar Change-Id: I44acc5e589b959e6d4bc93fdc369e503c54e7d87 --- quickstep/Android.bp | 1 + .../taskbar/TaskbarActivityContext.java | 19 +- .../taskbar/TaskbarStashController.java | 20 ++- .../QuickstepTestInformationHandler.java | 19 ++ .../quickstep/AbstractQuickStepTest.java | 1 + .../quickstep/NavigationModeSwitchRule.java | 2 +- .../android/quickstep/TaplTestsTaskbar.java | 17 ++ .../quickstep/TaskbarModeSwitchRule.java | 162 ++++++++++++++++++ .../testing/shared/TestProtocol.java | 2 + .../launcher3/tapl/LaunchedAppState.java | 4 + .../tapl/LauncherInstrumentation.java | 7 + 11 files changed, 247 insertions(+), 7 deletions(-) create mode 100644 quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java diff --git a/quickstep/Android.bp b/quickstep/Android.bp index 7292c4495b..f5a8253563 100644 --- a/quickstep/Android.bp +++ b/quickstep/Android.bp @@ -38,6 +38,7 @@ filegroup { name: "launcher3-quickstep-oop-tests-src", path: "tests", srcs: [ + "tests/src/com/android/quickstep/TaskbarModeSwitchRule.java", "tests/src/com/android/quickstep/NavigationModeSwitchRule.java", "tests/src/com/android/quickstep/AbstractQuickStepTest.java", "tests/src/com/android/quickstep/TaplTestsQuickstep.java", diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index fad9ff490c..d0256c5caf 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -23,6 +23,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE; +import static com.android.launcher3.Utilities.IS_RUNNING_IN_TEST_HARNESS; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN; import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING; import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_FULLSCREEN; @@ -304,7 +305,8 @@ public class TaskbarActivityContext extends BaseTaskbarContext { int windowFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_SLIPPERY | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH; - if (DisplayController.isTransientTaskbar(this)) { + if (DisplayController.isTransientTaskbar(this) + && !IS_RUNNING_IN_TEST_HARNESS) { windowFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; } @@ -857,13 +859,26 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mControllers.taskbarStashController.enableManualStashingDuringTests(enableManualStashing); } + /** + * Enables the auto timeout for taskbar stashing. This method should only be used for taskbar + * testing. + */ + @VisibleForTesting + public void enableBlockingTimeoutDuringTests(boolean enableBlockingTimeout) { + mControllers.taskbarStashController.enableBlockingTimeoutDuringTests(enableBlockingTimeout); + } + /** * Unstashes the Taskbar if it is stashed. This method should only be used to unstash the * taskbar at the end of a test. */ @VisibleForTesting public void unstashTaskbarIfStashed() { - mControllers.taskbarStashController.onLongPressToUnstashTaskbar(); + if (DisplayController.isTransientTaskbar(this)) { + mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(false); + } else { + mControllers.taskbarStashController.onLongPressToUnstashTaskbar(); + } } protected boolean isUserSetupComplete() { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 72ae1d1c31..b53e9c56cd 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -37,6 +37,7 @@ import android.view.View; import android.view.ViewConfiguration; import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor; import com.android.launcher3.Alarm; @@ -169,6 +170,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba private boolean mEnableManualStashingDuringTests = false; private final Alarm mTimeoutAlarm = new Alarm(); + private boolean mEnableBlockingTimeoutDuringTests = false; // Evaluate whether the handle should be stashed private final StatePropertyHolder mStatePropertyHolder = new StatePropertyHolder( @@ -267,10 +269,20 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba * Enables support for manual stashing. This should only be used to add this functionality * to Launcher specific tests. */ + @VisibleForTesting public void enableManualStashingDuringTests(boolean enableManualStashing) { mEnableManualStashingDuringTests = enableManualStashing; } + /** + * Enables the auto timeout for taskbar stashing. This method should only be used for taskbar + * testing. + */ + @VisibleForTesting + public void enableBlockingTimeoutDuringTests(boolean enableBlockingTimeout) { + mEnableBlockingTimeoutDuringTests = enableBlockingTimeout; + } + /** * Sets the flag indicating setup UI is visible */ @@ -846,12 +858,12 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba * Attempts to start timer to auto hide the taskbar based on time. */ public void tryStartTaskbarTimeout() { - if (!DisplayController.isTransientTaskbar(mActivity)) { - return; - } - if (mIsStashed) { + if (!DisplayController.isTransientTaskbar(mActivity) + || mIsStashed + || mEnableBlockingTimeoutDuringTests) { return; } + cancelTimeoutIfExists(); mTimeoutAlarm.setOnAlarmListener(this::onTaskbarTimeout); diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java index 9621ce6eba..177ecf54a5 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -120,6 +120,18 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { .getCurrentActivityContext() .getTaskbarAllAppsTopPadding()); } + + case TestProtocol.REQUEST_ENABLE_BLOCK_TIMEOUT: + runOnTISBinder(tisBinder -> { + enableBlockingTimeout(tisBinder, true); + }); + return response; + + case TestProtocol.REQUEST_DISABLE_BLOCK_TIMEOUT: + runOnTISBinder(tisBinder -> { + enableBlockingTimeout(tisBinder, false); + }); + return response; } return super.call(method, arg, extras); @@ -149,6 +161,13 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { enable); } + private void enableBlockingTimeout( + TouchInteractionService.TISBinder tisBinder, boolean enable) { + // Allow null-pointer to catch illegal states. + tisBinder.getTaskbarManager().getCurrentActivityContext().enableBlockingTimeoutDuringTests( + enable); + } + /** * Runs the given command on the UI thread, after ensuring we are connected to * TouchInteractionService. diff --git a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java index e2774c003d..2c5825fd0b 100644 --- a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java +++ b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java @@ -39,6 +39,7 @@ public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest { protected TestRule getRulesInsideActivityMonitor() { return RuleChain. outerRule(new NavigationModeSwitchRule(mLauncher)). + around(new TaskbarModeSwitchRule(mLauncher)). around(super.getRulesInsideActivityMonitor()); } diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java index e5e2cf3337..eded1c961f 100644 --- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java +++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java @@ -51,7 +51,7 @@ import java.util.concurrent.TimeUnit; /** * Test rule that allows executing a test with Quickstep on and then Quickstep off. - * The test should be annotated with @QuickstepOnOff. + * The test should be annotated with @NavigationModeSwitch. */ public class NavigationModeSwitchRule implements TestRule { diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java index 9337cb55bc..0b8bc10fec 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java @@ -17,6 +17,8 @@ package com.android.quickstep; import static androidx.test.InstrumentationRegistry.getInstrumentation; +import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT; + import static junit.framework.TestCase.assertEquals; import android.content.Intent; @@ -27,6 +29,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.launcher3.tapl.Taskbar; import com.android.launcher3.ui.TaplTestsLauncher3; import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord; +import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch; import org.junit.After; import org.junit.Assume; @@ -53,21 +56,25 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { TaplTestsLauncher3.initialize(this); startAppFast(CALCULATOR_APP_PACKAGE); + mLauncher.enableBlockTimeout(true); mLauncher.showTaskbarIfHidden(); } @After public void tearDown() { mLauncher.useDefaultWorkspaceLayoutOnReload(); + mLauncher.enableBlockTimeout(false); } @Test + @TaskbarModeSwitch(mode = PERSISTENT) public void testHideShowTaskbar() { getTaskbar().hide(); mLauncher.getLaunchedAppState().showTaskbar(); } @Test + @TaskbarModeSwitch(mode = PERSISTENT) public void testHideTaskbarPersistsOnRecreate() { getTaskbar().hide(); mLauncher.recreateTaskbar(); @@ -75,16 +82,19 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { } @Test + @TaskbarModeSwitch public void testLaunchApp() throws Exception { getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE); } @Test + @TaskbarModeSwitch public void testOpenMenu() throws Exception { getTaskbar().getAppIcon(TEST_APP_NAME).openMenu(); } @Test + @TaskbarModeSwitch public void testLaunchShortcut() throws Exception { getTaskbar().getAppIcon(TEST_APP_NAME) .openDeepShortcutMenu() @@ -95,6 +105,7 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { @Test @ScreenRecord // b/231615831 @PortraitLandscape + @TaskbarModeSwitch public void testLaunchAppInSplitscreen() throws Exception { getTaskbar().getAppIcon(TEST_APP_NAME).dragToSplitscreen( TEST_APP_PACKAGE, CALCULATOR_APP_PACKAGE); @@ -103,6 +114,7 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { @Test @ScreenRecord // b/231615831 @PortraitLandscape + @TaskbarModeSwitch public void testLaunchShortcutInSplitscreen() throws Exception { getTaskbar().getAppIcon(TEST_APP_NAME) .openDeepShortcutMenu() @@ -111,16 +123,19 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { } @Test + @TaskbarModeSwitch public void testLaunchApp_FromTaskbarAllApps() throws Exception { getTaskbar().openAllApps().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE); } @Test + @TaskbarModeSwitch public void testOpenMenu_FromTaskbarAllApps() throws Exception { getTaskbar().openAllApps().getAppIcon(TEST_APP_NAME).openMenu(); } @Test + @TaskbarModeSwitch public void testLaunchShortcut_FromTaskbarAllApps() throws Exception { getTaskbar().openAllApps() .getAppIcon(TEST_APP_NAME) @@ -132,6 +147,7 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { @Test @ScreenRecord // b/231615831 @PortraitLandscape + @TaskbarModeSwitch public void testLaunchAppInSplitscreen_FromTaskbarAllApps() throws Exception { getTaskbar().openAllApps() .getAppIcon(TEST_APP_NAME) @@ -141,6 +157,7 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { @Test @ScreenRecord // b/231615831 @PortraitLandscape + @TaskbarModeSwitch public void testLaunchShortcutInSplitscreen_FromTaskbarAllApps() throws Exception { getTaskbar().openAllApps() .getAppIcon(TEST_APP_NAME) diff --git a/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java new file mode 100644 index 0000000000..8cc812bbb7 --- /dev/null +++ b/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java @@ -0,0 +1,162 @@ +/* + * Copyright (C) 2022 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 static androidx.test.InstrumentationRegistry.getInstrumentation; + +import static com.android.quickstep.TaskbarModeSwitchRule.Mode.ALL; +import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT; +import static com.android.quickstep.TaskbarModeSwitchRule.Mode.TRANSIENT; + +import android.content.Context; +import android.util.Log; + +import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.tapl.LauncherInstrumentation; +import com.android.launcher3.tapl.TestHelpers; +import com.android.launcher3.ui.AbstractLauncherUiTest; +import com.android.launcher3.util.rule.FailureWatcher; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Test rule that allows executing a test multiple times with different conditions + * ie. with transient taskbar enabled and disabled. + * The test should be annotated with @TaskbarModeSwitch. + */ +public class TaskbarModeSwitchRule implements TestRule { + + static final String TAG = "TaskbarModeSwitchRule"; + + public static final int WAIT_TIME_MS = 10000; + + public enum Mode { + TRANSIENT, PERSISTENT, ALL + } + + // Annotation for tests that need to be run with quickstep enabled and disabled. + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public @interface TaskbarModeSwitch { + Mode mode() default ALL; + } + + private final LauncherInstrumentation mLauncher; + + public TaskbarModeSwitchRule(LauncherInstrumentation launcher) { + mLauncher = launcher; + } + + @Override + public Statement apply(Statement base, Description description) { + if (TestHelpers.isInLauncherProcess() + && description.getAnnotation(TaskbarModeSwitch.class) != null) { + Mode mode = description.getAnnotation(TaskbarModeSwitch.class).mode(); + return new Statement() { + @Override + public void evaluate() throws Throwable { + mLauncher.enableDebugTracing(); + final boolean wasTransientTaskbarMode = isTaskbarTransientMode(); + try { + if (mode == TRANSIENT || mode == ALL) { + evaluateWithTransientTaskbar(); + } + if (mode == PERSISTENT || mode == ALL) { + evaluateWithPersistentTaskbar(); + } + } catch (Throwable e) { + Log.e(TAG, "Error", e); + throw e; + } finally { + Log.d(TAG, "In Finally block"); + setTaskbarMode(mLauncher, wasTransientTaskbarMode, description); + } + } + + private void evaluateWithPersistentTaskbar() throws Throwable { + setTaskbarMode(mLauncher, false, description); + base.evaluate(); + } + + private void evaluateWithTransientTaskbar() throws Throwable { + setTaskbarMode(mLauncher, true, description); + base.evaluate(); + } + }; + } else { + return base; + } + } + + private static void enableTransientTaskbar(LauncherInstrumentation launcher, Context c, + boolean enable, Description description) { + boolean success = c.getSharedPreferences(FeatureFlags.FLAGS_PREF_NAME, Context.MODE_PRIVATE) + .edit() + .putBoolean(FeatureFlags.ENABLE_TRANSIENT_TASKBAR.key, enable) + .commit(); + + if (!success) { + final AssertionError assertionError = new AssertionError( + "Unable to save state to SharedPrefs transientTaskbar=" + enable); + if (description != null) { + FailureWatcher.onError(launcher, description, assertionError); + } + throw assertionError; + } + + FeatureFlags.initialize(c); + } + + private static boolean isTaskbarTransientMode() { + return FeatureFlags.ENABLE_TRANSIENT_TASKBAR.get(); + } + + public static void setTaskbarMode(LauncherInstrumentation launcher, + boolean expectTransientTaskbar, Description description) throws Exception { + + Log.d(TAG, "setTaskbarMode: isTransientTaskbar=" + expectTransientTaskbar + "..."); + + enableTransientTaskbar(launcher, getInstrumentation().getTargetContext(), + expectTransientTaskbar, description); + + launcher.recreateTaskbar(); + + assertTrue(launcher, "Couldn't set taskbar=" + expectTransientTaskbar, + isTaskbarTransientMode() == expectTransientTaskbar, description); + + AbstractLauncherUiTest.checkDetectedLeaks(launcher); + } + + private static void assertTrue(LauncherInstrumentation launcher, String message, + boolean condition, Description description) { + launcher.checkForAnomaly(true, true); + if (!condition) { + final AssertionError assertionError = new AssertionError(message); + if (description != null) { + FailureWatcher.onError(launcher, description, assertionError); + } + throw assertionError; + } + } +} diff --git a/src/com/android/launcher3/testing/shared/TestProtocol.java b/src/com/android/launcher3/testing/shared/TestProtocol.java index 3fbce888f1..90b8bfa50d 100644 --- a/src/com/android/launcher3/testing/shared/TestProtocol.java +++ b/src/com/android/launcher3/testing/shared/TestProtocol.java @@ -84,6 +84,8 @@ public final class TestProtocol { public static final String REQUEST_UNFREEZE_APP_LIST = "unfreeze-app-list"; public static final String REQUEST_ENABLE_MANUAL_TASKBAR_STASHING = "enable-taskbar-stashing"; public static final String REQUEST_DISABLE_MANUAL_TASKBAR_STASHING = "disable-taskbar-stashing"; + public static final String REQUEST_ENABLE_BLOCK_TIMEOUT = "enable-block-timeout"; + public static final String REQUEST_DISABLE_BLOCK_TIMEOUT = "disable-block-timeout"; public static final String REQUEST_UNSTASH_TASKBAR_IF_STASHED = "unstash-taskbar-if-stashed"; public static final String REQUEST_STASHED_TASKBAR_HEIGHT = "stashed-taskbar-height"; public static final String REQUEST_RECREATE_TASKBAR = "recreate-taskbar"; diff --git a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java index 4b02ecc1f2..0a00480a84 100644 --- a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java +++ b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java @@ -17,7 +17,9 @@ package com.android.launcher3.tapl; import static com.android.launcher3.tapl.LauncherInstrumentation.TASKBAR_RES_ID; +import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_DISABLE_BLOCK_TIMEOUT; import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_DISABLE_MANUAL_TASKBAR_STASHING; +import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_ENABLE_BLOCK_TIMEOUT; import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_ENABLE_MANUAL_TASKBAR_STASHING; import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_STASHED_TASKBAR_HEIGHT; @@ -88,6 +90,7 @@ public final class LaunchedAppState extends Background { */ public Taskbar showTaskbar() { mLauncher.getTestInfo(REQUEST_ENABLE_MANUAL_TASKBAR_STASHING); + mLauncher.getTestInfo(REQUEST_ENABLE_BLOCK_TIMEOUT); try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck(); LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer( @@ -114,6 +117,7 @@ public final class LaunchedAppState extends Background { } } finally { mLauncher.getTestInfo(REQUEST_DISABLE_MANUAL_TASKBAR_STASHING); + mLauncher.getTestInfo(REQUEST_DISABLE_BLOCK_TIMEOUT); } } diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index fe060a1609..477d5ad46f 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -1824,6 +1824,13 @@ public final class LauncherInstrumentation { getTestInfo(TestProtocol.REQUEST_UNSTASH_TASKBAR_IF_STASHED); } + /** Blocks the taskbar from automatically stashing based on time. */ + public void enableBlockTimeout(boolean enable) { + getTestInfo(enable + ? TestProtocol.REQUEST_ENABLE_BLOCK_TIMEOUT + : TestProtocol.REQUEST_DISABLE_BLOCK_TIMEOUT); + } + /** * Recreates the taskbar (outside of tests this is done for certain configuration changes). * The expected behavior is that the taskbar retains its current state after being recreated. From e444ffb12475eff0726ae84028154bb4de60740a Mon Sep 17 00:00:00 2001 From: Jerry Chang Date: Fri, 28 Oct 2022 02:06:53 +0000 Subject: [PATCH 189/429] Make multi-instances split opt-in based Remove appending MULTIPLE_TASK flag when starting an intent and a task into split screen and leave it to wm-shell to decide whether to append the flag or not. Bug: 255224696 Test: atest WMShellFlickerTests Test: manual check the start intent and task flow Change-Id: I3d887f8dcea67b12a7e94cef55850d52a79a8d2d --- .../com/android/quickstep/SystemUiProxy.java | 18 +++-- .../util/SplitSelectStateController.java | 67 ++++++------------- 2 files changed, 28 insertions(+), 57 deletions(-) diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index acf597bc4c..ef7c6dca11 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -548,15 +548,13 @@ public class SystemUiProxy implements ISystemUiProxy { } } - public void startIntentAndTask(PendingIntent pendingIntent, Intent fillInIntent, - Bundle options1, int taskId, Bundle options2, - @SplitConfigurationOptions.StagePosition int splitPosition, float splitRatio, - RemoteTransition remoteTransition, InstanceId instanceId) { + public void startIntentAndTask(PendingIntent pendingIntent, Bundle options1, int taskId, + Bundle options2, @SplitConfigurationOptions.StagePosition int splitPosition, + float splitRatio, RemoteTransition remoteTransition, InstanceId instanceId) { if (mSystemUiProxy != null) { try { - mSplitScreen.startIntentAndTask(pendingIntent, fillInIntent, options1, - taskId, options2, splitPosition, splitRatio, - remoteTransition, instanceId); + mSplitScreen.startIntentAndTask(pendingIntent, options1, taskId, options2, + splitPosition, splitRatio, remoteTransition, instanceId); } catch (RemoteException e) { Log.w(TAG, "Failed call startIntentAndTask"); } @@ -593,13 +591,13 @@ public class SystemUiProxy implements ISystemUiProxy { } public void startIntentAndTaskWithLegacyTransition(PendingIntent pendingIntent, - Intent fillInIntent, Bundle options1, int taskId, Bundle options2, + Bundle options1, int taskId, Bundle options2, @SplitConfigurationOptions.StagePosition int splitPosition, float splitRatio, RemoteAnimationAdapter adapter, InstanceId instanceId) { if (mSystemUiProxy != null) { try { - mSplitScreen.startIntentAndTaskWithLegacyTransition(pendingIntent, fillInIntent, - options1, taskId, options2, splitPosition, splitRatio, adapter, instanceId); + mSplitScreen.startIntentAndTaskWithLegacyTransition(pendingIntent, options1, taskId, + options2, splitPosition, splitRatio, adapter, instanceId); } catch (RemoteException e) { Log.w(TAG, "Failed call startIntentAndTaskWithLegacyTransition"); } diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java index 08f9fa699f..4a74ac663b 100644 --- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java @@ -37,7 +37,6 @@ import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; -import android.text.TextUtils; import android.util.Log; import android.util.Pair; import android.view.RemoteAnimationAdapter; @@ -88,10 +87,8 @@ public class SplitSelectStateController { private ItemInfo mItemInfo; private Intent mInitialTaskIntent; private int mInitialTaskId = INVALID_TASK_ID; - private String mInitialTaskPackageName; private Intent mSecondTaskIntent; private int mSecondTaskId = INVALID_TASK_ID; - private String mSecondTaskPackageName; private boolean mRecentsAnimationRunning; @Nullable private UserHandle mUser; @@ -119,7 +116,6 @@ public class SplitSelectStateController { public void setInitialTaskSelect(Task task, @StagePosition int stagePosition, StatsLogManager.EventEnum splitEvent, ItemInfo itemInfo) { mInitialTaskId = task.key.id; - mInitialTaskPackageName = task.getTopComponent().getPackageName(); setInitialData(stagePosition, splitEvent, itemInfo); } @@ -131,7 +127,6 @@ public class SplitSelectStateController { mInitialTaskIntent = intent; mUser = itemInfo.user; mItemInfo = itemInfo; - mInitialTaskPackageName = intent.getComponent().getPackageName(); setInitialData(stagePosition, splitEvent, itemInfo); } @@ -143,7 +138,6 @@ public class SplitSelectStateController { @StagePosition int stagePosition, @NonNull ItemInfo itemInfo, StatsLogManager.EventEnum splitEvent) { mInitialTaskId = info.taskId; - mInitialTaskPackageName = info.topActivity.getPackageName(); setInitialData(stagePosition, splitEvent, itemInfo); } @@ -161,9 +155,9 @@ public class SplitSelectStateController { public void launchSplitTasks(Consumer callback) { Pair instanceIds = LogUtils.getShellShareableInstanceId(); - launchTasks(mInitialTaskId, mInitialTaskIntent, mInitialTaskPackageName, mSecondTaskId, - mSecondTaskIntent, mSecondTaskPackageName, mStagePosition, callback, - false /* freezeTaskList */, DEFAULT_SPLIT_RATIO, instanceIds.first); + launchTasks(mInitialTaskId, mInitialTaskIntent, mSecondTaskId, mSecondTaskIntent, + mStagePosition, callback, false /* freezeTaskList */, DEFAULT_SPLIT_RATIO, + instanceIds.first); mStatsLogManager.logger() .withItemInfo(mItemInfo) @@ -177,12 +171,10 @@ public class SplitSelectStateController { */ public void setSecondTask(Task task) { mSecondTaskId = task.key.id; - mSecondTaskPackageName = task.getTopComponent().getPackageName(); } public void setSecondTask(Intent intent) { mSecondTaskIntent = intent; - mSecondTaskPackageName = intent.getComponent().getPackageName(); } /** @@ -205,9 +197,8 @@ public class SplitSelectStateController { */ public void launchTasks(int taskId1, int taskId2, @StagePosition int stagePosition, Consumer callback, boolean freezeTaskList, float splitRatio) { - launchTasks(taskId1, null /* intent1 */, null /* packageName1 */, taskId2, - null /* intent2 */, null /* packageName2 */, stagePosition, callback, - freezeTaskList, splitRatio, null); + launchTasks(taskId1, null /* intent1 */, taskId2, null /* intent2 */, stagePosition, + callback, freezeTaskList, splitRatio, null); } /** @@ -220,8 +211,8 @@ public class SplitSelectStateController { * a split instance, null for cases that bring existing instaces to the * foreground (quickswitch, launching previous pairs from overview) */ - public void launchTasks(int taskId1, @Nullable Intent intent1, String packageName1, int taskId2, - @Nullable Intent intent2, String packageName2, @StagePosition int stagePosition, + public void launchTasks(int taskId1, @Nullable Intent intent1, int taskId2, + @Nullable Intent intent2, @StagePosition int stagePosition, Consumer callback, boolean freezeTaskList, float splitRatio, @Nullable InstanceId shellInstanceId) { TestLogging.recordEvent( @@ -240,10 +231,10 @@ public class SplitSelectStateController { null /* options2 */, stagePosition, splitRatio, remoteTransition, shellInstanceId); } else if (intent2 == null) { - launchIntentOrShortcut(intent1, packageName2, options1, taskId2, stagePosition, - splitRatio, remoteTransition, shellInstanceId); + launchIntentOrShortcut(intent1, options1, taskId2, stagePosition, splitRatio, + remoteTransition, shellInstanceId); } else if (intent1 == null) { - launchIntentOrShortcut(intent2, packageName1, options1, taskId1, + launchIntentOrShortcut(intent2, options1, taskId1, getOppositeStagePosition(stagePosition), splitRatio, remoteTransition, shellInstanceId); } else { @@ -261,10 +252,10 @@ public class SplitSelectStateController { taskId2, null /* options2 */, stagePosition, splitRatio, adapter, shellInstanceId); } else if (intent2 == null) { - launchIntentOrShortcutLegacy(intent1, packageName2, options1, taskId2, - stagePosition, splitRatio, adapter, shellInstanceId); + launchIntentOrShortcutLegacy(intent1, options1, taskId2, stagePosition, splitRatio, + adapter, shellInstanceId); } else if (intent1 == null) { - launchIntentOrShortcutLegacy(intent2, packageName1, options1, taskId1, + launchIntentOrShortcutLegacy(intent2, options1, taskId1, getOppositeStagePosition(stagePosition), splitRatio, adapter, shellInstanceId); } else { @@ -273,9 +264,8 @@ public class SplitSelectStateController { } } - private void launchIntentOrShortcut(Intent intent, String otherTaskPackageName, - ActivityOptions options1, int taskId, @StagePosition int stagePosition, - float splitRatio, RemoteTransition remoteTransition, + private void launchIntentOrShortcut(Intent intent, ActivityOptions options1, int taskId, + @StagePosition int stagePosition, float splitRatio, RemoteTransition remoteTransition, @Nullable InstanceId shellInstanceId) { PendingIntent pendingIntent = getPendingIntent(intent); final ShortcutInfo shortcutInfo = getShortcutInfo(intent, @@ -285,16 +275,14 @@ public class SplitSelectStateController { options1.toBundle(), taskId, null /* options2 */, stagePosition, splitRatio, remoteTransition, shellInstanceId); } else { - mSystemUiProxy.startIntentAndTask(pendingIntent, - getFillInIntent(intent, otherTaskPackageName), options1.toBundle(), taskId, + mSystemUiProxy.startIntentAndTask(pendingIntent, options1.toBundle(), taskId, null /* options2 */, stagePosition, splitRatio, remoteTransition, shellInstanceId); } } - private void launchIntentOrShortcutLegacy(Intent intent, String otherTaskPackageName, - ActivityOptions options1, int taskId, @StagePosition int stagePosition, - float splitRatio, RemoteAnimationAdapter adapter, + private void launchIntentOrShortcutLegacy(Intent intent, ActivityOptions options1, int taskId, + @StagePosition int stagePosition, float splitRatio, RemoteAnimationAdapter adapter, @Nullable InstanceId shellInstanceId) { PendingIntent pendingIntent = getPendingIntent(intent); final ShortcutInfo shortcutInfo = getShortcutInfo(intent, @@ -305,9 +293,8 @@ public class SplitSelectStateController { splitRatio, adapter, shellInstanceId); } else { mSystemUiProxy.startIntentAndTaskWithLegacyTransition(pendingIntent, - getFillInIntent(intent, otherTaskPackageName), options1.toBundle(), taskId, - null /* options2 */, stagePosition, splitRatio, adapter, - shellInstanceId); + options1.toBundle(), taskId, null /* options2 */, stagePosition, splitRatio, + adapter, shellInstanceId); } } @@ -318,18 +305,6 @@ public class SplitSelectStateController { : PendingIntent.getActivity(mContext, 0, intent, FLAG_MUTABLE)); } - private Intent getFillInIntent(Intent intent, String otherTaskPackageName) { - if (intent == null) { - return null; - } - - Intent fillInIntent = new Intent(); - if (TextUtils.equals(intent.getComponent().getPackageName(), otherTaskPackageName)) { - fillInIntent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK); - } - return fillInIntent; - } - public @StagePosition int getActiveSplitStagePosition() { return mStagePosition; @@ -464,10 +439,8 @@ public class SplitSelectStateController { public void resetState() { mInitialTaskId = INVALID_TASK_ID; mInitialTaskIntent = null; - mInitialTaskPackageName = null; mSecondTaskId = INVALID_TASK_ID; mSecondTaskIntent = null; - mSecondTaskPackageName = null; mStagePosition = SplitConfigurationOptions.STAGE_POSITION_UNDEFINED; mRecentsAnimationRunning = false; mLaunchingTaskView = null; From 29f7474056225cb007c0c6b58b18461d1e52ebf5 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Mon, 7 Nov 2022 13:50:49 -0800 Subject: [PATCH 190/429] Have responsive taskbar UI during swipe up gesture. - Makes taskbar threshold an absolute Y threshold instead of a distance threshold. - Moves handle, taskbar view, and taskbar background during the swipe up gesture Next CL will address transforming the nav handle <-> taskbar and ensuring that there's a clean handoff Bug: 246631059 Test: swipe up on taskbar, release. see bounce swipe up on taskbar to go home, proper icon alignment swipe up on taskbar, pause for overview, see bounce -> further movement should not move taskbar test launcher3 Change-Id: I141236fd72428cda7edd0ff116de1d478d18c722 --- .../taskbar/LauncherTaskbarUIController.java | 10 +- .../taskbar/StashedHandleViewController.java | 30 ++- .../taskbar/TaskbarActivityContext.java | 16 ++ .../taskbar/TaskbarBackgroundRenderer.kt | 7 +- .../launcher3/taskbar/TaskbarControllers.java | 6 +- .../launcher3/taskbar/TaskbarDragLayer.java | 8 + .../taskbar/TaskbarDragLayerController.java | 7 + .../taskbar/TaskbarTranslationController.java | 197 ++++++++++++++++++ .../taskbar/TaskbarUIController.java | 7 + .../taskbar/TaskbarViewController.java | 12 +- .../android/quickstep/AbsSwipeUpHandler.java | 3 + .../TaskbarStashInputConsumer.java | 44 +++- 12 files changed, 327 insertions(+), 20 deletions(-) create mode 100644 quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index 317f6a4884..50fbe23792 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -193,7 +193,15 @@ public class LauncherTaskbarUIController extends TaskbarUIController { */ public Animator createAnimToLauncher(@NonNull LauncherState toState, @NonNull RecentsAnimationCallbacks callbacks, long duration) { - return mTaskbarLauncherStateController.createAnimToLauncher(toState, callbacks, duration); + AnimatorSet set = new AnimatorSet(); + Animator taskbarState = mTaskbarLauncherStateController + .createAnimToLauncher(toState, callbacks, duration); + long halfDuration = Math.round(duration * 0.5f); + Animator translation = + mControllers.taskbarTranslationController.createAnimToLauncher(halfDuration); + + set.playTogether(taskbarState, translation); + return set; } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java index 12dbcb3902..45d573994d 100644 --- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java @@ -30,6 +30,7 @@ import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.RevealOutlineAnimation; import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; +import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.Executors; import com.android.launcher3.util.MultiPropertyFactory; import com.android.launcher3.util.MultiValueAlpha; @@ -66,6 +67,7 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT // Initialized in init. private TaskbarControllers mControllers; + private int mTaskbarSize; // The bounds we want to clip to in the settled state when showing the stashed handle. private final Rect mStashedHandleBounds = new Rect(); @@ -96,15 +98,18 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT DeviceProfile deviceProfile = mActivity.getDeviceProfile(); Resources resources = mActivity.getResources(); if (isPhoneGestureNavMode(mActivity.getDeviceProfile())) { - mStashedHandleView.getLayoutParams().height = - resources.getDimensionPixelSize(R.dimen.taskbar_size); + mTaskbarSize = resources.getDimensionPixelSize(R.dimen.taskbar_size); mStashedHandleWidth = resources.getDimensionPixelSize(R.dimen.taskbar_stashed_small_screen); } else { - mStashedHandleView.getLayoutParams().height = deviceProfile.taskbarSize; + mTaskbarSize = deviceProfile.taskbarSize; mStashedHandleWidth = resources .getDimensionPixelSize(R.dimen.taskbar_stashed_handle_width); } + int taskbarBottomMargin = DisplayController.isTransientTaskbar(mActivity) + ? resources.getDimensionPixelSize(R.dimen.transient_taskbar_margin) + : 0; + mStashedHandleView.getLayoutParams().height = mTaskbarSize + taskbarBottomMargin; mTaskbarStashedHandleAlpha.get(ALPHA_INDEX_STASHED).setValue( isPhoneGestureNavMode(deviceProfile) ? 1 : 0); @@ -181,9 +186,17 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT * morphs into the size of where the taskbar icons will be. */ public Animator createRevealAnimToIsStashed(boolean isStashed) { + Rect visualBounds = new Rect(mControllers.taskbarViewController.getIconLayoutBounds()); + + if (DisplayController.isTransientTaskbar(mActivity)) { + // Account for the full visual height of the transient taskbar. + int heightDiff = (mTaskbarSize - visualBounds.height()) / 2; + visualBounds.top -= heightDiff; + visualBounds.bottom += heightDiff; + } + final RevealOutlineAnimation handleRevealProvider = new RoundedRectRevealOutlineProvider( - mStashedHandleRadius, mStashedHandleRadius, - mControllers.taskbarViewController.getIconLayoutBounds(), mStashedHandleBounds); + mStashedHandleRadius, mStashedHandleRadius, visualBounds, mStashedHandleBounds); boolean isReversed = !isStashed; boolean changingDirection = mWasLastRevealAnimReversed != isReversed; @@ -219,6 +232,13 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT mStashedHandleView.setScaleY(mTaskbarStashedHandleHintScale.value); } + /** + * Sets the translation of the stashed handle during the swipe up gesture. + */ + protected void setTranslationYForSwipe(float transY) { + mStashedHandleView.setTranslationY(transY); + } + /** * Should be called when the home button is disabled, so we can hide this handle as well. */ diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index fad9ff490c..3c9e96f295 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -78,6 +78,7 @@ import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.popup.PopupDataProvider; import com.android.launcher3.taskbar.TaskbarAutohideSuspendController.AutohideSuspendFlag; +import com.android.launcher3.taskbar.TaskbarTranslationController.TransitionCallback; import com.android.launcher3.taskbar.allapps.TaskbarAllAppsController; import com.android.launcher3.taskbar.overlay.TaskbarOverlayController; import com.android.launcher3.testing.TestLogging; @@ -223,6 +224,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { new TaskbarAllAppsController(), new TaskbarInsetsController(this), new VoiceInteractionWindowController(this), + new TaskbarTranslationController(this), isDesktopMode ? new DesktopTaskbarRecentAppsController(this) : TaskbarRecentAppsController.DEFAULT); @@ -833,6 +835,20 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(false); } + /** + * Called to start the taskbar translation spring to its settled translation (0). + */ + public void startTranslationSpring() { + mControllers.taskbarTranslationController.startSpring(); + } + + /** + * Returns a callback to help monitor the swipe gesture. + */ + public TransitionCallback getTranslationCallbacks() { + return mControllers.taskbarTranslationController.getTransitionCallback(); + } + /** * Called when a transient Autohide flag suspend status changes. */ diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt index a948fb37e7..ff7e8e9af2 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt @@ -34,6 +34,7 @@ class TaskbarBackgroundRenderer(context: TaskbarActivityContext) { val paint: Paint = Paint() var backgroundHeight = context.deviceProfile.taskbarSize.toFloat() + var translationYForSwipe = 0f private var maxBackgroundHeight = context.deviceProfile.taskbarSize.toFloat() private val transientBackgroundBounds = context.transientTaskbarBounds @@ -114,11 +115,13 @@ class TaskbarBackgroundRenderer(context: TaskbarActivityContext) { canvas.translate(canvas.width - rightCornerRadius, -rightCornerRadius) canvas.drawPath(invertedRightCornerPath, paint) } else { + // Approximates the stash/unstash animation to transform the background. val scaleFactor = backgroundHeight / maxBackgroundHeight val width = transientBackgroundBounds.width() val widthScale = mapToRange(scaleFactor, 0f, 1f, 0.4f, 1f, Interpolators.LINEAR) val newWidth = widthScale * width val delta = width - newWidth + canvas.translate(0f, bottomMargin * ((1f - scaleFactor) / 2f)) // Draw shadow. val shadowAlpha = mapToRange(paint.alpha.toFloat(), 0f, 255f, 0f, 25f, @@ -132,9 +135,9 @@ class TaskbarBackgroundRenderer(context: TaskbarActivityContext) { canvas.drawRoundRect( transientBackgroundBounds.left + (delta / 2f), - 0f, + translationYForSwipe, transientBackgroundBounds.right - (delta / 2f), - backgroundHeight, + backgroundHeight + translationYForSwipe, radius, radius, paint ) } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java index fc20753c54..2b95df0a76 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarControllers.java @@ -56,6 +56,7 @@ public class TaskbarControllers { public final TaskbarInsetsController taskbarInsetsController; public final VoiceInteractionWindowController voiceInteractionWindowController; public final TaskbarRecentAppsController taskbarRecentAppsController; + public final TaskbarTranslationController taskbarTranslationController; public final TaskbarOverlayController taskbarOverlayController; @Nullable private LoggableTaskbarController[] mControllersToLog = null; @@ -92,6 +93,7 @@ public class TaskbarControllers { TaskbarAllAppsController taskbarAllAppsController, TaskbarInsetsController taskbarInsetsController, VoiceInteractionWindowController voiceInteractionWindowController, + TaskbarTranslationController taskbarTranslationController, TaskbarRecentAppsController taskbarRecentAppsController) { this.taskbarActivityContext = taskbarActivityContext; this.taskbarDragController = taskbarDragController; @@ -113,6 +115,7 @@ public class TaskbarControllers { this.taskbarAllAppsController = taskbarAllAppsController; this.taskbarInsetsController = taskbarInsetsController; this.voiceInteractionWindowController = voiceInteractionWindowController; + this.taskbarTranslationController = taskbarTranslationController; this.taskbarRecentAppsController = taskbarRecentAppsController; } @@ -144,6 +147,7 @@ public class TaskbarControllers { taskbarInsetsController.init(this); voiceInteractionWindowController.init(this); taskbarRecentAppsController.init(this); + taskbarTranslationController.init(this); mControllersToLog = new LoggableTaskbarController[] { taskbarDragController, navButtonController, navbarButtonsViewController, @@ -151,7 +155,7 @@ public class TaskbarControllers { taskbarUnfoldAnimationController, taskbarKeyguardController, stashedHandleViewController, taskbarStashController, taskbarEduController, taskbarAutohideSuspendController, taskbarPopupController, taskbarInsetsController, - voiceInteractionWindowController + voiceInteractionWindowController, taskbarTranslationController }; mBackgroundRendererControllers = new BackgroundRendererController[] { taskbarDragLayerController, taskbarScrimViewController, diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java index 41f39653c3..24257da767 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java @@ -167,6 +167,14 @@ public class TaskbarDragLayer extends BaseDragLayer { invalidate(); } + /* + * Sets the translation of the background during the swipe up gesture. + */ + protected void setBackgroundTranslationYForSwipe(float translationY) { + mBackgroundRenderer.setTranslationYForSwipe(translationY); + invalidate(); + } + @Override public boolean dispatchTouchEvent(MotionEvent ev) { TestLogging.recordMotionEvent(TestProtocol.SEQUENCE_MAIN, "Touch event", ev); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java index 9765a41b7d..48f3f5ef4f 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java @@ -133,6 +133,13 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa updateNavBarDarkIntensityMultiplier(); } + /** + * Sets the translation of the background during the swipe up gesture. + */ + public void setTranslationYForSwipe(float transY) { + mTaskbarDragLayer.setBackgroundTranslationYForSwipe(transY); + } + private void updateBackgroundOffset() { mTaskbarDragLayer.setTaskbarBackgroundOffset(mBgOffset.value); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java new file mode 100644 index 0000000000..1a7ec13963 --- /dev/null +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarTranslationController.java @@ -0,0 +1,197 @@ +/* + * Copyright (C) 2022 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.launcher3.taskbar; + +import static com.android.launcher3.anim.AnimatorListeners.forEndCallback; +import static com.android.quickstep.AnimatedFloat.VALUE; + +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; +import android.animation.ObjectAnimator; +import android.animation.ValueAnimator; + +import androidx.annotation.Nullable; +import androidx.dynamicanimation.animation.SpringForce; + +import com.android.launcher3.anim.Interpolators; +import com.android.launcher3.anim.SpringAnimationBuilder; +import com.android.launcher3.util.DisplayController; +import com.android.quickstep.AnimatedFloat; + +import java.io.PrintWriter; + +/** + * Class responsible for translating the transient taskbar UI during a swipe gesture. + * + * The translation is controlled, in priority order: + * - animation to home + * - a spring animation + * - controlled by user + * + * The spring animation will play start once the user lets go or when user pauses to go to overview. + * When the user goes home, the stash animation will play. + */ +public class TaskbarTranslationController implements TaskbarControllers.LoggableTaskbarController { + + private final TaskbarActivityContext mContext; + private TaskbarControllers mControllers; + private final AnimatedFloat mTranslationYForSwipe = new AnimatedFloat( + this::updateTranslationYForSwipe); + + private boolean mHasSprungOnceThisGesture; + private @Nullable ValueAnimator mSpringBounce; + private boolean mGestureEnded; + private boolean mAnimationToHomeRunning; + + private final boolean mIsTransientTaskbar; + + private final TransitionCallback mCallback; + + public TaskbarTranslationController(TaskbarActivityContext context) { + mContext = context; + mIsTransientTaskbar = DisplayController.isTransientTaskbar(mContext); + mCallback = new TransitionCallback(); + } + + /** + * Initialization method. + */ + public void init(TaskbarControllers controllers) { + mControllers = controllers; + } + + /** + * Called to cancel any existing animations. + */ + public void cancelAnimationIfExists() { + if (mSpringBounce != null) { + mSpringBounce.cancel(); + mSpringBounce = null; + } + reset(); + } + + private void updateTranslationYForSwipe() { + if (!mIsTransientTaskbar) { + return; + } + + float transY = mTranslationYForSwipe.value; + mControllers.stashedHandleViewController.setTranslationYForSwipe(transY); + mControllers.taskbarViewController.setTranslationYForSwipe(transY); + mControllers.taskbarDragLayerController.setTranslationYForSwipe(transY); + } + + /** + * Starts a spring aniamtion to set the views back to the resting state. + */ + public void startSpring() { + if (mHasSprungOnceThisGesture || mAnimationToHomeRunning) { + return; + } + mSpringBounce = new SpringAnimationBuilder(mContext) + .setStartValue(mTranslationYForSwipe.value) + .setEndValue(0) + .setDampingRatio(SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY) + .setStiffness(SpringForce.STIFFNESS_LOW) + .build(mTranslationYForSwipe, VALUE); + mSpringBounce.addListener(forEndCallback(() -> { + if (mGestureEnded) { + reset(); + } + })); + mSpringBounce.start(); + mHasSprungOnceThisGesture = true; + } + + private void reset() { + mGestureEnded = false; + mHasSprungOnceThisGesture = false; + } + + /** + * Returns a callback to help monitor the swipe gesture. + */ + public TransitionCallback getTransitionCallback() { + return mCallback; + } + + /** + * Returns an animation to reset the taskbar translation for animation back to launcher. + */ + public ObjectAnimator createAnimToLauncher(long duration) { + ObjectAnimator animator = ObjectAnimator.ofFloat(mTranslationYForSwipe, VALUE, 0); + animator.setInterpolator(Interpolators.LINEAR); + animator.setDuration(duration); + animator.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationStart(Animator animation) { + cancelAnimationIfExists(); + mAnimationToHomeRunning = true; + } + + @Override + public void onAnimationEnd(Animator animation) { + mAnimationToHomeRunning = false; + reset(); + } + }); + return animator; + } + + /** + * Helper class to communicate to/from the input consumer. + */ + public class TransitionCallback { + + /** + * Called when there is movement to move the taskbar. + */ + public void onActionMove(float dY) { + if (mAnimationToHomeRunning + || (mHasSprungOnceThisGesture && !mGestureEnded)) { + return; + } + + mTranslationYForSwipe.updateValue(dY); + } + + /** + * Called when swipe gesture has ended. + */ + public void onActionEnd() { + if (mHasSprungOnceThisGesture) { + reset(); + } else { + mGestureEnded = true; + startSpring(); + } + } + } + + @Override + public void dumpLogs(String prefix, PrintWriter pw) { + pw.println(prefix + "TaskbarTranslationController:"); + + pw.println(prefix + "\tmTranslationYForSwipe=" + mTranslationYForSwipe.value); + pw.println(prefix + "\tmHasSprungOnceThisGesture=" + mHasSprungOnceThisGesture); + pw.println(prefix + "\tmAnimationToHomeRunning=" + mAnimationToHomeRunning); + pw.println(prefix + "\tmGestureEnded=" + mGestureEnded); + pw.println(prefix + "\tmSpringBounce is running=" + (mSpringBounce != null + && mSpringBounce.isRunning())); + } +} + diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java index 11521260e9..1014cb6691 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java @@ -105,6 +105,13 @@ public class TaskbarUIController { return mControllers.taskbarStashController.isStashed(); } + /** + * Called at the end of the swipe gesture on Transient taskbar. + */ + public void startTranslationSpring() { + mControllers.taskbarActivityContext.startTranslationSpring(); + } + /* * @param ev MotionEvent in screen coordinates. * @return Whether any Taskbar item could handle the given MotionEvent if given the chance. diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index a73528b5ef..80a31b4b44 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -91,6 +91,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar this::updateTranslationY); private AnimatedFloat mTaskbarNavButtonTranslationY; private AnimatedFloat mTaskbarNavButtonTranslationYForInAppDisplay; + private float mTaskbarIconTranslationYForSwipe; private final int mTaskbarBottomMargin; @@ -260,9 +261,18 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar mTaskbarView.setScaleY(scale); } + /** + * Sets the translation of the TaskbarView during the swipe up gesture. + */ + public void setTranslationYForSwipe(float transY) { + mTaskbarIconTranslationYForSwipe = transY; + updateTranslationY(); + } + private void updateTranslationY() { mTaskbarView.setTranslationY(mTaskbarIconTranslationYForHome.value - + mTaskbarIconTranslationYForStash.value); + + mTaskbarIconTranslationYForStash.value + + mTaskbarIconTranslationYForSwipe); } private void updateIconsBackground() { diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 7e4c2f690a..3d59d7339f 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -99,6 +99,7 @@ import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.logging.StatsLogManager.StatsLogger; import com.android.launcher3.statemanager.BaseState; import com.android.launcher3.statemanager.StatefulActivity; +import com.android.launcher3.taskbar.TaskbarUIController; import com.android.launcher3.tracing.InputConsumerProto; import com.android.launcher3.tracing.SwipeHandlerProto; import com.android.launcher3.util.ActivityLifecycleCallbacksAdapter; @@ -662,6 +663,8 @@ public abstract class AbsSwipeUpHandler, true/* moveFocusedTask */, new ActiveGestureLog.CompoundString( "motion pause detected (animate=true)")); + Optional.ofNullable(mActivityInterface.getTaskbarController()) + .ifPresent(TaskbarUIController::startTranslationSpring); performHapticFeedback(); } diff --git a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java index 1430492401..b7f2022073 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarStashInputConsumer.java @@ -27,9 +27,13 @@ import android.view.GestureDetector; import android.view.GestureDetector.SimpleOnGestureListener; import android.view.MotionEvent; +import androidx.annotation.Nullable; + import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.taskbar.TaskbarActivityContext; +import com.android.launcher3.taskbar.TaskbarTranslationController.TransitionCallback; +import com.android.launcher3.touch.OverScroll; import com.android.launcher3.util.DisplayController; import com.android.quickstep.InputConsumer; import com.android.systemui.shared.system.InputMonitorCompat; @@ -48,7 +52,7 @@ public class TaskbarStashInputConsumer extends DelegateInputConsumer { private final float mUnstashArea; private final float mScreenWidth; - private final int mTaskbarThreshold; + private final int mTaskbarThresholdY; private boolean mHasPassedTaskbarThreshold; private final PointF mDownPos = new PointF(); @@ -57,6 +61,8 @@ public class TaskbarStashInputConsumer extends DelegateInputConsumer { private final boolean mIsTransientTaskbar; + private final @Nullable TransitionCallback mTransitionCallback; + public TaskbarStashInputConsumer(Context context, InputConsumer delegate, InputMonitorCompat inputMonitor, TaskbarActivityContext taskbarActivityContext) { super(delegate, inputMonitor); @@ -66,7 +72,9 @@ public class TaskbarStashInputConsumer extends DelegateInputConsumer { Resources res = context.getResources(); mUnstashArea = res.getDimensionPixelSize(R.dimen.taskbar_unstash_input_area); - mTaskbarThreshold = res.getDimensionPixelSize(R.dimen.taskbar_nav_threshold); + int taskbarThreshold = res.getDimensionPixelSize(R.dimen.taskbar_nav_threshold); + int screenHeight = taskbarActivityContext.getDeviceProfile().heightPx; + mTaskbarThresholdY = screenHeight - taskbarThreshold; mIsTransientTaskbar = DisplayController.isTransientTaskbar(context); @@ -76,6 +84,10 @@ public class TaskbarStashInputConsumer extends DelegateInputConsumer { onLongPressDetected(motionEvent); } }); + + mTransitionCallback = mIsTransientTaskbar + ? taskbarActivityContext.getTranslationCallbacks() + : null; } @Override @@ -138,16 +150,25 @@ public class TaskbarStashInputConsumer extends DelegateInputConsumer { break; } mLastPos.set(ev.getX(pointerIndex), ev.getY(pointerIndex)); - float displacementY = mLastPos.y - mDownPos.y; - float verticalDist = Math.abs(displacementY); - boolean passedTaskbarThreshold = verticalDist >= mTaskbarThreshold; - if (!mHasPassedTaskbarThreshold - && passedTaskbarThreshold - && mIsTransientTaskbar) { - mHasPassedTaskbarThreshold = true; + if (mIsTransientTaskbar) { + float dY = mLastPos.y - mDownPos.y; + boolean passedTaskbarThreshold = dY < 0 + && mLastPos.y < mTaskbarThresholdY; - mTaskbarActivityContext.onSwipeToUnstashTaskbar(); + if (!mHasPassedTaskbarThreshold + && passedTaskbarThreshold) { + mHasPassedTaskbarThreshold = true; + + mTaskbarActivityContext.onSwipeToUnstashTaskbar(); + } + + if (dY < 0) { + dY = -OverScroll.dampedScroll(-dY, mTaskbarThresholdY); + if (mTransitionCallback != null) { + mTransitionCallback.onActionMove(dY); + } + } } break; case MotionEvent.ACTION_UP: @@ -158,6 +179,9 @@ public class TaskbarStashInputConsumer extends DelegateInputConsumer { } mTaskbarActivityContext.setAutohideSuspendFlag( FLAG_AUTOHIDE_SUSPEND_TOUCHING, false); + if (mTransitionCallback != null) { + mTransitionCallback.onActionEnd(); + } mHasPassedTaskbarThreshold = false; break; } From e1100b904d8a258554779a0a5fde04319958f0ee Mon Sep 17 00:00:00 2001 From: Pat Manning Date: Thu, 13 Oct 2022 13:18:36 +0100 Subject: [PATCH 191/429] Unstash taskbar when transitioning to fallback overview. Update LauncherInstrumentation taskbar visibility check to include assertions in fallback launcher using OverviewObject instead of LauncherObject. Fix: 253042501 Test: manual Change-Id: I9f2aa228e8aa97ef8ca1a4535b7f8fcded8a4572 --- .../taskbar/FallbackTaskbarUIController.java | 9 +- .../android/launcher3/tapl/Background.java | 2 +- .../launcher3/tapl/LaunchedAppState.java | 10 +- .../tapl/LauncherInstrumentation.java | 124 +++++++++++------- .../com/android/launcher3/tapl/Taskbar.java | 11 +- 5 files changed, 93 insertions(+), 63 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java index f1e67479f5..08ed60d18a 100644 --- a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java @@ -21,6 +21,7 @@ import static com.android.launcher3.taskbar.TaskbarStashController.TASKBAR_STASH import android.animation.Animator; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.statemanager.StateManager; import com.android.quickstep.RecentsActivity; import com.android.quickstep.fallback.RecentsState; @@ -70,12 +71,14 @@ public class FallbackTaskbarUIController extends TaskbarUIController { * Currently this animation just force stashes the taskbar in Overview. */ public Animator createAnimToRecentsState(RecentsState toState, long duration) { - boolean forceStashed = toState.hasOverviewActions(); + boolean useStashedLauncherState = toState.hasOverviewActions(); + boolean stashedLauncherState = + useStashedLauncherState && !FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get(); TaskbarStashController controller = mControllers.taskbarStashController; // Set both FLAG_IN_STASHED_LAUNCHER_STATE and FLAG_IN_APP to ensure the state is respected. // For all other states, just use the current stashed-in-app setting (e.g. if long clicked). - controller.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, forceStashed); - controller.updateStateForFlag(FLAG_IN_APP, !forceStashed); + controller.updateStateForFlag(FLAG_IN_STASHED_LAUNCHER_STATE, stashedLauncherState); + controller.updateStateForFlag(FLAG_IN_APP, !useStashedLauncherState); return controller.applyStateWithoutStart(duration); } diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java index 15705e7c5b..5a96d95316 100644 --- a/tests/tapl/com/android/launcher3/tapl/Background.java +++ b/tests/tapl/com/android/launcher3/tapl/Background.java @@ -58,7 +58,7 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine "want to switch from background to overview")) { verifyActiveContainer(); goToOverviewUnchecked(); - return mLauncher.isFallbackOverview() + return mLauncher.is3PLauncher() ? new BaseOverview(mLauncher) : new Overview(mLauncher); } } diff --git a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java index 4b02ecc1f2..f23a38c3f2 100644 --- a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java +++ b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java @@ -55,7 +55,7 @@ public final class LaunchedAppState extends Background { public Taskbar getTaskbar() { try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "want to get the taskbar")) { - mLauncher.waitForLauncherObject(TASKBAR_RES_ID); + mLauncher.waitForSystemLauncherObject(TASKBAR_RES_ID); return new Taskbar(mLauncher); } @@ -67,7 +67,7 @@ public final class LaunchedAppState extends Background { public void assertTaskbarHidden() { try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "waiting for taskbar to be hidden")) { - mLauncher.waitUntilLauncherObjectGone(TASKBAR_RES_ID); + mLauncher.waitUntilSystemLauncherObjectGone(TASKBAR_RES_ID); } } @@ -77,7 +77,7 @@ public final class LaunchedAppState extends Background { public void assertTaskbarVisible() { try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "waiting for taskbar to be visible")) { - mLauncher.waitForLauncherObject(TASKBAR_RES_ID); + mLauncher.waitForSystemLauncherObject(TASKBAR_RES_ID); } } @@ -92,7 +92,7 @@ public final class LaunchedAppState extends Background { try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck(); LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer( "want to show the taskbar")) { - mLauncher.waitUntilLauncherObjectGone(TASKBAR_RES_ID); + mLauncher.waitUntilSystemLauncherObjectGone(TASKBAR_RES_ID); final long downTime = SystemClock.uptimeMillis(); final int unstashTargetY = mLauncher.getRealDisplaySize().y @@ -106,7 +106,7 @@ public final class LaunchedAppState extends Background { LauncherInstrumentation.log("showTaskbar: sent down"); try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("pressed down")) { - mLauncher.waitForLauncherObject(TASKBAR_RES_ID); + mLauncher.waitForSystemLauncherObject(TASKBAR_RES_ID); mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_UP, unstashTarget, LauncherInstrumentation.GestureScope.OUTSIDE_WITH_PILFER); diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 56ba9ea654..8f6431c549 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -555,7 +555,7 @@ public final class LauncherInstrumentation { private String getVisibleStateMessage() { if (hasLauncherObject(CONTEXT_MENU_RES_ID)) return "Context Menu"; if (hasLauncherObject(WIDGETS_RES_ID)) return "Widgets"; - if (hasLauncherObject(OVERVIEW_RES_ID)) return "Overview"; + if (hasSystemLauncherObject(OVERVIEW_RES_ID)) return "Overview"; if (hasLauncherObject(WORKSPACE_RES_ID)) return "Workspace"; if (hasLauncherObject(APPS_RES_ID)) return "AllApps"; return "LaunchedApp (" + getVisiblePackages() + ")"; @@ -760,73 +760,89 @@ public final class LauncherInstrumentation { switch (containerType) { case WORKSPACE: { waitUntilLauncherObjectGone(APPS_RES_ID); - waitUntilLauncherObjectGone(OVERVIEW_RES_ID); waitUntilLauncherObjectGone(WIDGETS_RES_ID); - waitUntilLauncherObjectGone(TASKBAR_RES_ID); - waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); + waitUntilSystemLauncherObjectGone(OVERVIEW_RES_ID); + waitUntilSystemLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); + + if (is3PLauncher() && isTablet()) { + waitForSystemLauncherObject(TASKBAR_RES_ID); + } else { + waitUntilSystemLauncherObjectGone(TASKBAR_RES_ID); + } return waitForLauncherObject(WORKSPACE_RES_ID); } case WIDGETS: { waitUntilLauncherObjectGone(WORKSPACE_RES_ID); waitUntilLauncherObjectGone(APPS_RES_ID); - waitUntilLauncherObjectGone(OVERVIEW_RES_ID); - waitUntilLauncherObjectGone(TASKBAR_RES_ID); - waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); + waitUntilSystemLauncherObjectGone(OVERVIEW_RES_ID); + waitUntilSystemLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); + + if (is3PLauncher() && isTablet()) { + waitForSystemLauncherObject(TASKBAR_RES_ID); + } else { + waitUntilSystemLauncherObjectGone(TASKBAR_RES_ID); + } return waitForLauncherObject(WIDGETS_RES_ID); } - case TASKBAR_ALL_APPS: - case HOME_ALL_APPS: { + case TASKBAR_ALL_APPS: { waitUntilLauncherObjectGone(WORKSPACE_RES_ID); - waitUntilLauncherObjectGone(OVERVIEW_RES_ID); waitUntilLauncherObjectGone(WIDGETS_RES_ID); - waitUntilLauncherObjectGone(TASKBAR_RES_ID); - waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); + waitUntilSystemLauncherObjectGone(OVERVIEW_RES_ID); + waitUntilSystemLauncherObjectGone(TASKBAR_RES_ID); + waitUntilSystemLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); return waitForLauncherObject(APPS_RES_ID); } - case OVERVIEW: { + case HOME_ALL_APPS: { + waitUntilLauncherObjectGone(WORKSPACE_RES_ID); + waitUntilLauncherObjectGone(WIDGETS_RES_ID); + waitUntilSystemLauncherObjectGone(OVERVIEW_RES_ID); + waitUntilSystemLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); + + if (is3PLauncher() && isTablet()) { + waitForSystemLauncherObject(TASKBAR_RES_ID); + } else { + waitUntilSystemLauncherObjectGone(TASKBAR_RES_ID); + } + + return waitForLauncherObject(APPS_RES_ID); + } + case OVERVIEW: + case FALLBACK_OVERVIEW: { waitUntilLauncherObjectGone(APPS_RES_ID); waitUntilLauncherObjectGone(WORKSPACE_RES_ID); waitUntilLauncherObjectGone(WIDGETS_RES_ID); - waitUntilLauncherObjectGone(TASKBAR_RES_ID); - waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); + waitUntilSystemLauncherObjectGone(TASKBAR_RES_ID); + waitUntilSystemLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); - return waitForLauncherObject(OVERVIEW_RES_ID); + return waitForSystemLauncherObject(OVERVIEW_RES_ID); } case SPLIT_SCREEN_SELECT: { waitUntilLauncherObjectGone(APPS_RES_ID); waitUntilLauncherObjectGone(WORKSPACE_RES_ID); waitUntilLauncherObjectGone(WIDGETS_RES_ID); - waitUntilLauncherObjectGone(TASKBAR_RES_ID); + waitUntilSystemLauncherObjectGone(TASKBAR_RES_ID); - waitForLauncherObject(SPLIT_PLACEHOLDER_RES_ID); - return waitForLauncherObject(OVERVIEW_RES_ID); - } - case FALLBACK_OVERVIEW: { - waitUntilLauncherObjectGone(APPS_RES_ID); - waitUntilLauncherObjectGone(WORKSPACE_RES_ID); - waitUntilLauncherObjectGone(WIDGETS_RES_ID); - waitUntilLauncherObjectGone(TASKBAR_RES_ID); - waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); - - return waitForFallbackLauncherObject(OVERVIEW_RES_ID); + waitForSystemLauncherObject(SPLIT_PLACEHOLDER_RES_ID); + return waitForSystemLauncherObject(OVERVIEW_RES_ID); } case LAUNCHED_APP: { waitUntilLauncherObjectGone(WORKSPACE_RES_ID); waitUntilLauncherObjectGone(APPS_RES_ID); - waitUntilLauncherObjectGone(OVERVIEW_RES_ID); waitUntilLauncherObjectGone(WIDGETS_RES_ID); - waitUntilLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); + waitUntilSystemLauncherObjectGone(OVERVIEW_RES_ID); + waitUntilSystemLauncherObjectGone(SPLIT_PLACEHOLDER_RES_ID); if (mIgnoreTaskbarVisibility) { return null; } - if (isTablet() && !isFallbackOverview()) { - waitForLauncherObject(TASKBAR_RES_ID); + + if (isTablet()) { + waitForSystemLauncherObject(TASKBAR_RES_ID); } else { - waitUntilLauncherObjectGone(TASKBAR_RES_ID); + waitUntilSystemLauncherObjectGone(TASKBAR_RES_ID); } return null; } @@ -957,14 +973,9 @@ public final class LauncherInstrumentation { checkForAnomaly(false, true); final Point displaySize = getRealDisplaySize(); - // The swipe up to home gesture starts from inside the launcher when the user is - // already home. Otherwise, the gesture can start inside the launcher process if the - // taskbar is visible. - boolean gestureStartFromLauncher = isTablet() - ? !isLauncher3() - || hasLauncherObject(WORKSPACE_RES_ID) - || hasLauncherObject(TASKBAR_RES_ID) - : isLauncherVisible(); + + boolean gestureStartFromLauncher = + isTablet() ? !isLauncher3() : isLauncherVisible(); // CLose floating views before going back to home. swipeUpToCloseFloatingView(gestureStartFromLauncher); @@ -997,7 +1008,7 @@ public final class LauncherInstrumentation { NORMAL_STATE_ORDINAL, !hasLauncherObject(WORKSPACE_RES_ID) && (hasLauncherObject(APPS_RES_ID) - || hasLauncherObject(OVERVIEW_RES_ID)), + || hasSystemLauncherObject(OVERVIEW_RES_ID)), action); } try (LauncherInstrumentation.Closable c1 = addContextLayer( @@ -1053,7 +1064,8 @@ public final class LauncherInstrumentation { boolean isLauncherContainerVisible() { final String[] containerResources = {WORKSPACE_RES_ID, OVERVIEW_RES_ID, APPS_RES_ID}; - return Arrays.stream(containerResources).anyMatch(r -> hasLauncherObject(r)); + return Arrays.stream(containerResources).anyMatch( + r -> r.equals(OVERVIEW_RES_ID) ? hasSystemLauncherObject(r) : hasLauncherObject(r)); } /** @@ -1136,6 +1148,14 @@ public final class LauncherInstrumentation { waitUntilGoneBySelector(getOverviewObjectSelector(resId)); } + void waitUntilSystemLauncherObjectGone(String resId) { + if (is3PLauncher()) { + waitUntilOverviewObjectGone(resId); + } else { + waitUntilLauncherObjectGone(resId); + } + } + void waitUntilLauncherObjectGone(BySelector selector) { waitUntilGoneBySelector(makeLauncherSelector(selector)); } @@ -1266,6 +1286,11 @@ public final class LauncherInstrumentation { return mDevice.hasObject(getLauncherObjectSelector(resId)); } + private boolean hasSystemLauncherObject(String resId) { + return mDevice.hasObject(is3PLauncher() ? getOverviewObjectSelector(resId) + : getLauncherObjectSelector(resId)); + } + boolean hasLauncherObject(BySelector selector) { return mDevice.hasObject(makeLauncherSelector(selector)); } @@ -1284,6 +1309,12 @@ public final class LauncherInstrumentation { return waitForObjectBySelector(getLauncherObjectSelector(resName)); } + @NonNull + UiObject2 waitForSystemLauncherObject(String resName) { + return is3PLauncher() ? waitForOverviewObject(resName) + : waitForLauncherObject(resName); + } + @NonNull UiObject2 waitForLauncherObject(BySelector selector) { return waitForObjectBySelector(makeLauncherSelector(selector)); @@ -1294,11 +1325,6 @@ public final class LauncherInstrumentation { return tryWaitForObjectBySelector(makeLauncherSelector(selector), timeout); } - @NonNull - UiObject2 waitForFallbackLauncherObject(String resName) { - return waitForObjectBySelector(getOverviewObjectSelector(resName)); - } - @NonNull UiObject2 waitForAndroidObject(String resId) { final UiObject2 object = TestHelpers.wait( @@ -1336,7 +1362,7 @@ public final class LauncherInstrumentation { return mDevice.getLauncherPackageName(); } - boolean isFallbackOverview() { + boolean is3PLauncher() { return !getOverviewPackageName().equals(getLauncherPackageName()); } diff --git a/tests/tapl/com/android/launcher3/tapl/Taskbar.java b/tests/tapl/com/android/launcher3/tapl/Taskbar.java index 0f9d5f52c7..6ca7f4bf79 100644 --- a/tests/tapl/com/android/launcher3/tapl/Taskbar.java +++ b/tests/tapl/com/android/launcher3/tapl/Taskbar.java @@ -52,7 +52,7 @@ public final class Taskbar { try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "want to get a taskbar icon")) { return new TaskbarAppIcon(mLauncher, mLauncher.waitForObjectInContainer( - mLauncher.waitForLauncherObject(TASKBAR_RES_ID), + mLauncher.waitForSystemLauncherObject(TASKBAR_RES_ID), AppIcon.getAppIconSelector(appName, mLauncher))); } } @@ -68,7 +68,7 @@ public final class Taskbar { try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "want to hide the taskbar"); LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) { - mLauncher.waitForLauncherObject(TASKBAR_RES_ID); + mLauncher.waitForSystemLauncherObject(TASKBAR_RES_ID); final long downTime = SystemClock.uptimeMillis(); Point stashTarget = new Point( @@ -79,7 +79,7 @@ public final class Taskbar { LauncherInstrumentation.log("hideTaskbar: sent down"); try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer("pressed down")) { - mLauncher.waitUntilLauncherObjectGone("taskbar_view"); + mLauncher.waitUntilSystemLauncherObjectGone(TASKBAR_RES_ID); mLauncher.sendPointer(downTime, downTime, MotionEvent.ACTION_UP, stashTarget, LauncherInstrumentation.GestureScope.INSIDE); } @@ -97,7 +97,8 @@ public final class Taskbar { LauncherInstrumentation.Closable e = mLauncher.eventsCheck()) { mLauncher.clickLauncherObject(mLauncher.waitForObjectInContainer( - mLauncher.waitForLauncherObject(TASKBAR_RES_ID), getAllAppsButtonSelector())); + mLauncher.waitForSystemLauncherObject(TASKBAR_RES_ID), + getAllAppsButtonSelector())); return new AllAppsFromTaskbar(mLauncher); } @@ -108,7 +109,7 @@ public final class Taskbar { try (LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "want to get all taskbar icons")) { return mLauncher.waitForObjectsInContainer( - mLauncher.waitForLauncherObject(TASKBAR_RES_ID), + mLauncher.waitForSystemLauncherObject(TASKBAR_RES_ID), AppIcon.getAnyAppIconSelector()) .stream() .map(UiObject2::getText) From 81f5cee2cb457fd14f24474be788127c0a16d559 Mon Sep 17 00:00:00 2001 From: Luca Zuccarini Date: Tue, 11 Oct 2022 13:02:09 +0000 Subject: [PATCH 192/429] Fix IME sync flicker with 3-button navigation. With keyboard sync, the dismissal is handled by the animator. Calling hideKeyboard() on top of that causes the two signals to conflict with each other, resulting in the visible flicker and extra delayed hiding animation. Fixes: 251185052 Test: manual, see videos in the bug Change-Id: Ic12ad304ef9e4b6a51279ce18d6c09ba93bd59be --- src/com/android/launcher3/Launcher.java | 7 +++---- .../allapps/AllAppsTransitionController.java | 13 ++++++++++--- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index c73e07794f..ab7f6226c9 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -482,6 +482,9 @@ public class Launcher extends StatefulActivity mOnboardingPrefs = createOnboardingPrefs(mSharedPrefs); + // TODO: move the SearchConfig to SearchState when new LauncherState is created. + mBaseSearchConfig = new BaseSearchConfig(); + mAppWidgetManager = new WidgetManagerHelper(this); mAppWidgetHolder = createAppWidgetHolder(); mAppWidgetHolder.startListening(); @@ -548,9 +551,6 @@ public class Launcher extends StatefulActivity getWindow().setSoftInputMode(LayoutParams.SOFT_INPUT_ADJUST_NOTHING); } setTitle(R.string.home_screen); - - // TODO: move the SearchConfig to SearchState when new LauncherState is created. - mBaseSearchConfig = new BaseSearchConfig(); } protected LauncherOverlayManager getDefaultOverlay() { @@ -1598,7 +1598,6 @@ public class Launcher extends StatefulActivity && AbstractFloatingView.getTopOpenView(this) == null; boolean isActionMain = Intent.ACTION_MAIN.equals(intent.getAction()); boolean internalStateHandled = ACTIVITY_TRACKER.handleNewIntent(this); - hideKeyboard(); if (isActionMain) { if (!internalStateHandled) { diff --git a/src/com/android/launcher3/allapps/AllAppsTransitionController.java b/src/com/android/launcher3/allapps/AllAppsTransitionController.java index fa2c6e93c0..9930abeb12 100644 --- a/src/com/android/launcher3/allapps/AllAppsTransitionController.java +++ b/src/com/android/launcher3/allapps/AllAppsTransitionController.java @@ -141,6 +141,9 @@ public class AllAppsTransitionController private final Launcher mLauncher; private boolean mIsVerticalLayout; + // Whether this class should take care of closing the keyboard. + private boolean mShouldControlKeyboard; + // Animation in this class is controlled by a single variable {@link mProgress}. // Visually, it represents top y coordinate of the all apps container if multiplied with // {@link mShiftRange}. @@ -238,7 +241,7 @@ public class AllAppsTransitionController StateAnimationConfig config, PendingAnimation builder) { if (mLauncher.isInState(ALL_APPS) && !ALL_APPS.equals(toState)) { // For atomic animations, we close the keyboard immediately. - if (!config.userControlled && !mLauncher.getSearchConfig().isKeyboardSyncEnabled()) { + if (!config.userControlled && mShouldControlKeyboard) { mLauncher.getAppsView().getSearchUiManager().getEditText().hideKeyboard(); } @@ -252,7 +255,7 @@ public class AllAppsTransitionController // the keyboard open and then changes their mind and swipes back up, we want the // keyboard to remain open. However an onCancel signal is sent to the listeners // (success = false), so we need to check for that. - if (config.userControlled && success) { + if (config.userControlled && success && mShouldControlKeyboard) { mLauncher.getAppsView().getSearchUiManager().getEditText().hideKeyboard(); } }); @@ -317,6 +320,8 @@ public class AllAppsTransitionController mAppsViewAlpha.setUpdateVisibility(true); mAppsViewTranslationY = new MultiPropertyFactory<>( mAppsView, VIEW_TRANSLATE_Y, APPS_VIEW_INDEX_COUNT, Float::sum); + + mShouldControlKeyboard = !mLauncher.getSearchConfig().isKeyboardSyncEnabled(); } /** @@ -333,7 +338,9 @@ public class AllAppsTransitionController private void onProgressAnimationEnd() { if (Float.compare(mProgress, 1f) == 0) { mAppsView.reset(false /* animate */); - mLauncher.getAppsView().getSearchUiManager().getEditText().hideKeyboard(); + if (mShouldControlKeyboard) { + mLauncher.getAppsView().getSearchUiManager().getEditText().hideKeyboard(); + } } } } From 893615f241a036b3a6097521585262e4fe8f5cc5 Mon Sep 17 00:00:00 2001 From: Sebastian Franco Date: Tue, 8 Nov 2022 10:40:59 -0800 Subject: [PATCH 193/429] Reorder widgets no longer overlaps when no space is available In the previous refactor I got confused between findNearestVacantArea and findNearestArea thinking the later did the former. So it ignored the occupied spaces and treat it as a solution. Changed the names to prevent further confusion. Fix: 258023561 Test: manual, need to add this case to ReorderWidgets Change-Id: I04b262ecce168d5c93a9d66ef62d5b0e148e38b6 --- src/com/android/launcher3/CellLayout.java | 51 ++++++++++++------- src/com/android/launcher3/Workspace.java | 3 +- .../launcher3/folder/FolderPagedView.java | 2 +- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index de2a1f91ed..e500e59369 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -1651,8 +1651,19 @@ public class CellLayout extends ViewGroup { } } - private ItemConfiguration findConfigurationNoShuffle(int pixelX, int pixelY, int minSpanX, int minSpanY, - int spanX, int spanY, View dragView, ItemConfiguration solution) { + /** + * Returns a "reorder" where we simply drop the item in the closest empty space, without moving + * any other item in the way. + * + * @param pixelX X coordinate in pixels in the screen + * @param pixelY Y coordinate in pixels in the screen + * @param spanX horizontal cell span + * @param spanY vertical cell span + * @return the configuration that represents the found reorder + */ + private ItemConfiguration closestEmptySpaceReorder(int pixelX, int pixelY, int minSpanX, + int minSpanY, int spanX, int spanY) { + ItemConfiguration solution = new ItemConfiguration(); int[] result = new int[2]; int[] resultSpan = new int[2]; findNearestVacantArea(pixelX, pixelY, minSpanX, minSpanY, spanX, spanY, result, @@ -1697,7 +1708,7 @@ public class CellLayout extends ViewGroup { boolean isNearestDropLocationOccupied(int pixelX, int pixelY, int spanX, int spanY, View dragView, int[] result) { - result = findNearestArea(pixelX, pixelY, spanX, spanY, result); + result = findNearestAreaIgnoreOccupied(pixelX, pixelY, spanX, spanY, result); getViewsIntersectingRegion(result[0], result[1], spanX, spanY, dragView, null, mIntersectingViews); return !mIntersectingViews.isEmpty(); @@ -2247,7 +2258,8 @@ public class CellLayout extends ViewGroup { //TODO(adamcohen) b/151776141 use the items visual center for the direction vector int[] targetDestination = new int[2]; - findNearestArea(dragViewCenterX, dragViewCenterY, spanX, spanY, targetDestination); + findNearestAreaIgnoreOccupied(dragViewCenterX, dragViewCenterY, spanX, spanY, + targetDestination); Rect dragRect = new Rect(); cellToRect(targetDestination[0], targetDestination[1], spanX, spanY, dragRect); dragRect.offset(dragViewCenterX - dragRect.centerX(), dragViewCenterY - dragRect.centerY()); @@ -2400,7 +2412,7 @@ public class CellLayout extends ViewGroup { // We find the nearest cell into which we would place the dragged item, assuming there's // nothing in its way. int result[] = new int[2]; - result = findNearestArea(pixelX, pixelY, spanX, spanY, result); + result = findNearestAreaIgnoreOccupied(pixelX, pixelY, spanX, spanY, result); boolean success; // First we try the exact nearest position of the item being dragged, @@ -2445,19 +2457,21 @@ public class CellLayout extends ViewGroup { } /** - * Returns a "reorder" where we simply drop the item in the closest empty space, without moving - * any other item in the way. + * Returns a "reorder" if there is empty space without rearranging anything. * * @param pixelX X coordinate in pixels in the screen * @param pixelY Y coordinate in pixels in the screen * @param spanX horizontal cell span * @param spanY vertical cell span + * @param dragView view being dragged in reorder * @return the configuration that represents the found reorder */ - public ItemConfiguration closestEmptySpaceReorder(int pixelX, int pixelY, int spanX, - int spanY) { + public ItemConfiguration dropInPlaceSolution(int pixelX, int pixelY, int spanX, + int spanY, View dragView) { int[] result = new int[2]; - result = findNearestArea(pixelX, pixelY, spanX, spanY, result); + if (isNearestDropLocationOccupied(pixelX, pixelY, spanX, spanY, dragView, result)) { + result[0] = result[1] = -1; + } ItemConfiguration solution = new ItemConfiguration(); copyCurrentStateToSolution(solution, false); solution.isSolution = result[0] != -1; @@ -2490,25 +2504,25 @@ public class CellLayout extends ViewGroup { int spanX, int spanY, View dragView) { getDirectionVectorForDrop(pixelX, pixelY, spanX, spanY, dragView, mDirectionVector); - ItemConfiguration closestSpaceSolution = closestEmptySpaceReorder(pixelX, pixelY, spanX, - spanY); + ItemConfiguration dropInPlaceSolution = dropInPlaceSolution(pixelX, pixelY, spanX, spanY, + dragView); // Find a solution involving pushing / displacing any items in the way ItemConfiguration swapSolution = findReorderSolution(pixelX, pixelY, minSpanX, minSpanY, spanX, spanY, mDirectionVector, dragView, true, new ItemConfiguration()); // We attempt the approach which doesn't shuffle views at all - ItemConfiguration noShuffleSolution = findConfigurationNoShuffle(pixelX, pixelY, minSpanX, - minSpanY, spanX, spanY, dragView, new ItemConfiguration()); + ItemConfiguration closestSpaceSolution = closestEmptySpaceReorder(pixelX, pixelY, minSpanX, + minSpanY, spanX, spanY); // If the reorder solution requires resizing (shrinking) the item being dropped, we instead // favor a solution in which the item is not resized, but - if (swapSolution.isSolution && swapSolution.area() >= noShuffleSolution.area()) { + if (swapSolution.isSolution && swapSolution.area() >= closestSpaceSolution.area()) { return swapSolution; - } else if (noShuffleSolution.isSolution) { - return noShuffleSolution; } else if (closestSpaceSolution.isSolution) { return closestSpaceSolution; + } else if (dropInPlaceSolution.isSolution) { + return dropInPlaceSolution; } return null; } @@ -2665,7 +2679,8 @@ public class CellLayout extends ViewGroup { * @return The X, Y cell of a vacant area that can contain this object, * nearest the requested location. */ - public int[] findNearestArea(int pixelX, int pixelY, int spanX, int spanY, int[] result) { + public int[] findNearestAreaIgnoreOccupied(int pixelX, int pixelY, int spanX, int spanY, + int[] result) { return findNearestArea(pixelX, pixelY, spanX, spanY, spanX, spanY, true, result, null); } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 27e1ba143b..b31db82ab3 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -2615,7 +2615,6 @@ public class Workspace extends PagedView setDragMode(DRAG_MODE_REORDER); } - boolean resize = resultSpan[0] != spanX || resultSpan[1] != spanY; mDragTargetLayout.visualizeDropLocation(mTargetCell[0], mTargetCell[1], resultSpan[0], resultSpan[1], dragObject); } @@ -2972,7 +2971,7 @@ public class Workspace extends PagedView */ @Thunk int[] findNearestArea(int pixelX, int pixelY, int spanX, int spanY, CellLayout layout, int[] recycle) { - return layout.findNearestArea( + return layout.findNearestAreaIgnoreOccupied( pixelX, pixelY, spanX, spanY, recycle); } diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java index efd511de37..b87ab17cb3 100644 --- a/src/com/android/launcher3/folder/FolderPagedView.java +++ b/src/com/android/launcher3/folder/FolderPagedView.java @@ -365,7 +365,7 @@ public class FolderPagedView extends PagedView implements Cli public int findNearestArea(int pixelX, int pixelY) { int pageIndex = getNextPage(); CellLayout page = getPageAt(pageIndex); - page.findNearestArea(pixelX, pixelY, 1, 1, sTmpArray); + page.findNearestAreaIgnoreOccupied(pixelX, pixelY, 1, 1, sTmpArray); if (mFolder.isLayoutRtl()) { sTmpArray[0] = page.getCountX() - sTmpArray[0] - 1; } From 4f56f0a10b051eb0414512b3f1301980678b6b8e Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 8 Nov 2022 11:19:05 -0800 Subject: [PATCH 194/429] Add dark theme bg for transient taskbar. Bug: 256052691 Test: enable dark theme, view dark taskbar disable dark theme, view light taskbar Change-Id: Icf8b946fd68804a904493336063704a6584d5f0e --- .../transient_taskbar_background.xml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 res/color-night-v31/transient_taskbar_background.xml diff --git a/res/color-night-v31/transient_taskbar_background.xml b/res/color-night-v31/transient_taskbar_background.xml new file mode 100644 index 0000000000..40f6494933 --- /dev/null +++ b/res/color-night-v31/transient_taskbar_background.xml @@ -0,0 +1,19 @@ + + + + + + From 29e71bdd7257cb4919762e10c7915da4d2ae8752 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Mon, 31 Oct 2022 14:13:44 -0700 Subject: [PATCH 195/429] Improve Split portrait gesture animation * Crop out taskbar from bottom thumbnail for vertical split * TODO: Need to re-calculate thumbnail sizes if taskbar is stashed. There's also a very slight rounding error somewhere even in the unstashed case that needs to be revisited Bug: 219411750 Test: Start gesture animation in split in potrait Change-Id: I35f2415e13af7467e0735ac8865cee0e3e3d27f8 --- .../quickstep/util/TaskViewSimulator.java | 2 +- .../quickstep/views/TaskThumbnailView.java | 4 +-- .../quickstep/FullscreenDrawParamsTest.kt | 4 +-- .../touch/PortraitPagedViewHandler.java | 35 ++++++++++++------- 4 files changed, 28 insertions(+), 17 deletions(-) diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java index 5c37da16b5..b476c12a51 100644 --- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java +++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java @@ -322,7 +322,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { boolean isRtlEnabled = !mIsRecentsRtl; mPositionHelper.updateThumbnailMatrix( mThumbnailPosition, mThumbnailData, mTaskRect.width(), mTaskRect.height(), - mDp.widthPx, mDp.taskbarSize, mDp.isTablet, + mDp.widthPx, mDp.heightPx, mDp.taskbarSize, mDp.isTablet, mOrientationState.getRecentsActivityRotation(), isRtlEnabled); mPositionHelper.getMatrix().invert(mInversePositionMatrix); if (DEBUG) { diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java index 6792dc5445..904c944c1a 100644 --- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java +++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java @@ -473,8 +473,8 @@ public class TaskThumbnailView extends View { boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; DeviceProfile dp = mActivity.getDeviceProfile(); mPreviewPositionHelper.updateThumbnailMatrix(mPreviewRect, mThumbnailData, - getMeasuredWidth(), getMeasuredHeight(), dp.widthPx, dp.taskbarSize, - dp.isTablet, currentRotation, isRtl); + getMeasuredWidth(), getMeasuredHeight(), dp.widthPx, dp.heightPx, + dp.taskbarSize, dp.isTablet, currentRotation, isRtl); mBitmapShader.setLocalMatrix(mPreviewPositionHelper.getMatrix()); mPaint.setShader(mBitmapShader); diff --git a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt index 478535051c..963da2793d 100644 --- a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt +++ b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt @@ -57,7 +57,7 @@ class FullscreenDrawParamsTest : DeviceProfileBaseTest() { val isRtl = false mPreviewPositionHelper.updateThumbnailMatrix(previewRect, mThumbnailData, canvasWidth, - canvasHeight, dp.widthPx, dp.taskbarSize, dp.isTablet, currentRotation, + canvasHeight, dp.widthPx, dp.heightPx, dp.taskbarSize, dp.isTablet, currentRotation, isRtl) params.setProgress(/* fullscreenProgress= */ 1.0f, /* parentScale= */ 1.0f, /* taskViewScale= */ 1.0f, /* previewWidth= */ 0, dp, mPreviewPositionHelper) @@ -78,7 +78,7 @@ class FullscreenDrawParamsTest : DeviceProfileBaseTest() { val isRtl = false mPreviewPositionHelper.updateThumbnailMatrix(previewRect, mThumbnailData, canvasWidth, - canvasHeight, dp.widthPx, dp.taskbarSize, dp.isTablet, currentRotation, + canvasHeight, dp.widthPx, dp.heightPx, dp.taskbarSize, dp.isTablet, currentRotation, isRtl) params.setProgress(/* fullscreenProgress= */ 1.0f, /* parentScale= */ 1.0f, /* taskViewScale= */ 1.0f, /* previewWidth= */ 0, dp, mPreviewPositionHelper) diff --git a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java index af689dc3a3..78e17d835d 100644 --- a/src/com/android/launcher3/touch/PortraitPagedViewHandler.java +++ b/src/com/android/launcher3/touch/PortraitPagedViewHandler.java @@ -585,7 +585,6 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { @Override public void setSplitTaskSwipeRect(DeviceProfile dp, Rect outRect, SplitBounds splitInfo, int desiredStagePosition) { - boolean isLandscape = dp.isLandscape; float topLeftTaskPercent = splitInfo.appsStackedVertically ? splitInfo.topTaskPercent : splitInfo.leftTaskPercent; @@ -593,18 +592,24 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { ? splitInfo.dividerHeightPercent : splitInfo.dividerWidthPercent; + int deviceHeightWithoutTaskbar = dp.availableHeightPx - dp.taskbarSize; + float scale = (float) outRect.height() / deviceHeightWithoutTaskbar; + float topTaskHeight = dp.availableHeightPx * topLeftTaskPercent; + float scaledTopTaskHeight = topTaskHeight * scale; + float dividerHeight = dp.availableHeightPx * dividerBarPercent; + float scaledDividerHeight = dividerHeight * scale; + if (desiredStagePosition == SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT) { - if (isLandscape) { - outRect.right = outRect.left + Math.round(outRect.width() * topLeftTaskPercent); + if (splitInfo.appsStackedVertically) { + outRect.bottom = Math.round(outRect.top + scaledTopTaskHeight); } else { - outRect.bottom = outRect.top + Math.round(outRect.height() * topLeftTaskPercent); + outRect.right = outRect.left + Math.round(outRect.width() * topLeftTaskPercent); } } else { - if (isLandscape) { - outRect.left += Math.round(outRect.width() - * (topLeftTaskPercent + dividerBarPercent)); + if (splitInfo.appsStackedVertically) { + outRect.top += Math.round(scaledTopTaskHeight + scaledDividerHeight); } else { - outRect.top += Math.round(outRect.height() + outRect.left += Math.round(outRect.width() * (topLeftTaskPercent + dividerBarPercent)); } } @@ -617,7 +622,7 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { int spaceAboveSnapshot = dp.overviewTaskThumbnailTopMarginPx; int totalThumbnailHeight = parentHeight - spaceAboveSnapshot; int dividerBar = Math.round(splitBoundsConfig.appsStackedVertically - ? splitBoundsConfig.dividerHeightPercent * totalThumbnailHeight + ? splitBoundsConfig.dividerHeightPercent * dp.availableHeightPx : splitBoundsConfig.dividerWidthPercent * parentWidth); int primarySnapshotHeight; int primarySnapshotWidth; @@ -641,12 +646,18 @@ public class PortraitPagedViewHandler implements PagedOrientationHandler { } secondarySnapshot.setTranslationY(spaceAboveSnapshot); } else { + int deviceHeightWithoutTaskbar = dp.availableHeightPx - dp.taskbarSize; + float scale = (float) totalThumbnailHeight / deviceHeightWithoutTaskbar; + float topTaskHeight = dp.availableHeightPx * taskPercent; + float finalDividerHeight = dividerBar * scale; + float scaledTopTaskHeight = topTaskHeight * scale; primarySnapshotWidth = parentWidth; - primarySnapshotHeight = Math.round(totalThumbnailHeight * taskPercent); + primarySnapshotHeight = Math.round(scaledTopTaskHeight); secondarySnapshotWidth = parentWidth; - secondarySnapshotHeight = totalThumbnailHeight - primarySnapshotHeight - dividerBar; - int translationY = primarySnapshotHeight + spaceAboveSnapshot + dividerBar; + secondarySnapshotHeight = Math.round(totalThumbnailHeight - primarySnapshotHeight + - finalDividerHeight); + float translationY = primarySnapshotHeight + spaceAboveSnapshot + finalDividerHeight; secondarySnapshot.setTranslationY(translationY); FrameLayout.LayoutParams primaryParams = From 3153cd9b971fba459ec952962cbcfa0209905d23 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 8 Nov 2022 11:42:28 -0800 Subject: [PATCH 196/429] Proposal to move Developer Options to top of Home settings if studio build. - Increases developer efficiency by avoiding the need to scroll Bug: 258263867 Test: manual Change-Id: I6cb46fdd12b51f8c45017f823dd4b2458e21fc72 --- src/com/android/launcher3/settings/SettingsActivity.java | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java index 49d27b7ed4..70956a35ac 100644 --- a/src/com/android/launcher3/settings/SettingsActivity.java +++ b/src/com/android/launcher3/settings/SettingsActivity.java @@ -18,6 +18,7 @@ package com.android.launcher3.settings; import static androidx.core.view.accessibility.AccessibilityNodeInfoCompat.ACTION_ACCESSIBILITY_FOCUS; +import static com.android.launcher3.config.FeatureFlags.IS_STUDIO_BUILD; import static com.android.launcher3.states.RotationHelper.ALLOW_ROTATION_PREFERENCE_KEY; import android.content.Intent; @@ -207,7 +208,11 @@ public class SettingsActivity extends FragmentActivity PreferenceScreen screen = getPreferenceScreen(); for (int i = screen.getPreferenceCount() - 1; i >= 0; i--) { Preference preference = screen.getPreference(i); - if (!initPreference(preference)) { + if (initPreference(preference)) { + if (IS_STUDIO_BUILD && preference == mDeveloperOptionPref) { + preference.setOrder(0); + } + } else { screen.removePreference(preference); } } From e7011d2b876770dcefde509e8775bb65b6d1d8e1 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 8 Nov 2022 21:56:52 +0000 Subject: [PATCH 197/429] Revert "Add TaskbarModeSwitchRule to test both transient/persistent taskbar." This reverts commit d5a6b5f688f45f3f98cb22170f574495214d3f4f. Reason for revert: Breaks tests due to "SharedPreferences in credential encrypted storage are not available until after user is unlocked" Bug: 258256906 Change-Id: I1de69249685f9d2e71183357cf3eda8d443c7d97 --- quickstep/Android.bp | 1 - .../taskbar/TaskbarActivityContext.java | 19 +- .../taskbar/TaskbarStashController.java | 20 +-- .../QuickstepTestInformationHandler.java | 19 -- .../quickstep/AbstractQuickStepTest.java | 1 - .../quickstep/NavigationModeSwitchRule.java | 2 +- .../android/quickstep/TaplTestsTaskbar.java | 17 -- .../quickstep/TaskbarModeSwitchRule.java | 162 ------------------ .../testing/shared/TestProtocol.java | 2 - .../launcher3/tapl/LaunchedAppState.java | 4 - .../tapl/LauncherInstrumentation.java | 7 - 11 files changed, 7 insertions(+), 247 deletions(-) delete mode 100644 quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java diff --git a/quickstep/Android.bp b/quickstep/Android.bp index f5a8253563..7292c4495b 100644 --- a/quickstep/Android.bp +++ b/quickstep/Android.bp @@ -38,7 +38,6 @@ filegroup { name: "launcher3-quickstep-oop-tests-src", path: "tests", srcs: [ - "tests/src/com/android/quickstep/TaskbarModeSwitchRule.java", "tests/src/com/android/quickstep/NavigationModeSwitchRule.java", "tests/src/com/android/quickstep/AbstractQuickStepTest.java", "tests/src/com/android/quickstep/TaplTestsQuickstep.java", diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index d0256c5caf..fad9ff490c 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -23,7 +23,6 @@ import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE; -import static com.android.launcher3.Utilities.IS_RUNNING_IN_TEST_HARNESS; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN; import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING; import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_FULLSCREEN; @@ -305,8 +304,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { int windowFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_SLIPPERY | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH; - if (DisplayController.isTransientTaskbar(this) - && !IS_RUNNING_IN_TEST_HARNESS) { + if (DisplayController.isTransientTaskbar(this)) { windowFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; } @@ -859,26 +857,13 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mControllers.taskbarStashController.enableManualStashingDuringTests(enableManualStashing); } - /** - * Enables the auto timeout for taskbar stashing. This method should only be used for taskbar - * testing. - */ - @VisibleForTesting - public void enableBlockingTimeoutDuringTests(boolean enableBlockingTimeout) { - mControllers.taskbarStashController.enableBlockingTimeoutDuringTests(enableBlockingTimeout); - } - /** * Unstashes the Taskbar if it is stashed. This method should only be used to unstash the * taskbar at the end of a test. */ @VisibleForTesting public void unstashTaskbarIfStashed() { - if (DisplayController.isTransientTaskbar(this)) { - mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(false); - } else { - mControllers.taskbarStashController.onLongPressToUnstashTaskbar(); - } + mControllers.taskbarStashController.onLongPressToUnstashTaskbar(); } protected boolean isUserSetupComplete() { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index b53e9c56cd..72ae1d1c31 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -37,7 +37,6 @@ import android.view.View; import android.view.ViewConfiguration; import androidx.annotation.NonNull; -import androidx.annotation.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor; import com.android.launcher3.Alarm; @@ -170,7 +169,6 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba private boolean mEnableManualStashingDuringTests = false; private final Alarm mTimeoutAlarm = new Alarm(); - private boolean mEnableBlockingTimeoutDuringTests = false; // Evaluate whether the handle should be stashed private final StatePropertyHolder mStatePropertyHolder = new StatePropertyHolder( @@ -269,20 +267,10 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba * Enables support for manual stashing. This should only be used to add this functionality * to Launcher specific tests. */ - @VisibleForTesting public void enableManualStashingDuringTests(boolean enableManualStashing) { mEnableManualStashingDuringTests = enableManualStashing; } - /** - * Enables the auto timeout for taskbar stashing. This method should only be used for taskbar - * testing. - */ - @VisibleForTesting - public void enableBlockingTimeoutDuringTests(boolean enableBlockingTimeout) { - mEnableBlockingTimeoutDuringTests = enableBlockingTimeout; - } - /** * Sets the flag indicating setup UI is visible */ @@ -858,12 +846,12 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba * Attempts to start timer to auto hide the taskbar based on time. */ public void tryStartTaskbarTimeout() { - if (!DisplayController.isTransientTaskbar(mActivity) - || mIsStashed - || mEnableBlockingTimeoutDuringTests) { + if (!DisplayController.isTransientTaskbar(mActivity)) { + return; + } + if (mIsStashed) { return; } - cancelTimeoutIfExists(); mTimeoutAlarm.setOnAlarmListener(this::onTaskbarTimeout); diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java index 177ecf54a5..9621ce6eba 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -120,18 +120,6 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { .getCurrentActivityContext() .getTaskbarAllAppsTopPadding()); } - - case TestProtocol.REQUEST_ENABLE_BLOCK_TIMEOUT: - runOnTISBinder(tisBinder -> { - enableBlockingTimeout(tisBinder, true); - }); - return response; - - case TestProtocol.REQUEST_DISABLE_BLOCK_TIMEOUT: - runOnTISBinder(tisBinder -> { - enableBlockingTimeout(tisBinder, false); - }); - return response; } return super.call(method, arg, extras); @@ -161,13 +149,6 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { enable); } - private void enableBlockingTimeout( - TouchInteractionService.TISBinder tisBinder, boolean enable) { - // Allow null-pointer to catch illegal states. - tisBinder.getTaskbarManager().getCurrentActivityContext().enableBlockingTimeoutDuringTests( - enable); - } - /** * Runs the given command on the UI thread, after ensuring we are connected to * TouchInteractionService. diff --git a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java index 2c5825fd0b..e2774c003d 100644 --- a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java +++ b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java @@ -39,7 +39,6 @@ public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest { protected TestRule getRulesInsideActivityMonitor() { return RuleChain. outerRule(new NavigationModeSwitchRule(mLauncher)). - around(new TaskbarModeSwitchRule(mLauncher)). around(super.getRulesInsideActivityMonitor()); } diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java index eded1c961f..e5e2cf3337 100644 --- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java +++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java @@ -51,7 +51,7 @@ import java.util.concurrent.TimeUnit; /** * Test rule that allows executing a test with Quickstep on and then Quickstep off. - * The test should be annotated with @NavigationModeSwitch. + * The test should be annotated with @QuickstepOnOff. */ public class NavigationModeSwitchRule implements TestRule { diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java index 0b8bc10fec..9337cb55bc 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java @@ -17,8 +17,6 @@ package com.android.quickstep; import static androidx.test.InstrumentationRegistry.getInstrumentation; -import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT; - import static junit.framework.TestCase.assertEquals; import android.content.Intent; @@ -29,7 +27,6 @@ import androidx.test.runner.AndroidJUnit4; import com.android.launcher3.tapl.Taskbar; import com.android.launcher3.ui.TaplTestsLauncher3; import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord; -import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch; import org.junit.After; import org.junit.Assume; @@ -56,25 +53,21 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { TaplTestsLauncher3.initialize(this); startAppFast(CALCULATOR_APP_PACKAGE); - mLauncher.enableBlockTimeout(true); mLauncher.showTaskbarIfHidden(); } @After public void tearDown() { mLauncher.useDefaultWorkspaceLayoutOnReload(); - mLauncher.enableBlockTimeout(false); } @Test - @TaskbarModeSwitch(mode = PERSISTENT) public void testHideShowTaskbar() { getTaskbar().hide(); mLauncher.getLaunchedAppState().showTaskbar(); } @Test - @TaskbarModeSwitch(mode = PERSISTENT) public void testHideTaskbarPersistsOnRecreate() { getTaskbar().hide(); mLauncher.recreateTaskbar(); @@ -82,19 +75,16 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { } @Test - @TaskbarModeSwitch public void testLaunchApp() throws Exception { getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE); } @Test - @TaskbarModeSwitch public void testOpenMenu() throws Exception { getTaskbar().getAppIcon(TEST_APP_NAME).openMenu(); } @Test - @TaskbarModeSwitch public void testLaunchShortcut() throws Exception { getTaskbar().getAppIcon(TEST_APP_NAME) .openDeepShortcutMenu() @@ -105,7 +95,6 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { @Test @ScreenRecord // b/231615831 @PortraitLandscape - @TaskbarModeSwitch public void testLaunchAppInSplitscreen() throws Exception { getTaskbar().getAppIcon(TEST_APP_NAME).dragToSplitscreen( TEST_APP_PACKAGE, CALCULATOR_APP_PACKAGE); @@ -114,7 +103,6 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { @Test @ScreenRecord // b/231615831 @PortraitLandscape - @TaskbarModeSwitch public void testLaunchShortcutInSplitscreen() throws Exception { getTaskbar().getAppIcon(TEST_APP_NAME) .openDeepShortcutMenu() @@ -123,19 +111,16 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { } @Test - @TaskbarModeSwitch public void testLaunchApp_FromTaskbarAllApps() throws Exception { getTaskbar().openAllApps().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE); } @Test - @TaskbarModeSwitch public void testOpenMenu_FromTaskbarAllApps() throws Exception { getTaskbar().openAllApps().getAppIcon(TEST_APP_NAME).openMenu(); } @Test - @TaskbarModeSwitch public void testLaunchShortcut_FromTaskbarAllApps() throws Exception { getTaskbar().openAllApps() .getAppIcon(TEST_APP_NAME) @@ -147,7 +132,6 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { @Test @ScreenRecord // b/231615831 @PortraitLandscape - @TaskbarModeSwitch public void testLaunchAppInSplitscreen_FromTaskbarAllApps() throws Exception { getTaskbar().openAllApps() .getAppIcon(TEST_APP_NAME) @@ -157,7 +141,6 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { @Test @ScreenRecord // b/231615831 @PortraitLandscape - @TaskbarModeSwitch public void testLaunchShortcutInSplitscreen_FromTaskbarAllApps() throws Exception { getTaskbar().openAllApps() .getAppIcon(TEST_APP_NAME) diff --git a/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java deleted file mode 100644 index 8cc812bbb7..0000000000 --- a/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java +++ /dev/null @@ -1,162 +0,0 @@ -/* - * Copyright (C) 2022 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 static androidx.test.InstrumentationRegistry.getInstrumentation; - -import static com.android.quickstep.TaskbarModeSwitchRule.Mode.ALL; -import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT; -import static com.android.quickstep.TaskbarModeSwitchRule.Mode.TRANSIENT; - -import android.content.Context; -import android.util.Log; - -import com.android.launcher3.config.FeatureFlags; -import com.android.launcher3.tapl.LauncherInstrumentation; -import com.android.launcher3.tapl.TestHelpers; -import com.android.launcher3.ui.AbstractLauncherUiTest; -import com.android.launcher3.util.rule.FailureWatcher; - -import org.junit.rules.TestRule; -import org.junit.runner.Description; -import org.junit.runners.model.Statement; - -import java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Test rule that allows executing a test multiple times with different conditions - * ie. with transient taskbar enabled and disabled. - * The test should be annotated with @TaskbarModeSwitch. - */ -public class TaskbarModeSwitchRule implements TestRule { - - static final String TAG = "TaskbarModeSwitchRule"; - - public static final int WAIT_TIME_MS = 10000; - - public enum Mode { - TRANSIENT, PERSISTENT, ALL - } - - // Annotation for tests that need to be run with quickstep enabled and disabled. - @Retention(RetentionPolicy.RUNTIME) - @Target(ElementType.METHOD) - public @interface TaskbarModeSwitch { - Mode mode() default ALL; - } - - private final LauncherInstrumentation mLauncher; - - public TaskbarModeSwitchRule(LauncherInstrumentation launcher) { - mLauncher = launcher; - } - - @Override - public Statement apply(Statement base, Description description) { - if (TestHelpers.isInLauncherProcess() - && description.getAnnotation(TaskbarModeSwitch.class) != null) { - Mode mode = description.getAnnotation(TaskbarModeSwitch.class).mode(); - return new Statement() { - @Override - public void evaluate() throws Throwable { - mLauncher.enableDebugTracing(); - final boolean wasTransientTaskbarMode = isTaskbarTransientMode(); - try { - if (mode == TRANSIENT || mode == ALL) { - evaluateWithTransientTaskbar(); - } - if (mode == PERSISTENT || mode == ALL) { - evaluateWithPersistentTaskbar(); - } - } catch (Throwable e) { - Log.e(TAG, "Error", e); - throw e; - } finally { - Log.d(TAG, "In Finally block"); - setTaskbarMode(mLauncher, wasTransientTaskbarMode, description); - } - } - - private void evaluateWithPersistentTaskbar() throws Throwable { - setTaskbarMode(mLauncher, false, description); - base.evaluate(); - } - - private void evaluateWithTransientTaskbar() throws Throwable { - setTaskbarMode(mLauncher, true, description); - base.evaluate(); - } - }; - } else { - return base; - } - } - - private static void enableTransientTaskbar(LauncherInstrumentation launcher, Context c, - boolean enable, Description description) { - boolean success = c.getSharedPreferences(FeatureFlags.FLAGS_PREF_NAME, Context.MODE_PRIVATE) - .edit() - .putBoolean(FeatureFlags.ENABLE_TRANSIENT_TASKBAR.key, enable) - .commit(); - - if (!success) { - final AssertionError assertionError = new AssertionError( - "Unable to save state to SharedPrefs transientTaskbar=" + enable); - if (description != null) { - FailureWatcher.onError(launcher, description, assertionError); - } - throw assertionError; - } - - FeatureFlags.initialize(c); - } - - private static boolean isTaskbarTransientMode() { - return FeatureFlags.ENABLE_TRANSIENT_TASKBAR.get(); - } - - public static void setTaskbarMode(LauncherInstrumentation launcher, - boolean expectTransientTaskbar, Description description) throws Exception { - - Log.d(TAG, "setTaskbarMode: isTransientTaskbar=" + expectTransientTaskbar + "..."); - - enableTransientTaskbar(launcher, getInstrumentation().getTargetContext(), - expectTransientTaskbar, description); - - launcher.recreateTaskbar(); - - assertTrue(launcher, "Couldn't set taskbar=" + expectTransientTaskbar, - isTaskbarTransientMode() == expectTransientTaskbar, description); - - AbstractLauncherUiTest.checkDetectedLeaks(launcher); - } - - private static void assertTrue(LauncherInstrumentation launcher, String message, - boolean condition, Description description) { - launcher.checkForAnomaly(true, true); - if (!condition) { - final AssertionError assertionError = new AssertionError(message); - if (description != null) { - FailureWatcher.onError(launcher, description, assertionError); - } - throw assertionError; - } - } -} diff --git a/src/com/android/launcher3/testing/shared/TestProtocol.java b/src/com/android/launcher3/testing/shared/TestProtocol.java index 90b8bfa50d..3fbce888f1 100644 --- a/src/com/android/launcher3/testing/shared/TestProtocol.java +++ b/src/com/android/launcher3/testing/shared/TestProtocol.java @@ -84,8 +84,6 @@ public final class TestProtocol { public static final String REQUEST_UNFREEZE_APP_LIST = "unfreeze-app-list"; public static final String REQUEST_ENABLE_MANUAL_TASKBAR_STASHING = "enable-taskbar-stashing"; public static final String REQUEST_DISABLE_MANUAL_TASKBAR_STASHING = "disable-taskbar-stashing"; - public static final String REQUEST_ENABLE_BLOCK_TIMEOUT = "enable-block-timeout"; - public static final String REQUEST_DISABLE_BLOCK_TIMEOUT = "disable-block-timeout"; public static final String REQUEST_UNSTASH_TASKBAR_IF_STASHED = "unstash-taskbar-if-stashed"; public static final String REQUEST_STASHED_TASKBAR_HEIGHT = "stashed-taskbar-height"; public static final String REQUEST_RECREATE_TASKBAR = "recreate-taskbar"; diff --git a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java index 0a00480a84..4b02ecc1f2 100644 --- a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java +++ b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java @@ -17,9 +17,7 @@ package com.android.launcher3.tapl; import static com.android.launcher3.tapl.LauncherInstrumentation.TASKBAR_RES_ID; -import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_DISABLE_BLOCK_TIMEOUT; import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_DISABLE_MANUAL_TASKBAR_STASHING; -import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_ENABLE_BLOCK_TIMEOUT; import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_ENABLE_MANUAL_TASKBAR_STASHING; import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_STASHED_TASKBAR_HEIGHT; @@ -90,7 +88,6 @@ public final class LaunchedAppState extends Background { */ public Taskbar showTaskbar() { mLauncher.getTestInfo(REQUEST_ENABLE_MANUAL_TASKBAR_STASHING); - mLauncher.getTestInfo(REQUEST_ENABLE_BLOCK_TIMEOUT); try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck(); LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer( @@ -117,7 +114,6 @@ public final class LaunchedAppState extends Background { } } finally { mLauncher.getTestInfo(REQUEST_DISABLE_MANUAL_TASKBAR_STASHING); - mLauncher.getTestInfo(REQUEST_DISABLE_BLOCK_TIMEOUT); } } diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 477d5ad46f..fe060a1609 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -1824,13 +1824,6 @@ public final class LauncherInstrumentation { getTestInfo(TestProtocol.REQUEST_UNSTASH_TASKBAR_IF_STASHED); } - /** Blocks the taskbar from automatically stashing based on time. */ - public void enableBlockTimeout(boolean enable) { - getTestInfo(enable - ? TestProtocol.REQUEST_ENABLE_BLOCK_TIMEOUT - : TestProtocol.REQUEST_DISABLE_BLOCK_TIMEOUT); - } - /** * Recreates the taskbar (outside of tests this is done for certain configuration changes). * The expected behavior is that the taskbar retains its current state after being recreated. From 93fc0f3a7c73017463167bb2db1e8b3d6a7e6c03 Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Wed, 2 Nov 2022 22:24:33 -0700 Subject: [PATCH 198/429] Allow user to select second split app from Taskbar This patch makes it so that (when we enable Taskbar in Overview) users will be able to select their second app for splitscreen by tapping the Taskbar icon, or the icon in AllApps. This was done by performing a check to SplitSelectStateController when a taskbar icon is hit. If we are currently in split select mode, Taskbar/AllApps icons will no longer launch their respective fullscreen apps, but instead confirm the split attempt. The confirmed app will either be an already-running instance of the app, or a fresh instance of the app (if none is currently running). The split confirmation function is located in TaskbarUIController, where it is accessible to both LauncherTaskbarUIController (for 1P Launcher) and FallbackTaskbarUIController (for 3P launchers). Also cleans up ~2 lines of unused code from the old splitscreen instructions toast. Outstanding issues: - When selecting a second app from within AllApps, the AllApps shade does not animate away in a satisfying way - When selecting a second app and launching a fresh instance of that app, the animation appears to come from the wrong location - Intent + Intent splitting does not currently work - If the selected app is already running with multiple instances, it picks the oldest instance. Ideally, the newest instance is preferred. Bug: 251747761 Test: Manual testing with Taskbar in Overview flag enabled Change-Id: I302dc092740bb880f9134ba8e2e587c4f2c29d01 --- .../taskbar/FallbackTaskbarUIController.java | 8 +- .../taskbar/LauncherTaskbarUIController.java | 6 ++ .../taskbar/TaskbarActivityContext.java | 85 ++++++++++++------- .../taskbar/TaskbarUIController.java | 39 +++++++++ .../android/quickstep/views/RecentsView.java | 61 ++++++++++--- .../com/android/quickstep/views/TaskView.java | 3 +- 6 files changed, 154 insertions(+), 48 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java index f1e67479f5..53ca7ed18e 100644 --- a/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/FallbackTaskbarUIController.java @@ -40,8 +40,7 @@ public class FallbackTaskbarUIController extends TaskbarUIController { animateToRecentsState(toState); // Handle tapping on live tile. - RecentsView recentsView = mRecentsActivity.getOverviewPanel(); - recentsView.setTaskLaunchListener(toState == RecentsState.DEFAULT + getRecentsView().setTaskLaunchListener(toState == RecentsState.DEFAULT ? (() -> animateToRecentsState(RecentsState.BACKGROUND_APP)) : null); } }; @@ -85,4 +84,9 @@ public class FallbackTaskbarUIController extends TaskbarUIController { anim.start(); } } + + @Override + public RecentsView getRecentsView() { + return mRecentsActivity.getOverviewPanel(); + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index 317f6a4884..2bcf179a4c 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -48,6 +48,7 @@ import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.OnboardingPrefs; import com.android.quickstep.AnimatedFloat; import com.android.quickstep.RecentsAnimationCallbacks; +import com.android.quickstep.views.RecentsView; import java.io.PrintWriter; import java.util.Arrays; @@ -393,4 +394,9 @@ public class LauncherTaskbarUIController extends TaskbarUIController { mTaskbarLauncherStateController.dumpLogs(prefix + "\t", pw); } + + @Override + public RecentsView getRecentsView() { + return mLauncher.getOverviewPanel(); + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index fad9ff490c..9fb13db8f6 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -90,6 +90,7 @@ import com.android.launcher3.util.SettingsCache; import com.android.launcher3.util.TraceHelper; import com.android.launcher3.util.ViewCache; import com.android.launcher3.views.ActivityContext; +import com.android.quickstep.views.RecentsView; import com.android.systemui.shared.recents.model.Task; import com.android.systemui.shared.rotation.RotationButtonController; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -132,6 +133,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { private final boolean mIsUserSetupComplete; private final boolean mIsNavBarForceVisible; private final boolean mIsNavBarKidsMode; + private boolean mIsDestroyed = false; // The flag to know if the window is excluded from magnification region computation. private boolean mIsExcludeFromMagnificationRegion = false; @@ -755,42 +757,63 @@ public class TaskbarActivityContext extends BaseTaskbarContext { if (info.isDisabled()) { ItemClickHandler.handleDisabledItemClicked(info, this); } else { - Intent intent = new Intent(info.getIntent()) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - try { - if (mIsSafeModeEnabled && !PackageManagerHelper.isSystemApp(this, intent)) { - Toast.makeText(this, R.string.safemode_shortcut_error, - Toast.LENGTH_SHORT).show(); - } else if (info.isPromise()) { - TestLogging.recordEvent( - TestProtocol.SEQUENCE_MAIN, "start: taskbarPromiseIcon"); - intent = new PackageManagerHelper(this) - .getMarketIntent(info.getTargetPackage()) - .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); - startActivity(intent); + TaskbarUIController taskbarUIController = mControllers.uiController; + RecentsView recents = taskbarUIController.getRecentsView(); + if (recents != null + && taskbarUIController.getRecentsView().isSplitSelectionActive()) { + // If we are selecting a second app for split, launch the split tasks + taskbarUIController.triggerSecondAppForSplit(info, info.intent, view); + } else { + // Else launch the selected task + Intent intent = new Intent(info.getIntent()) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + try { + if (mIsSafeModeEnabled && !PackageManagerHelper.isSystemApp(this, intent)) { + Toast.makeText(this, R.string.safemode_shortcut_error, + Toast.LENGTH_SHORT).show(); + } else if (info.isPromise()) { + TestLogging.recordEvent( + TestProtocol.SEQUENCE_MAIN, "start: taskbarPromiseIcon"); + intent = new PackageManagerHelper(this) + .getMarketIntent(info.getTargetPackage()) + .addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(intent); - } else if (info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) { - TestLogging.recordEvent( - TestProtocol.SEQUENCE_MAIN, "start: taskbarDeepShortcut"); - String id = info.getDeepShortcutId(); - String packageName = intent.getPackage(); - getSystemService(LauncherApps.class) - .startShortcut(packageName, id, null, null, info.user); - } else { - startItemInfoActivity(info); + } else if (info.itemType == Favorites.ITEM_TYPE_DEEP_SHORTCUT) { + TestLogging.recordEvent( + TestProtocol.SEQUENCE_MAIN, "start: taskbarDeepShortcut"); + String id = info.getDeepShortcutId(); + String packageName = intent.getPackage(); + getSystemService(LauncherApps.class) + .startShortcut(packageName, id, null, null, info.user); + } else { + startItemInfoActivity(info); + } + + mControllers.uiController.onTaskbarIconLaunched(info); + } catch (NullPointerException + | ActivityNotFoundException + | SecurityException e) { + Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT) + .show(); + Log.e(TAG, "Unable to launch. tag=" + info + " intent=" + intent, e); } - - mControllers.uiController.onTaskbarIconLaunched(info); - mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true); - } catch (NullPointerException | ActivityNotFoundException | SecurityException e) { - Toast.makeText(this, R.string.activity_not_found, Toast.LENGTH_SHORT) - .show(); - Log.e(TAG, "Unable to launch. tag=" + info + " intent=" + intent, e); } + mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true); } } else if (tag instanceof AppInfo) { - startItemInfoActivity((AppInfo) tag); - mControllers.uiController.onTaskbarIconLaunched((AppInfo) tag); + AppInfo info = (AppInfo) tag; + TaskbarUIController taskbarUIController = mControllers.uiController; + RecentsView recents = taskbarUIController.getRecentsView(); + if (recents != null + && taskbarUIController.getRecentsView().isSplitSelectionActive()) { + // If we are selecting a second app for split, launch the split tasks + taskbarUIController.triggerSecondAppForSplit(info, info.intent, view); + } else { + // Else launch the selected task + startItemInfoActivity((AppInfo) tag); + mControllers.uiController.onTaskbarIconLaunched((AppInfo) tag); + } mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true); } else { Log.e(TAG, "Unknown type clicked: " + tag); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java index 11521260e9..0af25966ea 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java @@ -15,13 +15,18 @@ */ package com.android.launcher3.taskbar; +import android.content.Intent; +import android.graphics.drawable.BitmapDrawable; import android.view.MotionEvent; import android.view.View; import androidx.annotation.CallSuper; +import androidx.annotation.Nullable; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfoWithIcon; +import com.android.quickstep.views.RecentsView; +import com.android.quickstep.views.TaskView; import java.io.PrintWriter; import java.util.stream.Stream; @@ -128,4 +133,38 @@ public class TaskbarUIController { prefix, getClass().getSimpleName())); } + + /** + * Returns RecentsView. Overwritten in LauncherTaskbarUIController and + * FallbackTaskbarUIController with Launcher-specific implementations. Returns null for other + * UI controllers (like DesktopTaskbarUIController) that don't have a RecentsView. + */ + public @Nullable RecentsView getRecentsView() { + return null; + } + + /** + * Uses the clicked Taskbar icon to launch a second app for splitscreen. + */ + public void triggerSecondAppForSplit(ItemInfoWithIcon info, Intent intent, View startingView) { + RecentsView recents = getRecentsView(); + TaskView foundTaskView = recents.getTaskViewByComponentName(info.getTargetComponent()); + if (foundTaskView != null) { + recents.confirmSplitSelect( + foundTaskView, + foundTaskView.getTask(), + foundTaskView.getIconView().getDrawable(), + foundTaskView.getThumbnail(), + foundTaskView.getThumbnail().getThumbnail(), + /* intent */ null); + } else { + recents.confirmSplitSelect( + /* containerTaskView */ null, + /* task */ null, + new BitmapDrawable(info.bitmap.icon), + startingView, + /* thumbnail */ null, + intent); + } + } } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 35414a644a..fed982c6fe 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -74,9 +74,12 @@ import android.animation.ValueAnimator; import android.annotation.SuppressLint; import android.annotation.TargetApi; import android.app.WindowConfiguration; +import android.content.ComponentName; import android.content.Context; +import android.content.Intent; import android.content.LocusId; import android.content.res.Configuration; +import android.graphics.Bitmap; import android.graphics.BlendMode; import android.graphics.Canvas; import android.graphics.Color; @@ -661,8 +664,6 @@ public abstract class RecentsView Date: Tue, 8 Nov 2022 14:25:09 +0000 Subject: [PATCH 199/429] Align system navigation setting link in AllSet page for tablets to top/start. Fix: 233610579 Test: manual Change-Id: If6d462df02bf795e8a6e73fbb040a6a84ea99404 --- .../allset_navigation_and_hint.xml | 43 ------------------- .../allset_navigation_and_hint.xml | 7 ++- quickstep/res/values-sw600dp-land/dimens.xml | 1 - quickstep/res/values-sw600dp/dimens.xml | 1 - quickstep/res/values-sw720dp-land/dimens.xml | 3 -- quickstep/res/values-sw720dp/dimens.xml | 1 - quickstep/res/values/dimens.xml | 1 - 7 files changed, 3 insertions(+), 54 deletions(-) delete mode 100644 quickstep/res/layout-sw600dp-land/allset_navigation_and_hint.xml diff --git a/quickstep/res/layout-sw600dp-land/allset_navigation_and_hint.xml b/quickstep/res/layout-sw600dp-land/allset_navigation_and_hint.xml deleted file mode 100644 index 3bfa6da49d..0000000000 --- a/quickstep/res/layout-sw600dp-land/allset_navigation_and_hint.xml +++ /dev/null @@ -1,43 +0,0 @@ - - - - - - - - - \ No newline at end of file diff --git a/quickstep/res/layout-sw600dp/allset_navigation_and_hint.xml b/quickstep/res/layout-sw600dp/allset_navigation_and_hint.xml index 9559072f8f..44b3ecbd97 100644 --- a/quickstep/res/layout-sw600dp/allset_navigation_and_hint.xml +++ b/quickstep/res/layout-sw600dp/allset_navigation_and_hint.xml @@ -21,12 +21,11 @@ style="@style/TextAppearance.GestureTutorial.LinkText" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:layout_marginBottom="96dp" + android:layout_marginTop="24dp" android:background="?android:attr/selectableItemBackground" android:minHeight="48dp" android:text="@string/allset_navigation_settings" - app:layout_constraintBottom_toTopOf="@id/hint" - app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toBottomOf="@id/subtitle" app:layout_constraintStart_toStartOf="parent" /> 48dp - 24dp diff --git a/quickstep/res/values-sw600dp/dimens.xml b/quickstep/res/values-sw600dp/dimens.xml index c96ad11e8b..5899814600 100644 --- a/quickstep/res/values-sw600dp/dimens.xml +++ b/quickstep/res/values-sw600dp/dimens.xml @@ -36,7 +36,6 @@ 120dp - 24dp 38sp 15sp diff --git a/quickstep/res/values-sw720dp-land/dimens.xml b/quickstep/res/values-sw720dp-land/dimens.xml index 4bc8bf3c03..02d11892dd 100644 --- a/quickstep/res/values-sw720dp-land/dimens.xml +++ b/quickstep/res/values-sw720dp-land/dimens.xml @@ -17,7 +17,4 @@ 20dp - - - 24dp diff --git a/quickstep/res/values-sw720dp/dimens.xml b/quickstep/res/values-sw720dp/dimens.xml index a84b9394b1..585f01e46a 100644 --- a/quickstep/res/values-sw720dp/dimens.xml +++ b/quickstep/res/values-sw720dp/dimens.xml @@ -35,7 +35,6 @@ 64dp - 0dp 42sp 16sp diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index 6e3fd32329..cd60879580 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -202,7 +202,6 @@ 40dp - 0dp 36sp 14sp From b67bfa7512092d38cb7e29851148cebaf4b0387f Mon Sep 17 00:00:00 2001 From: Thales Lima Date: Wed, 2 Nov 2022 15:30:11 +0000 Subject: [PATCH 200/429] Create test for default grid Fixes: 256044695 Test: DeviceDefaultGridTest Change-Id: Ie0a4de12f777ad3d15020252b2f67b575cc0eca9 --- src/com/android/launcher3/InvariantDeviceProfile.java | 5 +++++ src/com/android/launcher3/Utilities.java | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 0c6f340cb1..ca92aa48f6 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -324,6 +324,11 @@ public class InvariantDeviceProfile { return displayOption.grid.name; } + @VisibleForTesting + public static String getDefaultGridName(Context context) { + return new InvariantDeviceProfile().initGrid(context, null); + } + private void initGrid(Context context, Info displayInfo, DisplayOption displayOption, @DeviceType int deviceType) { DisplayMetrics metrics = context.getResources().getDisplayMetrics(); diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index f70511af7b..a5075327d0 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -521,6 +521,11 @@ public final class Utilities { return (int) (dp * Resources.getSystem().getDisplayMetrics().density); } + /** Converts a dp value to pixels for a certain density. */ + public static int dpToPx(float dp, int densityDpi) { + float densityRatio = (float) densityDpi / DisplayMetrics.DENSITY_DEFAULT; + return (int) (dp * densityRatio); + } public static int pxFromSp(float size, DisplayMetrics metrics) { return pxFromSp(size, metrics, 1f); From d82fc92b2db86fc8d17b4346a0222569829a1d45 Mon Sep 17 00:00:00 2001 From: Saumya Prakash Date: Wed, 9 Nov 2022 01:11:54 +0000 Subject: [PATCH 201/429] Add padding around clear all button in overview. With different languages, the length of the string "clear all" varies, leading to the clear all button in overview looking different. This change adds padding to account for these different lengths to ensure that users have a consistent experience. Screenshot for English: https://screenshot.googleplex.com/4oijo96WSfGNwWp.png Screenshot for Ukrainian: https://screenshot.googleplex.com/Bv2963Vn96BkMeT.png Test: Manual Fix: 225119413 Change-Id: I09fe7bc95ca0c2fd7fe620997d1298f2670b50a4 --- quickstep/res/values/styles.xml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml index 868d38bd81..4f0fdf182d 100644 --- a/quickstep/res/values/styles.xml +++ b/quickstep/res/values/styles.xml @@ -152,6 +152,8 @@ @drawable/bg_overview_clear_all_button 96dp 48dp + 12dp + 12dp @null From 431f05b3a0cf42cfb5dcb188abafc8d9df69ca90 Mon Sep 17 00:00:00 2001 From: Luca Zuccarini Date: Wed, 21 Sep 2022 14:10:28 +0000 Subject: [PATCH 202/429] [Toast] Update A-Z <-> Toast transition for drawable backgrounds. This and the other change in the topic are protected by a new feature flag (included here). Bug: 229297414 Bug: 248006105 Test: manual (see screenshots and recordings in the second bug) Change-Id: I3478d7e194ee5d3bc4f8affdadbec969c033d084 --- .../allapps/SearchTransitionController.java | 44 +++++++++++++++---- .../launcher3/config/FeatureFlags.java | 4 ++ 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/src/com/android/launcher3/allapps/SearchTransitionController.java b/src/com/android/launcher3/allapps/SearchTransitionController.java index 9c3dab4ec3..495f5c3eff 100644 --- a/src/com/android/launcher3/allapps/SearchTransitionController.java +++ b/src/com/android/launcher3/allapps/SearchTransitionController.java @@ -32,6 +32,7 @@ import android.graphics.drawable.Drawable; import android.util.FloatProperty; import android.util.Log; import android.view.View; +import android.view.ViewGroup; import android.view.animation.Interpolator; import com.android.launcher3.BubbleTextView; @@ -39,6 +40,7 @@ import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; import com.android.launcher3.R; import com.android.launcher3.Utilities; +import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.data.ItemInfo; /** Coordinates the transition between Search and A-Z in All Apps. */ @@ -225,16 +227,35 @@ public class SearchTransitionController { numSearchResultsAnimated++; } - searchResultView.setAlpha(contentAlpha); - // Apply background alpha to decorator if possible. - if (adapterPosition != NO_POSITION) { - searchRecyclerView.getApps().getAdapterItems() - .get(adapterPosition).setDecorationFillAlpha((int) (255 * backgroundAlpha)); - } - // Apply background alpha to view's background (e.g. for Search Edu card). + Drawable background = searchResultView.getBackground(); - if (background != null) { + if (background != null + && searchResultView instanceof ViewGroup + && FeatureFlags.ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES.get()) { + searchResultView.setAlpha(1f); + + // Apply content alpha to each child, since the view needs to be fully opaque for + // the background to show properly. + ViewGroup searchResultViewGroup = (ViewGroup) searchResultView; + for (int j = 0; j < searchResultViewGroup.getChildCount(); j++) { + searchResultViewGroup.getChildAt(j).setAlpha(contentAlpha); + } + + // Apply background alpha to the background drawable directly. background.setAlpha((int) (255 * backgroundAlpha)); + } else { + searchResultView.setAlpha(contentAlpha); + + // Apply background alpha to decorator if possible. + if (adapterPosition != NO_POSITION) { + searchRecyclerView.getApps().getAdapterItems().get(adapterPosition) + .setDecorationFillAlpha((int) (255 * backgroundAlpha)); + } + + // Apply background alpha to view's background (e.g. for Search Edu card). + if (background != null) { + background.setAlpha((int) (255 * backgroundAlpha)); + } } float scaleY = 1; @@ -304,6 +325,13 @@ public class SearchTransitionController { getSearchRecyclerView().getApps().getAdapterItems().get(adapterPosition) .setDecorationFillAlpha(255); } + if (child instanceof ViewGroup + && FeatureFlags.ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES.get()) { + ViewGroup childGroup = (ViewGroup) child; + for (int i = 0; i < childGroup.getChildCount(); i++) { + childGroup.getChildAt(i).setAlpha(1f); + } + } if (child.getBackground() != null) { child.getBackground().setAlpha(255); } diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 4287779c31..7b221dcc8a 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -264,6 +264,10 @@ public final class FeatureFlags { public static final BooleanFlag ENABLE_ONE_SEARCH_MOTION = new DeviceFlag( "ENABLE_ONE_SEARCH_MOTION", true, "Enables animations in OneSearch."); + public static final BooleanFlag ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES = new DeviceFlag( + "ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES", false, + "Enable option to replace decorator-based search result backgrounds with drawables"); + public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = new DeviceFlag( "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", true, "Enable option to show keyboard when going to all-apps"); From f213afc0a7b4ca68f5546040b3a06072d2415699 Mon Sep 17 00:00:00 2001 From: Anushree Ganjam Date: Tue, 8 Nov 2022 03:11:56 +0000 Subject: [PATCH 203/429] Add OnLayoutCompleted() Listener. OnLayoutCompleted() Listener for RecyclerView.LayoutManager#onLayoutCompleted(RecyclerView.State) so we can do impression logging when RecyclerView has finished laying out the items. Bug: 204781396 Test: Manual Change-Id: I59b81e98415b2b0c6f3b26d2c41d348242342048 --- .../launcher3/allapps/AllAppsGridAdapter.java | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java index 368a37384d..e34d4c85ae 100644 --- a/src/com/android/launcher3/allapps/AllAppsGridAdapter.java +++ b/src/com/android/launcher3/allapps/AllAppsGridAdapter.java @@ -31,6 +31,7 @@ import androidx.recyclerview.widget.RecyclerView.Adapter; import com.android.launcher3.util.ScrollableLayoutManager; import com.android.launcher3.views.ActivityContext; +import java.util.ArrayList; import java.util.List; /** @@ -43,6 +44,31 @@ public class AllAppsGridAdapter extends public static final String TAG = "AppsGridAdapter"; private final AppsGridLayoutManager mGridLayoutMgr; + private final List mOnLayoutCompletedListeners = new ArrayList<>(); + + /** + * Listener for {@link RecyclerView.LayoutManager#onLayoutCompleted(RecyclerView.State)} + */ + public interface OnLayoutCompletedListener { + void onLayoutCompleted(); + } + + /** + * Adds a {@link OnLayoutCompletedListener} to receive a callback when {@link + * RecyclerView.LayoutManager#onLayoutCompleted(RecyclerView.State)} is called + */ + public void addOnLayoutCompletedListener(OnLayoutCompletedListener listener) { + mOnLayoutCompletedListeners.add(listener); + } + + /** + * Removes a {@link OnLayoutCompletedListener} to not receive a callback when {@link + * RecyclerView.LayoutManager#onLayoutCompleted(RecyclerView.State)} is called + */ + public void removeOnLayoutCompletedListener(OnLayoutCompletedListener listener) { + mOnLayoutCompletedListeners.remove(listener); + } + public AllAppsGridAdapter(T activityContext, LayoutInflater inflater, AlphabeticalAppsList apps, BaseAdapterProvider[] adapterProviders) { @@ -132,6 +158,14 @@ public class AllAppsGridAdapter extends return extraRows; } + @Override + public void onLayoutCompleted(RecyclerView.State state) { + super.onLayoutCompleted(state); + for (OnLayoutCompletedListener listener : mOnLayoutCompletedListeners) { + listener.onLayoutCompleted(); + } + } + @Override protected int incrementTotalHeight(Adapter adapter, int position, int heightUntilLastPos) { AllAppsGridAdapter.AdapterItem item = mApps.getAdapterItems().get(position); From 29eb74f9bd7f906f390d4f06b6f51183a812371d Mon Sep 17 00:00:00 2001 From: Anushree Ganjam Date: Tue, 8 Nov 2022 03:19:50 +0000 Subject: [PATCH 204/429] Add ENABLE_TOAST_IMPRESSION_LOGGING to FeatureFlags. Bug: 204781396 Test: Manual Change-Id: Icd1170d8fc349ca3a50836ef0d1d0c9a0c793002 --- src/com/android/launcher3/config/FeatureFlags.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 4287779c31..3a580203c6 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -323,6 +323,9 @@ public final class FeatureFlags { public static final BooleanFlag SHOW_DOT_PAGINATION = getDebugFlag( "SHOW_DOT_PAGINATION", false, "Enable showing dot pagination in workspace"); + public static final BooleanFlag ENABLE_TOAST_IMPRESSION_LOGGING = getDebugFlag( + "ENABLE_TOAST_IMPRESSION_LOGGING", false, "Enable toast impression logging"); + public static void initialize(Context context) { synchronized (sDebugFlags) { for (DebugFlag flag : sDebugFlags) { From f0349354ec3dfda294261381afbf21fc5b07721e Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Wed, 9 Nov 2022 15:35:21 -0800 Subject: [PATCH 205/429] Revert "Revert "Add TaskbarModeSwitchRule to test both transient/persistent taskbar."" This reverts commit e7011d2b876770dcefde509e8775bb65b6d1d8e1. Reason for revert: attempt to fix test issues - Instead of using SharedPrefs which can be flaky anyways, we pass along a boolean to test transient taskbar when we are in the test harness Bug: 257549303 Test: TaplTestsTaskbar Change-Id: I7c15a97363adc377f29853c1fe60b1960c77bfc3 --- quickstep/Android.bp | 1 + .../taskbar/TaskbarActivityContext.java | 19 ++- .../taskbar/TaskbarStashController.java | 20 ++- .../QuickstepTestInformationHandler.java | 40 +++++ .../quickstep/AbstractQuickStepTest.java | 1 + .../quickstep/NavigationModeSwitchRule.java | 2 +- .../android/quickstep/TaplTestsTaskbar.java | 17 +++ .../quickstep/TaskbarModeSwitchRule.java | 140 ++++++++++++++++++ .../testing/shared/TestProtocol.java | 4 + .../launcher3/util/DisplayController.java | 16 +- .../launcher3/tapl/LaunchedAppState.java | 4 + .../tapl/LauncherInstrumentation.java | 14 ++ 12 files changed, 269 insertions(+), 9 deletions(-) create mode 100644 quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java diff --git a/quickstep/Android.bp b/quickstep/Android.bp index 7292c4495b..f5a8253563 100644 --- a/quickstep/Android.bp +++ b/quickstep/Android.bp @@ -38,6 +38,7 @@ filegroup { name: "launcher3-quickstep-oop-tests-src", path: "tests", srcs: [ + "tests/src/com/android/quickstep/TaskbarModeSwitchRule.java", "tests/src/com/android/quickstep/NavigationModeSwitchRule.java", "tests/src/com/android/quickstep/AbstractQuickStepTest.java", "tests/src/com/android/quickstep/TaplTestsQuickstep.java", diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 3c9e96f295..48828426cc 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -23,6 +23,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_NAVIGATION_BAR_PANEL; import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE; +import static com.android.launcher3.Utilities.IS_RUNNING_IN_TEST_HARNESS; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN; import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_DRAGGING; import static com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_FULLSCREEN; @@ -306,7 +307,8 @@ public class TaskbarActivityContext extends BaseTaskbarContext { int windowFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE | WindowManager.LayoutParams.FLAG_SLIPPERY | WindowManager.LayoutParams.FLAG_SPLIT_TOUCH; - if (DisplayController.isTransientTaskbar(this)) { + if (DisplayController.isTransientTaskbar(this) + && !IS_RUNNING_IN_TEST_HARNESS) { windowFlags |= WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH; } @@ -873,13 +875,26 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mControllers.taskbarStashController.enableManualStashingDuringTests(enableManualStashing); } + /** + * Enables the auto timeout for taskbar stashing. This method should only be used for taskbar + * testing. + */ + @VisibleForTesting + public void enableBlockingTimeoutDuringTests(boolean enableBlockingTimeout) { + mControllers.taskbarStashController.enableBlockingTimeoutDuringTests(enableBlockingTimeout); + } + /** * Unstashes the Taskbar if it is stashed. This method should only be used to unstash the * taskbar at the end of a test. */ @VisibleForTesting public void unstashTaskbarIfStashed() { - mControllers.taskbarStashController.onLongPressToUnstashTaskbar(); + if (DisplayController.isTransientTaskbar(this)) { + mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(false); + } else { + mControllers.taskbarStashController.onLongPressToUnstashTaskbar(); + } } protected boolean isUserSetupComplete() { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 72ae1d1c31..b53e9c56cd 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -37,6 +37,7 @@ import android.view.View; import android.view.ViewConfiguration; import androidx.annotation.NonNull; +import androidx.annotation.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor; import com.android.launcher3.Alarm; @@ -169,6 +170,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba private boolean mEnableManualStashingDuringTests = false; private final Alarm mTimeoutAlarm = new Alarm(); + private boolean mEnableBlockingTimeoutDuringTests = false; // Evaluate whether the handle should be stashed private final StatePropertyHolder mStatePropertyHolder = new StatePropertyHolder( @@ -267,10 +269,20 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba * Enables support for manual stashing. This should only be used to add this functionality * to Launcher specific tests. */ + @VisibleForTesting public void enableManualStashingDuringTests(boolean enableManualStashing) { mEnableManualStashingDuringTests = enableManualStashing; } + /** + * Enables the auto timeout for taskbar stashing. This method should only be used for taskbar + * testing. + */ + @VisibleForTesting + public void enableBlockingTimeoutDuringTests(boolean enableBlockingTimeout) { + mEnableBlockingTimeoutDuringTests = enableBlockingTimeout; + } + /** * Sets the flag indicating setup UI is visible */ @@ -846,12 +858,12 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba * Attempts to start timer to auto hide the taskbar based on time. */ public void tryStartTaskbarTimeout() { - if (!DisplayController.isTransientTaskbar(mActivity)) { - return; - } - if (mIsStashed) { + if (!DisplayController.isTransientTaskbar(mActivity) + || mIsStashed + || mEnableBlockingTimeoutDuringTests) { return; } + cancelTimeoutIfExists(); mTimeoutAlarm.setOnAlarmListener(this::onTaskbarTimeout); diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java index 9621ce6eba..6f124b8418 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -11,9 +11,11 @@ import android.os.Bundle; import androidx.annotation.Nullable; import com.android.launcher3.R; +import com.android.launcher3.taskbar.TaskbarActivityContext; import com.android.launcher3.testing.TestInformationHandler; import com.android.launcher3.testing.shared.TestProtocol; import com.android.launcher3.touch.PagedOrientationHandler; +import com.android.launcher3.util.DisplayController; import com.android.quickstep.util.LayoutUtils; import com.android.quickstep.util.TISBindHelper; @@ -120,6 +122,30 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { .getCurrentActivityContext() .getTaskbarAllAppsTopPadding()); } + + case TestProtocol.REQUEST_ENABLE_BLOCK_TIMEOUT: + runOnTISBinder(tisBinder -> { + enableBlockingTimeout(tisBinder, true); + }); + return response; + + case TestProtocol.REQUEST_DISABLE_BLOCK_TIMEOUT: + runOnTISBinder(tisBinder -> { + enableBlockingTimeout(tisBinder, false); + }); + return response; + + case TestProtocol.REQUEST_ENABLE_TRANSIENT_TASKBAR: + runOnTISBinder(tisBinder -> { + enableTransientTaskbar(tisBinder, true); + }); + return response; + + case TestProtocol.REQUEST_DISABLE_TRANSIENT_TASKBAR: + runOnTISBinder(tisBinder -> { + enableTransientTaskbar(tisBinder, false); + }); + return response; } return super.call(method, arg, extras); @@ -149,6 +175,20 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { enable); } + private void enableBlockingTimeout( + TouchInteractionService.TISBinder tisBinder, boolean enable) { + // Allow null-pointer to catch illegal states. + tisBinder.getTaskbarManager().getCurrentActivityContext().enableBlockingTimeoutDuringTests( + enable); + } + + private void enableTransientTaskbar( + TouchInteractionService.TISBinder tisBinder, boolean enable) { + // Allow null-pointer to catch illegal states. + TaskbarActivityContext context = tisBinder.getTaskbarManager().getCurrentActivityContext(); + DisplayController.INSTANCE.get(context).enableTransientTaskbarForTests(enable); + } + /** * Runs the given command on the UI thread, after ensuring we are connected to * TouchInteractionService. diff --git a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java index e2774c003d..2c5825fd0b 100644 --- a/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java +++ b/quickstep/tests/src/com/android/quickstep/AbstractQuickStepTest.java @@ -39,6 +39,7 @@ public abstract class AbstractQuickStepTest extends AbstractLauncherUiTest { protected TestRule getRulesInsideActivityMonitor() { return RuleChain. outerRule(new NavigationModeSwitchRule(mLauncher)). + around(new TaskbarModeSwitchRule(mLauncher)). around(super.getRulesInsideActivityMonitor()); } diff --git a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java index e5e2cf3337..eded1c961f 100644 --- a/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java +++ b/quickstep/tests/src/com/android/quickstep/NavigationModeSwitchRule.java @@ -51,7 +51,7 @@ import java.util.concurrent.TimeUnit; /** * Test rule that allows executing a test with Quickstep on and then Quickstep off. - * The test should be annotated with @QuickstepOnOff. + * The test should be annotated with @NavigationModeSwitch. */ public class NavigationModeSwitchRule implements TestRule { diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java index 9337cb55bc..0b8bc10fec 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTaskbar.java @@ -17,6 +17,8 @@ package com.android.quickstep; import static androidx.test.InstrumentationRegistry.getInstrumentation; +import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT; + import static junit.framework.TestCase.assertEquals; import android.content.Intent; @@ -27,6 +29,7 @@ import androidx.test.runner.AndroidJUnit4; import com.android.launcher3.tapl.Taskbar; import com.android.launcher3.ui.TaplTestsLauncher3; import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord; +import com.android.quickstep.TaskbarModeSwitchRule.TaskbarModeSwitch; import org.junit.After; import org.junit.Assume; @@ -53,21 +56,25 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { TaplTestsLauncher3.initialize(this); startAppFast(CALCULATOR_APP_PACKAGE); + mLauncher.enableBlockTimeout(true); mLauncher.showTaskbarIfHidden(); } @After public void tearDown() { mLauncher.useDefaultWorkspaceLayoutOnReload(); + mLauncher.enableBlockTimeout(false); } @Test + @TaskbarModeSwitch(mode = PERSISTENT) public void testHideShowTaskbar() { getTaskbar().hide(); mLauncher.getLaunchedAppState().showTaskbar(); } @Test + @TaskbarModeSwitch(mode = PERSISTENT) public void testHideTaskbarPersistsOnRecreate() { getTaskbar().hide(); mLauncher.recreateTaskbar(); @@ -75,16 +82,19 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { } @Test + @TaskbarModeSwitch public void testLaunchApp() throws Exception { getTaskbar().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE); } @Test + @TaskbarModeSwitch public void testOpenMenu() throws Exception { getTaskbar().getAppIcon(TEST_APP_NAME).openMenu(); } @Test + @TaskbarModeSwitch public void testLaunchShortcut() throws Exception { getTaskbar().getAppIcon(TEST_APP_NAME) .openDeepShortcutMenu() @@ -95,6 +105,7 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { @Test @ScreenRecord // b/231615831 @PortraitLandscape + @TaskbarModeSwitch public void testLaunchAppInSplitscreen() throws Exception { getTaskbar().getAppIcon(TEST_APP_NAME).dragToSplitscreen( TEST_APP_PACKAGE, CALCULATOR_APP_PACKAGE); @@ -103,6 +114,7 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { @Test @ScreenRecord // b/231615831 @PortraitLandscape + @TaskbarModeSwitch public void testLaunchShortcutInSplitscreen() throws Exception { getTaskbar().getAppIcon(TEST_APP_NAME) .openDeepShortcutMenu() @@ -111,16 +123,19 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { } @Test + @TaskbarModeSwitch public void testLaunchApp_FromTaskbarAllApps() throws Exception { getTaskbar().openAllApps().getAppIcon(TEST_APP_NAME).launch(TEST_APP_PACKAGE); } @Test + @TaskbarModeSwitch public void testOpenMenu_FromTaskbarAllApps() throws Exception { getTaskbar().openAllApps().getAppIcon(TEST_APP_NAME).openMenu(); } @Test + @TaskbarModeSwitch public void testLaunchShortcut_FromTaskbarAllApps() throws Exception { getTaskbar().openAllApps() .getAppIcon(TEST_APP_NAME) @@ -132,6 +147,7 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { @Test @ScreenRecord // b/231615831 @PortraitLandscape + @TaskbarModeSwitch public void testLaunchAppInSplitscreen_FromTaskbarAllApps() throws Exception { getTaskbar().openAllApps() .getAppIcon(TEST_APP_NAME) @@ -141,6 +157,7 @@ public class TaplTestsTaskbar extends AbstractQuickStepTest { @Test @ScreenRecord // b/231615831 @PortraitLandscape + @TaskbarModeSwitch public void testLaunchShortcutInSplitscreen_FromTaskbarAllApps() throws Exception { getTaskbar().openAllApps() .getAppIcon(TEST_APP_NAME) diff --git a/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java b/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java new file mode 100644 index 0000000000..9e41f74186 --- /dev/null +++ b/quickstep/tests/src/com/android/quickstep/TaskbarModeSwitchRule.java @@ -0,0 +1,140 @@ +/* + * Copyright (C) 2022 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 static androidx.test.InstrumentationRegistry.getInstrumentation; + +import static com.android.quickstep.TaskbarModeSwitchRule.Mode.ALL; +import static com.android.quickstep.TaskbarModeSwitchRule.Mode.PERSISTENT; +import static com.android.quickstep.TaskbarModeSwitchRule.Mode.TRANSIENT; + +import android.content.Context; +import android.util.Log; + +import com.android.launcher3.tapl.LauncherInstrumentation; +import com.android.launcher3.tapl.TestHelpers; +import com.android.launcher3.ui.AbstractLauncherUiTest; +import com.android.launcher3.util.DisplayController; +import com.android.launcher3.util.rule.FailureWatcher; + +import org.junit.rules.TestRule; +import org.junit.runner.Description; +import org.junit.runners.model.Statement; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +/** + * Test rule that allows executing a test multiple times with different conditions + * ie. with transient taskbar enabled and disabled. + * The test should be annotated with @TaskbarModeSwitch. + */ +public class TaskbarModeSwitchRule implements TestRule { + + static final String TAG = "TaskbarModeSwitchRule"; + + public static final int WAIT_TIME_MS = 10000; + + public enum Mode { + TRANSIENT, PERSISTENT, ALL + } + + // Annotation for tests that need to be run with quickstep enabled and disabled. + @Retention(RetentionPolicy.RUNTIME) + @Target(ElementType.METHOD) + public @interface TaskbarModeSwitch { + Mode mode() default ALL; + } + + private final LauncherInstrumentation mLauncher; + + public TaskbarModeSwitchRule(LauncherInstrumentation launcher) { + mLauncher = launcher; + } + + @Override + public Statement apply(Statement base, Description description) { + if (TestHelpers.isInLauncherProcess() + && description.getAnnotation(TaskbarModeSwitch.class) != null) { + Mode mode = description.getAnnotation(TaskbarModeSwitch.class).mode(); + return new Statement() { + @Override + public void evaluate() throws Throwable { + mLauncher.enableDebugTracing(); + final boolean wasTransientTaskbarMode = + isTaskbarTransientMode(getInstrumentation().getTargetContext()); + try { + if (mode == TRANSIENT || mode == ALL) { + evaluateWithTransientTaskbar(); + } + if (mode == PERSISTENT || mode == ALL) { + evaluateWithPersistentTaskbar(); + } + } catch (Throwable e) { + Log.e(TAG, "Error", e); + throw e; + } finally { + Log.d(TAG, "In Finally block"); + setTaskbarMode(mLauncher, wasTransientTaskbarMode, description); + } + } + + private void evaluateWithPersistentTaskbar() throws Throwable { + setTaskbarMode(mLauncher, false, description); + base.evaluate(); + } + + private void evaluateWithTransientTaskbar() throws Throwable { + setTaskbarMode(mLauncher, true, description); + base.evaluate(); + } + }; + } else { + return base; + } + } + + private static boolean isTaskbarTransientMode(Context context) { + return DisplayController.isTransientTaskbar(context); + } + + public static void setTaskbarMode(LauncherInstrumentation launcher, + boolean expectTransientTaskbar, Description description) throws Exception { + launcher.enableTransientTaskbar(expectTransientTaskbar); + launcher.recreateTaskbar(); + + Context context = getInstrumentation().getTargetContext(); + assertTrue(launcher, "Couldn't set taskbar=" + expectTransientTaskbar, + isTaskbarTransientMode(context) == expectTransientTaskbar, description); + + AbstractLauncherUiTest.checkDetectedLeaks(launcher); + } + + private static void assertTrue(LauncherInstrumentation launcher, String message, + boolean condition, Description description) { + launcher.checkForAnomaly(true, true); + if (!condition) { + final AssertionError assertionError = new AssertionError(message); + if (description != null) { + FailureWatcher.onError(launcher, description, assertionError); + } + throw assertionError; + } + } +} diff --git a/src/com/android/launcher3/testing/shared/TestProtocol.java b/src/com/android/launcher3/testing/shared/TestProtocol.java index 3fbce888f1..7586d0bc31 100644 --- a/src/com/android/launcher3/testing/shared/TestProtocol.java +++ b/src/com/android/launcher3/testing/shared/TestProtocol.java @@ -84,6 +84,10 @@ public final class TestProtocol { public static final String REQUEST_UNFREEZE_APP_LIST = "unfreeze-app-list"; public static final String REQUEST_ENABLE_MANUAL_TASKBAR_STASHING = "enable-taskbar-stashing"; public static final String REQUEST_DISABLE_MANUAL_TASKBAR_STASHING = "disable-taskbar-stashing"; + public static final String REQUEST_ENABLE_BLOCK_TIMEOUT = "enable-block-timeout"; + public static final String REQUEST_DISABLE_BLOCK_TIMEOUT = "disable-block-timeout"; + public static final String REQUEST_ENABLE_TRANSIENT_TASKBAR = "enable-transient-taskbar"; + public static final String REQUEST_DISABLE_TRANSIENT_TASKBAR = "disable-transient-taskbar"; public static final String REQUEST_UNSTASH_TASKBAR_IF_STASHED = "unstash-taskbar-if-stashed"; public static final String REQUEST_STASHED_TASKBAR_HEIGHT = "stashed-taskbar-height"; public static final String REQUEST_RECREATE_TASKBAR = "recreate-taskbar"; diff --git a/src/com/android/launcher3/util/DisplayController.java b/src/com/android/launcher3/util/DisplayController.java index f9f7ac0df1..226f2d93c7 100644 --- a/src/com/android/launcher3/util/DisplayController.java +++ b/src/com/android/launcher3/util/DisplayController.java @@ -42,6 +42,7 @@ import android.view.Display; import androidx.annotation.AnyThread; import androidx.annotation.UiThread; +import androidx.annotation.VisibleForTesting; import com.android.launcher3.Utilities; import com.android.launcher3.util.window.CachedDisplayInfo; @@ -63,6 +64,7 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable { private static final String TAG = "DisplayController"; private static final boolean DEBUG = false; + private static boolean sTransientTaskbarStatusForTests; public static final MainThreadInitializedObject INSTANCE = new MainThreadInitializedObject<>(DisplayController::new); @@ -128,8 +130,18 @@ public class DisplayController implements ComponentCallbacks, SafeCloseable { * Returns whether taskbar is transient. */ public static boolean isTransientTaskbar(Context context) { - return ENABLE_TRANSIENT_TASKBAR.get() - && getNavigationMode(context) == NavigationMode.NO_BUTTON; + return getNavigationMode(context) == NavigationMode.NO_BUTTON + && (Utilities.IS_RUNNING_IN_TEST_HARNESS + ? sTransientTaskbarStatusForTests + : ENABLE_TRANSIENT_TASKBAR.get()); + } + + /** + * Enables transient taskbar status for tests. + */ + @VisibleForTesting + public static void enableTransientTaskbarForTests(boolean enable) { + sTransientTaskbarStatusForTests = enable; } @Override diff --git a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java index f23a38c3f2..4a3507ed69 100644 --- a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java +++ b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java @@ -17,7 +17,9 @@ package com.android.launcher3.tapl; import static com.android.launcher3.tapl.LauncherInstrumentation.TASKBAR_RES_ID; +import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_DISABLE_BLOCK_TIMEOUT; import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_DISABLE_MANUAL_TASKBAR_STASHING; +import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_ENABLE_BLOCK_TIMEOUT; import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_ENABLE_MANUAL_TASKBAR_STASHING; import static com.android.launcher3.testing.shared.TestProtocol.REQUEST_STASHED_TASKBAR_HEIGHT; @@ -88,6 +90,7 @@ public final class LaunchedAppState extends Background { */ public Taskbar showTaskbar() { mLauncher.getTestInfo(REQUEST_ENABLE_MANUAL_TASKBAR_STASHING); + mLauncher.getTestInfo(REQUEST_ENABLE_BLOCK_TIMEOUT); try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck(); LauncherInstrumentation.Closable c1 = mLauncher.addContextLayer( @@ -114,6 +117,7 @@ public final class LaunchedAppState extends Background { } } finally { mLauncher.getTestInfo(REQUEST_DISABLE_MANUAL_TASKBAR_STASHING); + mLauncher.getTestInfo(REQUEST_DISABLE_BLOCK_TIMEOUT); } } diff --git a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java index 1212c3de01..c3ea14ae85 100644 --- a/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java +++ b/tests/tapl/com/android/launcher3/tapl/LauncherInstrumentation.java @@ -1850,6 +1850,20 @@ public final class LauncherInstrumentation { getTestInfo(TestProtocol.REQUEST_UNSTASH_TASKBAR_IF_STASHED); } + /** Blocks the taskbar from automatically stashing based on time. */ + public void enableBlockTimeout(boolean enable) { + getTestInfo(enable + ? TestProtocol.REQUEST_ENABLE_BLOCK_TIMEOUT + : TestProtocol.REQUEST_DISABLE_BLOCK_TIMEOUT); + } + + /** Enables transient taskbar for testing purposes only. */ + public void enableTransientTaskbar(boolean enable) { + getTestInfo(enable + ? TestProtocol.REQUEST_ENABLE_TRANSIENT_TASKBAR + : TestProtocol.REQUEST_DISABLE_TRANSIENT_TASKBAR); + } + /** * Recreates the taskbar (outside of tests this is done for certain configuration changes). * The expected behavior is that the taskbar retains its current state after being recreated. From 0844f2e8ef0c3152dbda50e46158b74a40b548cd Mon Sep 17 00:00:00 2001 From: Schneider Victor-tulias Date: Thu, 10 Nov 2022 11:22:33 -0800 Subject: [PATCH 206/429] Return to home when overview command fails. Returning a runnable list that doesn't get run later causes the overview command to be added to the pending command queue, but never gets removed. This causes following overview (and home on tablets) commands not to respond. Test: forcefully caused the error condition programmatically; checked the queue is cleared and the user is sent home. Fixes: 255851262 Change-Id: I9d2f54960c54963b1e7480a597d05911201c152b --- .../android/quickstep/OverviewCommandHelper.java | 2 +- .../android/quickstep/views/DesktopTaskView.java | 2 +- .../src/com/android/quickstep/views/TaskView.java | 14 ++++++++++---- 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java index 875b72cb34..5a09e021b2 100644 --- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java +++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java @@ -116,7 +116,7 @@ public class OverviewCommandHelper { */ @BinderThread public void addCommand(int type) { - if (mPendingCommands.size() > MAX_QUEUE_SIZE) { + if (mPendingCommands.size() >= MAX_QUEUE_SIZE) { return; } CommandInfo cmd = new CommandInfo(type); diff --git a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java index 2abd715fae..8c43fd108f 100644 --- a/quickstep/src/com/android/quickstep/views/DesktopTaskView.java +++ b/quickstep/src/com/android/quickstep/views/DesktopTaskView.java @@ -288,7 +288,7 @@ public class DesktopTaskView extends TaskView { public RunnableList launchTasks() { SystemUiProxy.INSTANCE.get(getContext()).showDesktopApps(); getRecentsView().startHome(); - return new RunnableList(); + return null; } @Nullable diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index 527a0d1b36..b7fbed5ab1 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -725,13 +725,14 @@ public class TaskView extends FrameLayout implements Reusable { /** * Launch of the current task (both live and inactive tasks) with an animation. */ + @Nullable public RunnableList launchTasks() { RecentsView recentsView = getRecentsView(); RemoteTargetHandle[] remoteTargetHandles = recentsView.mRemoteTargetHandles; - RunnableList runnableList = new RunnableList(); if (isRunningTask() && remoteTargetHandles != null) { if (!mIsClickableAsLiveTile) { - return runnableList; + Log.e(TAG, "TaskView is not clickable as a live tile; returning to home."); + return null; } mIsClickableAsLiveTile = false; @@ -756,11 +757,16 @@ public class TaskView extends FrameLayout implements Reusable { if (targets == null) { // If the recents animation is cancelled somehow between the parent if block and // here, try to launch the task as a non live tile task. - launchTaskAnimated(); + RunnableList runnableList = launchTaskAnimated(); + if (runnableList == null) { + Log.e(TAG, "Recents animation cancelled and cannot launch task as non-live tile" + + "; returning to home"); + } mIsClickableAsLiveTile = true; return runnableList; } + RunnableList runnableList = new RunnableList(); AnimatorSet anim = new AnimatorSet(); TaskViewUtils.composeRecentsLaunchAnimator( anim, this, targets.apps, @@ -797,10 +803,10 @@ public class TaskView extends FrameLayout implements Reusable { }); anim.start(); recentsView.onTaskLaunchedInLiveTileMode(); + return runnableList; } else { return launchTaskAnimated(); } - return runnableList; } /** From 592e2691f60bb65a49df4c1f5fd596b15696673f Mon Sep 17 00:00:00 2001 From: Sebastian Franco Date: Wed, 9 Nov 2022 16:42:01 -0800 Subject: [PATCH 207/429] Fix the wiggle reorder aniamtion stopping if dragging We were using the minimum span to calculate the cell position of the widget and if you move slightly because the minimum is usually smaller than the current size it would calculate wrong cell positions that are change more frequently because it's smaller. Also, I went back and moved performReorder(... CellLayout.MODE_SHOW_REORDER_HINT) with the alarm if block as it was before one of my refactors, it still works if they are separate but is harder to think about the logic if they are divided so it's better to all be in one block. Fix: 255421416 Test: manual testing, reordering and making sure the animation is playing well. Test: atest ReorderWidgets (to make sure the reorder is not broken) Change-Id: I3eff5bc9f21fda8f2f8908380397d8639ac15ff9 --- src/com/android/launcher3/Workspace.java | 30 ++++++++++-------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 27e1ba143b..a8def69304 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -2350,7 +2350,7 @@ public class Workspace extends PagedView } mTargetCell = findNearestArea((int) mDragViewVisualCenter[0], - (int) mDragViewVisualCenter[1], minSpanX, minSpanY, + (int) mDragViewVisualCenter[1], item.spanX, item.spanY, mDragTargetLayout, mTargetCell); int reorderX = mTargetCell[0]; int reorderY = mTargetCell[1]; @@ -2366,7 +2366,8 @@ public class Workspace extends PagedView mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], item.spanX, item.spanY, child, mTargetCell); - manageReorderOnDragOver(d, targetCellDistance, nearestDropOccupied, minSpanX, minSpanY); + manageReorderOnDragOver(d, targetCellDistance, nearestDropOccupied, minSpanX, minSpanY, + reorderX, reorderY); if (mDragMode == DRAG_MODE_CREATE_FOLDER || mDragMode == DRAG_MODE_ADD_TO_FOLDER || !nearestDropOccupied) { @@ -2378,26 +2379,23 @@ public class Workspace extends PagedView } protected void manageReorderOnDragOver(DragObject d, float targetCellDistance, - boolean nearestDropOccupied, int minSpanX, int minSpanY) { + boolean nearestDropOccupied, int minSpanX, int minSpanY, int reorderX, int reorderY) { ItemInfo item = d.dragInfo; final View child = (mDragInfo == null) ? null : mDragInfo.cell; - int reorderX = mTargetCell[0]; - int reorderY = mTargetCell[1]; - if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER) - && (mLastReorderX != reorderX || mLastReorderY != reorderY) - && targetCellDistance < mDragTargetLayout.getReorderRadius(mTargetCell, item.spanX, - item.spanY)) { - mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0], - (int) mDragViewVisualCenter[1], minSpanX, minSpanY, item.spanX, item.spanY, - child, mTargetCell, new int[2], CellLayout.MODE_SHOW_REORDER_HINT); - } - if (!nearestDropOccupied) { mDragTargetLayout.visualizeDropLocation(mTargetCell[0], mTargetCell[1], item.spanX, item.spanY, d); } else if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER) - && !mReorderAlarm.alarmPending()) { + && !mReorderAlarm.alarmPending() + && (mLastReorderX != reorderX || mLastReorderY != reorderY) + && targetCellDistance < mDragTargetLayout.getReorderRadius(mTargetCell, item.spanX, + item.spanY)) { + mLastReorderX = reorderX; + mLastReorderY = reorderY; + mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0], + (int) mDragViewVisualCenter[1], minSpanX, minSpanY, item.spanX, item.spanY, + child, mTargetCell, new int[2], CellLayout.MODE_SHOW_REORDER_HINT); // Otherwise, if we aren't adding to or creating a folder and there's no pending // reorder, then we schedule a reorder ReorderAlarmListener listener = new ReorderAlarmListener(mDragViewVisualCenter, @@ -2602,8 +2600,6 @@ public class Workspace extends PagedView mTargetCell = findNearestArea((int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], minSpanX, minSpanY, mDragTargetLayout, mTargetCell); - mLastReorderX = mTargetCell[0]; - mLastReorderY = mTargetCell[1]; mTargetCell = mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0], (int) mDragViewVisualCenter[1], minSpanX, minSpanY, spanX, spanY, From 584332202ccdb9d8bf634c192173094225706a53 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Thu, 10 Nov 2022 11:37:35 -0800 Subject: [PATCH 208/429] Only show split button for single fullscreen task if taskbar is present in Overview * Taskbar in overview allows second app to be selected so user wouldn't be stuck in split select state Fixes: 258543259 Test: Tested w/ flag on and off w/ one and multiple flags w/ fullscreen and split single focused task Change-Id: Ie588ad66fde4e012e08d8f5abbe1eef5a1a5db6b --- quickstep/src/com/android/quickstep/views/RecentsView.java | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 6286374752..ff0c984b6d 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -3544,7 +3544,8 @@ public abstract class RecentsView Date: Sun, 30 Oct 2022 16:50:32 -0700 Subject: [PATCH 209/429] Prevent dropping a drag from TaskbarAllApps in Overview * Don't close TaskbarAllApps once drag starts (see comment in code regarding needing multiple shared drag layers) * Hide app menu split options for taskbar in overview * One TODO is that the animation needs to be tweaked because the scale of the icon when it's returned is too large. * I think maybe we have to change the TaskbarDragController#mDragIconSize since that gets directly set from a resource. Unclear. Test: Dragged in TaskbarAllApps in overivew and in split select, app returned to original position and not taskbar Bug: 251747761 Change-Id: I785f34b0bdb0b0abfc440450494074f8dfe7c31a --- .../launcher3/taskbar/TaskbarDragController.java | 15 +++++++++++++-- .../taskbar/TaskbarLauncherStateController.java | 11 +++++++---- .../taskbar/TaskbarPopupController.java | 12 +++++++++++- .../allapps/TaskbarAllAppsController.java | 16 ++++++++++++++++ 4 files changed, 47 insertions(+), 7 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java index d7bb16e7a2..3045eca052 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java @@ -15,6 +15,7 @@ */ package com.android.launcher3.taskbar; +import static com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_ALL_APPS; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_ALL_APPS; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT; @@ -301,7 +302,12 @@ public class TaskbarDragController extends DragController im protected void callOnDragStart() { super.callOnDragStart(); // Pre-drag has ended, start the global system drag. - AbstractFloatingView.closeAllOpenViews(mActivity); + if (mDisallowGlobalDrag) { + AbstractFloatingView.closeAllOpenViewsExcept(mActivity, TYPE_TASKBAR_ALL_APPS); + } else { + AbstractFloatingView.closeAllOpenViews(mActivity); + } + startSystemDrag((BubbleTextView) mDragObject.originalView); } @@ -536,10 +542,15 @@ public class TaskbarDragController extends DragController im private View findTaskbarTargetForIconView(@NonNull View iconView) { Object tag = iconView.getTag(); + TaskbarViewController taskbarViewController = mControllers.taskbarViewController; + if (tag instanceof ItemInfo) { ItemInfo item = (ItemInfo) tag; - TaskbarViewController taskbarViewController = mControllers.taskbarViewController; if (item.container == CONTAINER_ALL_APPS || item.container == CONTAINER_PREDICTION) { + if (mDisallowGlobalDrag) { + // We're dragging in taskbarAllApps, we don't have folders or shortcuts + return iconView; + } // Since all apps closes when the drag starts, target the all apps button instead. return taskbarViewController.getAllAppsButtonView(); } else if (item.container >= 0) { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index fc26f5fe7f..ea5df87d35 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -119,10 +119,13 @@ import java.util.StringJoiner; mLauncherState = finalState; updateStateForFlag(FLAG_TRANSITION_STATE_RUNNING, false); applyState(); - mControllers.taskbarDragController.setDisallowGlobalDrag( - (finalState instanceof OverviewState)); - mControllers.taskbarDragController.setDisallowLongClick( - finalState == LauncherState.OVERVIEW_SPLIT_SELECT); + boolean disallowGlobalDrag = finalState instanceof OverviewState; + boolean disallowLongClick = finalState == LauncherState.OVERVIEW_SPLIT_SELECT; + mControllers.taskbarDragController.setDisallowGlobalDrag(disallowGlobalDrag); + mControllers.taskbarDragController.setDisallowLongClick(disallowLongClick); + mControllers.taskbarAllAppsController.setDisallowGlobalDrag(disallowGlobalDrag); + mControllers.taskbarAllAppsController.setDisallowLongClick(disallowLongClick); + mControllers.taskbarPopupController.setHideSplitOptions(disallowGlobalDrag); } }; diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java index da6dab1e10..9b27c9d026 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarPopupController.java @@ -75,6 +75,7 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba // Initialized in init. private TaskbarControllers mControllers; + private boolean mHideSplitOptions; public TaskbarPopupController(TaskbarActivityContext context) { mContext = context; @@ -100,6 +101,10 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba mPopupDataProvider.setDeepShortcutMap(deepShortcutMapCopy); } + public void setHideSplitOptions(boolean hideSplitOptions) { + mHideSplitOptions = hideSplitOptions; + } + private void updateNotificationDots(Predicate updatedDots) { final PackageUserKey packageUserKey = new PackageUserKey(null, null); Predicate matcher = info -> !packageUserKey.updateFromItemInfo(info) @@ -186,11 +191,16 @@ public class TaskbarPopupController implements TaskbarControllers.LoggableTaskba // TODO(b/227800345): Add "Split bottom" option when tablet is in portrait mode. private Stream getSystemShortcuts() { // concat a Stream of split options with a Stream of APP_INFO + Stream appInfo = Stream.of(APP_INFO); + if (mHideSplitOptions) { + return appInfo; + } + return Stream.concat( Utilities.getSplitPositionOptions(mContext.getDeviceProfile()) .stream() .map(this::createSplitShortcutFactory), - Stream.of(APP_INFO) + appInfo ); } diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java index 85c63183ad..4dc8d47f05 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsController.java @@ -48,6 +48,8 @@ public final class TaskbarAllAppsController { private AppInfo[] mApps; private int mAppsModelFlags; private List mPredictedApps; + private boolean mDisallowGlobalDrag; + private boolean mDisallowLongClick; /** Initialize the controller. */ public void init(TaskbarControllers controllers, boolean allAppsVisible) { @@ -78,6 +80,14 @@ public final class TaskbarAllAppsController { } } + public void setDisallowGlobalDrag(boolean disableDragForOverviewState) { + mDisallowGlobalDrag = disableDragForOverviewState; + } + + public void setDisallowLongClick(boolean disallowLongClick) { + mDisallowLongClick = disallowLongClick; + } + /** Updates the current predictions. */ public void setPredictedApps(List predictedApps) { if (!FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get()) { @@ -123,6 +133,12 @@ public final class TaskbarAllAppsController { mAppsView.getFloatingHeaderView() .findFixedRowByType(PredictionRowView.class) .setPredictedApps(mPredictedApps); + // 1 alternative that would be more work: + // Create a shared drag layer between taskbar and taskbarAllApps so that when dragging + // starts and taskbarAllApps can close, but the drag layer that the view is being dragged in + // doesn't also close + overlayContext.getDragController().setDisallowGlobalDrag(mDisallowGlobalDrag); + overlayContext.getDragController().setDisallowLongClick(mDisallowLongClick); } From 96c72745aefa5ddca08dbcf5393d5481d89ccd78 Mon Sep 17 00:00:00 2001 From: Anushree Ganjam Date: Tue, 8 Nov 2022 03:38:54 +0000 Subject: [PATCH 210/429] Add ImpressionLogger to StatsLogManager go/toast-search-impression-logging Bug: 204781396 Test: Manual Change-Id: If00027581000d315590ce2fac46428cbf173da49 --- .../logging/StatsLogCompatManager.java | 108 ++++++++++++++++-- .../android/launcher3/logging/InstanceId.java | 1 - .../launcher3/logging/StatsLogManager.java | 90 +++++++++++++++ 3 files changed, 190 insertions(+), 9 deletions(-) diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java index dac5a31006..0ef4597c47 100644 --- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java +++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java @@ -62,11 +62,14 @@ import com.android.launcher3.model.BgDataModel; import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.util.Executors; +import com.android.launcher3.util.IntArray; import com.android.launcher3.util.LogConfig; import com.android.launcher3.views.ActivityContext; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; import com.android.systemui.shared.system.SysUiStatsLog; +import java.util.ArrayList; +import java.util.List; import java.util.Optional; import java.util.OptionalInt; import java.util.concurrent.CopyOnWriteArrayList; @@ -85,6 +88,7 @@ public class StatsLogCompatManager extends StatsLogManager { private static final String TAG = "StatsLog"; private static final String LATENCY_TAG = "StatsLatencyLog"; + private static final String IMPRESSION_TAG = "StatsImpressionLog"; private static final boolean IS_VERBOSE = Utilities.isPropertyEnabled(LogConfig.STATSLOG); private static final InstanceId DEFAULT_INSTANCE_ID = InstanceId.fakeInstanceId(0); // LauncherAtom.ItemInfo.getDefaultInstance() should be used but until launcher proto migrates @@ -119,7 +123,12 @@ public class StatsLogCompatManager extends StatsLogManager { @Override protected StatsLatencyLogger createLatencyLogger() { - return new StatsCompatLatencyLogger(mContext, mActivityContext); + return new StatsCompatLatencyLogger(); + } + + @Override + protected StatsImpressionLogger createImpressionLogger() { + return new StatsCompatImpressionLogger(); } /** @@ -466,8 +475,6 @@ public class StatsLogCompatManager extends StatsLogManager { * Helps to construct and log statsd compatible latency events. */ private static class StatsCompatLatencyLogger implements StatsLatencyLogger { - private final Context mContext; - private final Optional mActivityContext; private InstanceId mInstanceId = DEFAULT_INSTANCE_ID; private LatencyType mType = LatencyType.UNKNOWN; private int mPackageId = 0; @@ -475,11 +482,6 @@ public class StatsLogCompatManager extends StatsLogManager { private int mQueryLength = -1; private int mSubEventType = 0; - StatsCompatLatencyLogger(Context context, ActivityContext activityContext) { - mContext = context; - mActivityContext = Optional.ofNullable(activityContext); - } - @Override public StatsLatencyLogger withInstanceId(InstanceId instanceId) { this.mInstanceId = instanceId; @@ -539,6 +541,96 @@ public class StatsLogCompatManager extends StatsLogManager { } } + /** + * Helps to construct and log statsd compatible impression events. + */ + private static class StatsCompatImpressionLogger implements StatsImpressionLogger { + private final IntArray mResultTypeList = new IntArray(); + private final IntArray mResultCountList = new IntArray(); + private final List mAboveKeyboardList = new ArrayList<>(); + private InstanceId mInstanceId = DEFAULT_INSTANCE_ID; + private State mLauncherState = State.UNKNOWN; + private int mQueryLength = -1; + + @Override + public StatsImpressionLogger withInstanceId(InstanceId instanceId) { + this.mInstanceId = instanceId; + return this; + } + + @Override + public StatsImpressionLogger withState(State state) { + this.mLauncherState = state; + return this; + } + + @Override + public StatsImpressionLogger withQueryLength(int queryLength) { + this.mQueryLength = queryLength; + return this; + } + + @Override + public StatsImpressionLogger withResultType(IntArray resultType) { + this.mResultTypeList.clear(); + this.mResultTypeList.addAll(resultType); + return this; + } + + @Override + public StatsImpressionLogger withResultCount(IntArray resultCount) { + this.mResultCountList.clear(); + this.mResultCountList.addAll(resultCount); + return this; + } + + @Override + public StatsImpressionLogger withAboveKeyboard(List aboveKeyboard) { + this.mAboveKeyboardList.clear(); + this.mAboveKeyboardList.addAll(aboveKeyboard); + return this; + } + + @Override + public void log(EventEnum event) { + boolean [] mAboveKeyboard = new boolean[mAboveKeyboardList.size()]; + for (int i = 0; i < mAboveKeyboardList.size(); i++) { + mAboveKeyboard[i] = mAboveKeyboardList.get(i); + } + if (IS_VERBOSE) { + String name = (event instanceof Enum) ? ((Enum) event).name() : + event.getId() + ""; + StringBuilder logStringBuilder = new StringBuilder("\n"); + logStringBuilder.append(String.format("InstanceId:%s ", mInstanceId)); + logStringBuilder.append(String.format("ImpressionEvent:%s ", name)); + logStringBuilder.append(String.format("LauncherState = %s ", mLauncherState)); + logStringBuilder.append(String.format("QueryLength = %s ", mQueryLength)); + for (int i = 0; i < mResultTypeList.size(); i++) { + logStringBuilder.append(String.format( + "\n ResultType = %s with ResultCount = %s with is_above_keyboard = %s", + mResultTypeList.get(i), mResultCountList.get(i), + mAboveKeyboard[i])); + } + Log.d(IMPRESSION_TAG, logStringBuilder.toString()); + } + + + + SysUiStatsLog.write(SysUiStatsLog.LAUNCHER_IMPRESSION_EVENT, + event.getId(), // event_id + mInstanceId.getId(), // instance_id + mLauncherState.getLauncherState(), // state + mQueryLength, // query_length + //result type list + mResultTypeList.toArray(), + // result count list + mResultCountList.toArray(), + // above keyboard list + mAboveKeyboard + ); + } + } + private static int getCardinality(LauncherAtom.ItemInfo info) { if (Utilities.IS_RUNNING_IN_TEST_HARNESS) { return 0; diff --git a/src/com/android/launcher3/logging/InstanceId.java b/src/com/android/launcher3/logging/InstanceId.java index 3c4a644053..5bbe07c9ad 100644 --- a/src/com/android/launcher3/logging/InstanceId.java +++ b/src/com/android/launcher3/logging/InstanceId.java @@ -47,7 +47,6 @@ public final class InstanceId implements Parcelable { this(in.readInt()); } - @VisibleForTesting public int getId() { return mId; } diff --git a/src/com/android/launcher3/logging/StatsLogManager.java b/src/com/android/launcher3/logging/StatsLogManager.java index fcc5d8615d..0e42d58ce8 100644 --- a/src/com/android/launcher3/logging/StatsLogManager.java +++ b/src/com/android/launcher3/logging/StatsLogManager.java @@ -32,9 +32,12 @@ import com.android.launcher3.logger.LauncherAtom.ContainerInfo; import com.android.launcher3.logger.LauncherAtom.FromState; import com.android.launcher3.logger.LauncherAtom.ToState; import com.android.launcher3.model.data.ItemInfo; +import com.android.launcher3.util.IntArray; import com.android.launcher3.util.ResourceBasedOverride; import com.android.launcher3.views.ActivityContext; +import java.util.List; + /** * Handles the user event logging in R+. * @@ -838,6 +841,77 @@ public class StatsLogManager implements ResourceBasedOverride { } } + /** + * Helps to construct and log impression event. + */ + public interface StatsImpressionLogger { + + enum State { + UNKNOWN(0), + ALLAPPS(1), + SEARCHBOX_WIDGET(2); + private final int mLauncherState; + + State(int id) { + this.mLauncherState = id; + } + + public int getLauncherState() { + return mLauncherState; + } + } + + /** + * Sets {@link InstanceId} of log message. + */ + default StatsImpressionLogger withInstanceId(InstanceId instanceId) { + return this; + } + + /** + * Sets {@link State} of impression event. + */ + default StatsImpressionLogger withState(State state) { + return this; + } + + /** + * Sets query length of the event. + */ + default StatsImpressionLogger withQueryLength(int queryLength) { + return this; + } + + /** + * Sets list of {@link com.android.app.search.ResultType} for the impression event. + */ + default StatsImpressionLogger withResultType(IntArray resultType) { + return this; + } + + /** + * Sets list of count for each of {@link com.android.app.search.ResultType} for the + * impression event. + */ + default StatsImpressionLogger withResultCount(IntArray resultCount) { + return this; + } + + /** + * Sets list of boolean for each of {@link com.android.app.search.ResultType} that indicates + * if this result is above keyboard or not for the impression event. + */ + default StatsImpressionLogger withAboveKeyboard(List aboveKeyboard) { + return this; + } + + /** + * Builds the final message and logs it as {@link EventEnum}. + */ + default void log(EventEnum event) { + } + } + /** * Returns new logger object. */ @@ -860,6 +934,17 @@ public class StatsLogManager implements ResourceBasedOverride { return logger; } + /** + * Returns new impression logger object. + */ + public StatsImpressionLogger impressionLogger() { + StatsImpressionLogger logger = createImpressionLogger(); + if (mInstanceId != null) { + logger.withInstanceId(mInstanceId); + } + return logger; + } + /** * Returns a singleton KeyboardStateManager. */ @@ -880,6 +965,11 @@ public class StatsLogManager implements ResourceBasedOverride { }; } + protected StatsImpressionLogger createImpressionLogger() { + return new StatsImpressionLogger() { + }; + } + /** * Sets InstanceId to every new {@link StatsLogger} object returned by {@link #logger()} when * not-null. From 60240139536e7df688517cb7aac82301a1a464b8 Mon Sep 17 00:00:00 2001 From: Anushree Ganjam Date: Tue, 8 Nov 2022 02:56:10 +0000 Subject: [PATCH 211/429] Add SearchResultCode to onSearchResult() Bug: 204781396 Test: Manual Change-Id: Ia776be0fdd42e1d5fa405911e28d9b0a12c1fdde --- .../allapps/ActivityAllAppsContainerView.java | 12 +++++++++++- .../android/launcher3/search/SearchCallback.java | 16 ++++++++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java index 08b42cd24c..c86f08d1fb 100644 --- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java @@ -102,6 +102,16 @@ public class ActivityAllAppsContainerView results, int searchResultCode) { + setSearchResults(results); + } + private void animateToSearchState(boolean goingToSearch) { animateToSearchState(goingToSearch, DEFAULT_SEARCH_TRANSITION_DURATION_MS); } @@ -311,7 +321,7 @@ public class ActivityAllAppsContainerView { + // Search Result Codes + int UNKNOWN = 0; + int INTERMEDIATE = 1; + int FINAL = 2; + /** * Called when the search from primary source is complete. * @@ -31,6 +36,17 @@ public interface SearchCallback { */ void onSearchResult(String query, ArrayList items); + /** + * Called when the search from primary source is complete. + * + * @param items list of search results + * @param searchResultCode indicates if the result is final or intermediate for a given query + * since we can get search results from multiple sources. + */ + default void onSearchResult(String query, ArrayList items, int searchResultCode) { + onSearchResult(query, items); + } + /** * Called when the search results should be cleared. */ From c36593139c7d34687692e376f51acfd1f1e11868 Mon Sep 17 00:00:00 2001 From: Anushree Ganjam Date: Fri, 11 Nov 2022 19:18:14 +0000 Subject: [PATCH 212/429] Introduce imeHeight in KeyboardStateManager. Bug: 204781396 Test: Manual Change-Id: If9dc9427a73ab22d6418edb9c954e79fd0958395 --- .../launcher3/logging/KeyboardStateManager.java | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/com/android/launcher3/logging/KeyboardStateManager.java b/src/com/android/launcher3/logging/KeyboardStateManager.java index 3103af1bd4..6dc0a0be22 100644 --- a/src/com/android/launcher3/logging/KeyboardStateManager.java +++ b/src/com/android/launcher3/logging/KeyboardStateManager.java @@ -24,6 +24,7 @@ import android.os.SystemClock; */ public class KeyboardStateManager { private long mUpdatedTime; + private int mImeHeight; public enum KeyboardState { NO_IME_ACTION, @@ -58,4 +59,18 @@ public class KeyboardStateManager { mUpdatedTime = SystemClock.elapsedRealtime(); mKeyboardState = keyboardState; } + + /** + * Returns keyboard's current height. + */ + public int getImeHeight() { + return mImeHeight; + } + + /** + * Setter method to set keyboard height. + */ + public void setImeHeight(int imeHeight) { + mImeHeight = imeHeight; + } } From c0dc93d38476d41f7ff913f25184433df98ea397 Mon Sep 17 00:00:00 2001 From: Federico Baron Date: Tue, 1 Nov 2022 11:31:57 -0700 Subject: [PATCH 213/429] Add flag for 'Improve widget picker UX on large display form factor' here's how we plan on improving widget picker under this flag: https://docs.google.com/presentation/d/1mcdjJWutr-ZGbPOndhe1D8YCdCh6EbO8eNyK3YMMVEY/edit#slide=id.g1571d496dda_0_145 Test: N/A Bug: 256684299 Change-Id: I365516b43e70a37c7b93e089b6822c58a0f81540 --- src/com/android/launcher3/config/FeatureFlags.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 3a580203c6..d98a7f378a 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -323,6 +323,10 @@ public final class FeatureFlags { public static final BooleanFlag SHOW_DOT_PAGINATION = getDebugFlag( "SHOW_DOT_PAGINATION", false, "Enable showing dot pagination in workspace"); + public static final BooleanFlag LARGE_SCREEN_WIDGET_PICKER = getDebugFlag( + "LARGE_SCREEN_WIDGET_PICKER", false, "Enable new widget picker that takes " + + "advantage of large screen format"); + public static final BooleanFlag ENABLE_TOAST_IMPRESSION_LOGGING = getDebugFlag( "ENABLE_TOAST_IMPRESSION_LOGGING", false, "Enable toast impression logging"); From d930011746e7b06f147512a3d7849efa7d62e9e3 Mon Sep 17 00:00:00 2001 From: Colin Cross Date: Fri, 11 Nov 2022 23:22:49 +0000 Subject: [PATCH 214/429] Add a lint baseline for Launcher3 The lint version in tm-qpr-dev incorrectly flags BaseActivity.java. Add an entry to lint-baseline.xml file to silence the incorrect error. The newer version of lint in master doesn't have the false positive. Bug: 258754271 Bug: 256019562 Test: m RUN_ERROR_PRONE=true javac-check lint-check Change-Id: I2fd22e96c8e89b7dc25132089e36d599e012e747 Merged-In: If02f87ef74c73321afa3427d845ad80539292b30 --- lint-baseline-launcher3.xml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/lint-baseline-launcher3.xml b/lint-baseline-launcher3.xml index 107a34694b..a9dc0c604e 100644 --- a/lint-baseline-launcher3.xml +++ b/lint-baseline-launcher3.xml @@ -606,4 +606,20 @@ column="61"/> + + + + + + + + From 2a8ed8a3e88078e7428b949e418731aba8d9ea4a Mon Sep 17 00:00:00 2001 From: Federico Baron Date: Mon, 14 Nov 2022 10:13:28 -0800 Subject: [PATCH 215/429] Make settings button touch target size larger The touch target of this item was 32dp, now we change it to 48dp to make it easier to interact with the button Fix: 179116216 Test: enable talkback, then go to home settings -> suggestions -> suggestions on home screen. Turn on suggestions on home screen. Notice touch target size is small in settings button of toast. Change-Id: I5b8b2ac99f3843cf6fe838cf572565a334e23b2a --- res/values/dimens.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 0a28b6c62f..5e7ac20474 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -333,7 +333,7 @@ 48dp - 32dp + 48dp 8dp 6dp 72dp From 9787ae6ad9be6caf2a0d4c5f3ec1a1e950772bda Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Wed, 9 Nov 2022 10:48:09 -0800 Subject: [PATCH 216/429] Allow transient taskbar to unstash over soft ime Bug: 255818649 Test: pull up ime, swipe to reveal taskbar Change-Id: Ibae77c8a29d06093823f2421fbf851979f9babed --- .../launcher3/taskbar/TaskbarStashController.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 72ae1d1c31..5b0b3a2219 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -745,6 +745,11 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba mIsImeShowing = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_IME_SHOWING); mIsImeSwitcherShowing = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_IME_SWITCHER_SHOWING); if (!mIsSystemGestureInProgress) { + if (mIsImeShowing || mIsImeSwitcherShowing) { + // Hide taskbar when IME is shown. + updateStateForFlag(FLAG_STASHED_IN_APP_AUTO, true); + } + updateStateForFlag(FLAG_STASHED_IN_APP_IME, shouldStashForIme()); animDuration = TASKBAR_STASH_DURATION_FOR_IME; startDelay = getTaskbarStashStartDelayForIme(); @@ -758,8 +763,12 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba * * in small screen AND * * 3 button nav AND * * landscape (or seascape) + * We do not stash if taskbar is transient */ private boolean shouldStashForIme() { + if (DisplayController.isTransientTaskbar(mActivity)) { + return false; + } return (mIsImeShowing || mIsImeSwitcherShowing) && !(isPhoneMode() && mActivity.isThreeButtonNav() && mActivity.getDeviceProfile().isLandscape); From 5eba9000df29708d72393165cddb0f3f35046893 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Mon, 14 Nov 2022 12:28:20 -0800 Subject: [PATCH 217/429] Update transient taskbar transition duration to match spec (417ms). Bug: 246632728 Bug: 246641848 Test: manual Change-Id: If3f73774444c6074a81101d91d291ef33edcaf9c --- .../android/launcher3/QuickstepTransitionManager.java | 1 + .../launcher3/taskbar/LauncherTaskbarUIController.java | 9 ++++++--- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 1b47939d04..dcad873ff6 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -194,6 +194,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener public static final int SPLIT_DIVIDER_ANIM_DURATION = 100; public static final int CONTENT_ALPHA_DURATION = 217; + public static final int TRANSIENT_TASKBAR_TRANSITION_DURATION = 417; public static final int TASKBAR_TO_APP_DURATION = 600; // TODO(b/236145847): Tune TASKBAR_TO_HOME_DURATION to 383 after conflict with unlock animation // is solved. diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index beab56c6a4..0945bf2d1d 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -17,6 +17,7 @@ package com.android.launcher3.taskbar; import static android.view.InsetsState.ITYPE_EXTRA_NAVIGATION_BAR; +import static com.android.launcher3.QuickstepTransitionManager.TRANSIENT_TASKBAR_TRANSITION_DURATION; import static com.android.launcher3.taskbar.TaskbarLauncherStateController.FLAG_RESUMED; import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS; @@ -157,9 +158,11 @@ public class LauncherTaskbarUIController extends TaskbarUIController { isResumed, fromInit, /* startAnimation= */ true, - !isResumed - ? QuickstepTransitionManager.TASKBAR_TO_APP_DURATION - : QuickstepTransitionManager.TASKBAR_TO_HOME_DURATION); + DisplayController.isTransientTaskbar(mLauncher) + ? TRANSIENT_TASKBAR_TRANSITION_DURATION + : (!isResumed + ? QuickstepTransitionManager.TASKBAR_TO_APP_DURATION + : QuickstepTransitionManager.TASKBAR_TO_HOME_DURATION)); } @Nullable From 7a382f139d0bc5077d36cdd3d4e53b7fa30fd33d Mon Sep 17 00:00:00 2001 From: Sihua Ma Date: Thu, 10 Nov 2022 15:48:26 -0800 Subject: [PATCH 218/429] Making talkback focus on the widget after the resize Fix: 216386890 Test: Manual Change-Id: I79b0280c0f24a81be44e1578755ed90cf3343f88 --- .../accessibility/LauncherAccessibilityDelegate.java | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java index dd47592e2e..063b82e0d9 100644 --- a/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java +++ b/src/com/android/launcher3/accessibility/LauncherAccessibilityDelegate.java @@ -1,5 +1,7 @@ package com.android.launcher3.accessibility; +import static android.view.accessibility.AccessibilityEvent.TYPE_VIEW_FOCUSED; +import static android.view.accessibility.AccessibilityNodeInfo.ACTION_ACCESSIBILITY_FOCUS; import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK; import static com.android.launcher3.LauncherState.NORMAL; @@ -172,7 +174,11 @@ public class LauncherAccessibilityDelegate extends BaseAccessibilityDelegate { + host.requestFocus(); + host.sendAccessibilityEvent(TYPE_VIEW_FOCUSED); + host.performAccessibilityAction(ACTION_ACCESSIBILITY_FOCUS, null); + }); return true; } else if (action == DEEP_SHORTCUTS || action == SHORTCUTS_AND_NOTIFICATIONS) { BubbleTextView btv = host instanceof BubbleTextView ? (BubbleTextView) host From 2426514bf6bdd0ba7ed696439cd47fd1b1b67e60 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Mon, 14 Nov 2022 21:19:44 +0000 Subject: [PATCH 219/429] Put IDP.getDeviceProfile logging behind a feature flag - To avoid memory regression in performance testse Fix: 257359801 Test: manual Change-Id: I5ed768d90dba149eeb8f7be7d1d229b0b599a485 --- src/com/android/launcher3/InvariantDeviceProfile.java | 3 ++- src/com/android/launcher3/config/FeatureFlags.java | 3 +++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index ca92aa48f6..3d7d14f1ab 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -17,6 +17,7 @@ package com.android.launcher3; import static com.android.launcher3.Utilities.dpiFromPx; +import static com.android.launcher3.config.FeatureFlags.ENABLE_DEVICE_PROFILE_LOGGING; import static com.android.launcher3.config.FeatureFlags.ENABLE_TWO_PANEL_HOME; import static com.android.launcher3.testing.shared.ResourceUtils.INVALID_RESOURCE_HANDLE; import static com.android.launcher3.util.DisplayController.CHANGE_DENSITY; @@ -648,7 +649,7 @@ public class InvariantDeviceProfile { float screenHeight = config.screenHeightDp * res.getDisplayMetrics().density; int rotation = WindowManagerProxy.INSTANCE.get(context).getRotation(context); - if (Utilities.IS_DEBUG_DEVICE) { + if (Utilities.IS_DEBUG_DEVICE && ENABLE_DEVICE_PROFILE_LOGGING.get()) { StringWriter stringWriter = new StringWriter(); PrintWriter printWriter = new PrintWriter(stringWriter); DisplayController.INSTANCE.get(context).dump(printWriter); diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index d98a7f378a..f23b8623d6 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -330,6 +330,9 @@ public final class FeatureFlags { public static final BooleanFlag ENABLE_TOAST_IMPRESSION_LOGGING = getDebugFlag( "ENABLE_TOAST_IMPRESSION_LOGGING", false, "Enable toast impression logging"); + public static final BooleanFlag ENABLE_DEVICE_PROFILE_LOGGING = new DeviceFlag( + "ENABLE_DEVICE_PROFILE_LOGGING", false, "Allows DeviceProfile logging"); + public static void initialize(Context context) { synchronized (sDebugFlags) { for (DebugFlag flag : sDebugFlags) { From 7eac37254b13b39d4729ab026bdbd9d5261f3fe8 Mon Sep 17 00:00:00 2001 From: Saumya Prakash Date: Mon, 14 Nov 2022 22:38:21 +0000 Subject: [PATCH 220/429] Add a flag for the redesigned Gesture Nav Tutorial We plan to improve the gesture navigation education tutorial as discussed and shown in go/gesture-nav-education. Test: N/A Bug: 241813570 Change-Id: I2ad8d12cf14c1b3f0eec3208ad12a24ac54b9dbc --- src/com/android/launcher3/config/FeatureFlags.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index d98a7f378a..9466576af1 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -327,6 +327,10 @@ public final class FeatureFlags { "LARGE_SCREEN_WIDGET_PICKER", false, "Enable new widget picker that takes " + "advantage of large screen format"); + public static final BooleanFlag ENABLE_NEW_GESTURE_NAV_TUTORIAL = getDebugFlag( + "ENABLE_NEW_GESTURE_NAV_TUTORIAL", false, + "Enable the redesigned gesture navigation tutorial"); + public static final BooleanFlag ENABLE_TOAST_IMPRESSION_LOGGING = getDebugFlag( "ENABLE_TOAST_IMPRESSION_LOGGING", false, "Enable toast impression logging"); From b2711a81e6565e50a1423567ae7f0e14451f2e42 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Mon, 14 Nov 2022 15:20:25 -0800 Subject: [PATCH 221/429] Update unsupported split app error text Bug: 258822425 Change-Id: I8ac24d094d14a5f65a1d83303a9fd087c76bf066 --- quickstep/res/values/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml index c0d52a42bd..d7fb419a60 100644 --- a/quickstep/res/values/strings.xml +++ b/quickstep/res/values/strings.xml @@ -204,7 +204,7 @@ Tap another app to use splitscreen - App does not support split-screen. + Choose another app to use split screen This action isn\'t allowed by the app or your organization From 39a3ac6fe5b8e2003bc320925be8da4fecafa503 Mon Sep 17 00:00:00 2001 From: Pat Manning Date: Mon, 31 Oct 2022 15:27:41 +0000 Subject: [PATCH 222/429] Update string for "swipe to go home" when in button nav. Bug: 252938555 Test: manual Change-Id: Id52867ec6a9b82a44ab0a803a9824258d9ad4044 --- quickstep/res/values/strings.xml | 2 ++ .../quickstep/interaction/AllSetActivity.java | 12 ++++++++---- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml index c0d52a42bd..8f6f60b0af 100644 --- a/quickstep/res/values/strings.xml +++ b/quickstep/res/values/strings.xml @@ -187,6 +187,8 @@ All set! Swipe up to go Home + + Tap the home button to go to your home screen You\u2019re ready to start using your phone diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java index 8986c054dd..897b55949c 100644 --- a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java +++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java @@ -53,6 +53,7 @@ import android.widget.TextView; import androidx.annotation.Nullable; import androidx.core.graphics.ColorUtils; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; @@ -120,10 +121,9 @@ public class AllSetActivity extends Activity { mContentView = findViewById(R.id.content_view); mSwipeUpShift = getResources().getDimension(R.dimen.allset_swipe_up_shift); - boolean isTablet = InvariantDeviceProfile.INSTANCE.get(getApplicationContext()) - .getDeviceProfile(this).isTablet; + DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this); TextView subtitle = findViewById(R.id.subtitle); - subtitle.setText(isTablet + subtitle.setText(dp.isTablet ? R.string.allset_description_tablet : R.string.allset_description); TextView tv = findViewById(R.id.navigation_settings); @@ -137,7 +137,11 @@ public class AllSetActivity extends Activity { } }); - findViewById(R.id.hint).setAccessibilityDelegate(new SkipButtonAccessibilityDelegate()); + TextView hintTextView = findViewById(R.id.hint); + if (!dp.isGestureMode) { + hintTextView.setText(R.string.allset_button_hint); + } + hintTextView.setAccessibilityDelegate(new SkipButtonAccessibilityDelegate()); mTISBindHelper = new TISBindHelper(this, this::onTISConnected); mVibrator = getSystemService(Vibrator.class); From 3dad4fec9f82b8c8553ad8b7ded8baddb1f0392c Mon Sep 17 00:00:00 2001 From: Sam Dubey Date: Tue, 15 Nov 2022 13:22:08 +0000 Subject: [PATCH 223/429] Revert "Reorder widgets no longer overlaps when no space is avai..." Revert "Reorder widgets no longer overlaps when no space is avai..." Revert submission 20427045-258023561 Reason for revert: Likely causing NPE while running launcher shortcut tests (Part of DM+Platinum monitor rotation. The revert won't be submitted if proven otherwise) Bug: 259234533 Reverted Changes: Ie599f7cb7:Reorder widgets no longer overlaps when no space i... I04b262ecc:Reorder widgets no longer overlaps when no space i... Change-Id: I4cc552588c8099356bc3f05c4c63d17a524f2a24 --- src/com/android/launcher3/CellLayout.java | 51 +++++++------------ src/com/android/launcher3/Workspace.java | 3 +- .../launcher3/folder/FolderPagedView.java | 2 +- 3 files changed, 21 insertions(+), 35 deletions(-) diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index e500e59369..de2a1f91ed 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -1651,19 +1651,8 @@ public class CellLayout extends ViewGroup { } } - /** - * Returns a "reorder" where we simply drop the item in the closest empty space, without moving - * any other item in the way. - * - * @param pixelX X coordinate in pixels in the screen - * @param pixelY Y coordinate in pixels in the screen - * @param spanX horizontal cell span - * @param spanY vertical cell span - * @return the configuration that represents the found reorder - */ - private ItemConfiguration closestEmptySpaceReorder(int pixelX, int pixelY, int minSpanX, - int minSpanY, int spanX, int spanY) { - ItemConfiguration solution = new ItemConfiguration(); + private ItemConfiguration findConfigurationNoShuffle(int pixelX, int pixelY, int minSpanX, int minSpanY, + int spanX, int spanY, View dragView, ItemConfiguration solution) { int[] result = new int[2]; int[] resultSpan = new int[2]; findNearestVacantArea(pixelX, pixelY, minSpanX, minSpanY, spanX, spanY, result, @@ -1708,7 +1697,7 @@ public class CellLayout extends ViewGroup { boolean isNearestDropLocationOccupied(int pixelX, int pixelY, int spanX, int spanY, View dragView, int[] result) { - result = findNearestAreaIgnoreOccupied(pixelX, pixelY, spanX, spanY, result); + result = findNearestArea(pixelX, pixelY, spanX, spanY, result); getViewsIntersectingRegion(result[0], result[1], spanX, spanY, dragView, null, mIntersectingViews); return !mIntersectingViews.isEmpty(); @@ -2258,8 +2247,7 @@ public class CellLayout extends ViewGroup { //TODO(adamcohen) b/151776141 use the items visual center for the direction vector int[] targetDestination = new int[2]; - findNearestAreaIgnoreOccupied(dragViewCenterX, dragViewCenterY, spanX, spanY, - targetDestination); + findNearestArea(dragViewCenterX, dragViewCenterY, spanX, spanY, targetDestination); Rect dragRect = new Rect(); cellToRect(targetDestination[0], targetDestination[1], spanX, spanY, dragRect); dragRect.offset(dragViewCenterX - dragRect.centerX(), dragViewCenterY - dragRect.centerY()); @@ -2412,7 +2400,7 @@ public class CellLayout extends ViewGroup { // We find the nearest cell into which we would place the dragged item, assuming there's // nothing in its way. int result[] = new int[2]; - result = findNearestAreaIgnoreOccupied(pixelX, pixelY, spanX, spanY, result); + result = findNearestArea(pixelX, pixelY, spanX, spanY, result); boolean success; // First we try the exact nearest position of the item being dragged, @@ -2457,21 +2445,19 @@ public class CellLayout extends ViewGroup { } /** - * Returns a "reorder" if there is empty space without rearranging anything. + * Returns a "reorder" where we simply drop the item in the closest empty space, without moving + * any other item in the way. * * @param pixelX X coordinate in pixels in the screen * @param pixelY Y coordinate in pixels in the screen * @param spanX horizontal cell span * @param spanY vertical cell span - * @param dragView view being dragged in reorder * @return the configuration that represents the found reorder */ - public ItemConfiguration dropInPlaceSolution(int pixelX, int pixelY, int spanX, - int spanY, View dragView) { + public ItemConfiguration closestEmptySpaceReorder(int pixelX, int pixelY, int spanX, + int spanY) { int[] result = new int[2]; - if (isNearestDropLocationOccupied(pixelX, pixelY, spanX, spanY, dragView, result)) { - result[0] = result[1] = -1; - } + result = findNearestArea(pixelX, pixelY, spanX, spanY, result); ItemConfiguration solution = new ItemConfiguration(); copyCurrentStateToSolution(solution, false); solution.isSolution = result[0] != -1; @@ -2504,25 +2490,25 @@ public class CellLayout extends ViewGroup { int spanX, int spanY, View dragView) { getDirectionVectorForDrop(pixelX, pixelY, spanX, spanY, dragView, mDirectionVector); - ItemConfiguration dropInPlaceSolution = dropInPlaceSolution(pixelX, pixelY, spanX, spanY, - dragView); + ItemConfiguration closestSpaceSolution = closestEmptySpaceReorder(pixelX, pixelY, spanX, + spanY); // Find a solution involving pushing / displacing any items in the way ItemConfiguration swapSolution = findReorderSolution(pixelX, pixelY, minSpanX, minSpanY, spanX, spanY, mDirectionVector, dragView, true, new ItemConfiguration()); // We attempt the approach which doesn't shuffle views at all - ItemConfiguration closestSpaceSolution = closestEmptySpaceReorder(pixelX, pixelY, minSpanX, - minSpanY, spanX, spanY); + ItemConfiguration noShuffleSolution = findConfigurationNoShuffle(pixelX, pixelY, minSpanX, + minSpanY, spanX, spanY, dragView, new ItemConfiguration()); // If the reorder solution requires resizing (shrinking) the item being dropped, we instead // favor a solution in which the item is not resized, but - if (swapSolution.isSolution && swapSolution.area() >= closestSpaceSolution.area()) { + if (swapSolution.isSolution && swapSolution.area() >= noShuffleSolution.area()) { return swapSolution; + } else if (noShuffleSolution.isSolution) { + return noShuffleSolution; } else if (closestSpaceSolution.isSolution) { return closestSpaceSolution; - } else if (dropInPlaceSolution.isSolution) { - return dropInPlaceSolution; } return null; } @@ -2679,8 +2665,7 @@ public class CellLayout extends ViewGroup { * @return The X, Y cell of a vacant area that can contain this object, * nearest the requested location. */ - public int[] findNearestAreaIgnoreOccupied(int pixelX, int pixelY, int spanX, int spanY, - int[] result) { + public int[] findNearestArea(int pixelX, int pixelY, int spanX, int spanY, int[] result) { return findNearestArea(pixelX, pixelY, spanX, spanY, spanX, spanY, true, result, null); } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index b31db82ab3..27e1ba143b 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -2615,6 +2615,7 @@ public class Workspace extends PagedView setDragMode(DRAG_MODE_REORDER); } + boolean resize = resultSpan[0] != spanX || resultSpan[1] != spanY; mDragTargetLayout.visualizeDropLocation(mTargetCell[0], mTargetCell[1], resultSpan[0], resultSpan[1], dragObject); } @@ -2971,7 +2972,7 @@ public class Workspace extends PagedView */ @Thunk int[] findNearestArea(int pixelX, int pixelY, int spanX, int spanY, CellLayout layout, int[] recycle) { - return layout.findNearestAreaIgnoreOccupied( + return layout.findNearestArea( pixelX, pixelY, spanX, spanY, recycle); } diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java index b87ab17cb3..efd511de37 100644 --- a/src/com/android/launcher3/folder/FolderPagedView.java +++ b/src/com/android/launcher3/folder/FolderPagedView.java @@ -365,7 +365,7 @@ public class FolderPagedView extends PagedView implements Cli public int findNearestArea(int pixelX, int pixelY) { int pageIndex = getNextPage(); CellLayout page = getPageAt(pageIndex); - page.findNearestAreaIgnoreOccupied(pixelX, pixelY, 1, 1, sTmpArray); + page.findNearestArea(pixelX, pixelY, 1, 1, sTmpArray); if (mFolder.isLayoutRtl()) { sTmpArray[0] = page.getCountX() - sTmpArray[0] - 1; } From 7545f20268a6429f7e01bad0409589322958a4c6 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Thu, 10 Nov 2022 15:12:50 -0800 Subject: [PATCH 224/429] Add test for vertical and horizontal split apps * More work still needs to be done for portrait split apps with stashed taskbar Bug: 258714015 Test: Existing tests pass, visually saw slight improvement in stashed portrait gesture clipping. Change-Id: Id1b9bb28a1a2676a5da1b5e5824e0835290cb616 --- .../quickstep/FullscreenDrawParamsTest.kt | 68 +++++++++++++++++-- 1 file changed, 63 insertions(+), 5 deletions(-) diff --git a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt index 963da2793d..6d47281f6c 100644 --- a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt +++ b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt @@ -20,14 +20,17 @@ import android.graphics.RectF import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.launcher3.DeviceProfileBaseTest +import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT import com.android.quickstep.views.TaskView.FullscreenDrawParams import com.android.systemui.shared.recents.model.ThumbnailData import com.android.systemui.shared.recents.utilities.PreviewPositionHelper +import com.android.wm.shell.util.SplitBounds import com.google.common.truth.Truth.assertThat import org.junit.Before import org.junit.Test import org.junit.runner.RunWith import org.mockito.Mockito.mock +import kotlin.math.roundToInt /** * Test for FullscreenDrawParams class. @@ -36,6 +39,7 @@ import org.mockito.Mockito.mock @RunWith(AndroidJUnit4::class) class FullscreenDrawParamsTest : DeviceProfileBaseTest() { + private val TASK_SCALE = 0.7f private var mThumbnailData: ThumbnailData = mock(ThumbnailData::class.java) private val mPreviewPositionHelper = PreviewPositionHelper() @@ -51,8 +55,8 @@ class FullscreenDrawParamsTest : DeviceProfileBaseTest() { initializeVarsForTablet() val dp = newDP() val previewRect = Rect(0, 0, 100, 100) - val canvasWidth = dp.widthPx / 2 - val canvasHeight = dp.heightPx / 2 + val canvasWidth = (dp.widthPx * TASK_SCALE).roundToInt() + val canvasHeight = (dp.heightPx * TASK_SCALE).roundToInt() val currentRotation = 0 val isRtl = false @@ -62,18 +66,72 @@ class FullscreenDrawParamsTest : DeviceProfileBaseTest() { params.setProgress(/* fullscreenProgress= */ 1.0f, /* parentScale= */ 1.0f, /* taskViewScale= */ 1.0f, /* previewWidth= */ 0, dp, mPreviewPositionHelper) - val expectedClippedInsets = RectF(0f, 0f, 0f, dp.taskbarSize / 2f) + val expectedClippedInsets = RectF(0f, 0f, 0f, dp.taskbarSize * TASK_SCALE) assertThat(params.mCurrentDrawnInsets) .isEqualTo(expectedClippedInsets) } + @Test + fun setFullProgress_currentDrawnInsets_clipTaskbarSizeFromBottomForTablets_splitPortrait() { + initializeVarsForTablet() + val dp = newDP() + val previewRect = Rect(0, 0, 100, 100) + val canvasWidth = (dp.widthPx * TASK_SCALE).roundToInt() + val canvasHeight = (dp.heightPx * TASK_SCALE / 2).roundToInt() + val currentRotation = 0 + val isRtl = false + // portrait/vertical split apps + val dividerSize = 10 + val splitBounds = SplitBounds( + Rect(0, 0, dp.widthPx, (dp.heightPx - dividerSize) / 2), + Rect(0, (dp.heightPx + dividerSize) / 2, dp.widthPx, dp.heightPx), + 0 /*lefTopTaskId*/, 0 /*rightBottomTaskId*/) + mPreviewPositionHelper.setSplitBounds(splitBounds, STAGE_POSITION_BOTTOM_OR_RIGHT) + + mPreviewPositionHelper.updateThumbnailMatrix(previewRect, mThumbnailData, canvasWidth, + canvasHeight, dp.widthPx, dp.heightPx, dp.taskbarSize, dp.isTablet, currentRotation, + isRtl) + params.setProgress(/* fullscreenProgress= */ 1.0f, /* parentScale= */ 1.0f, + /* taskViewScale= */ 1.0f, /* previewWidth= */ 0, dp, mPreviewPositionHelper) + + assertThat(params.mCurrentDrawnInsets.bottom) + .isWithin(1f).of((dp.taskbarSize * TASK_SCALE)) + } + + @Test + fun setFullProgress_currentDrawnInsets_clipTaskbarSizeFromBottomForTablets_splitLandscape() { + initializeVarsForTablet(isLandscape = true) + val dp = newDP() + val previewRect = Rect(0, 0, 100, 100) + val canvasWidth = (dp.widthPx * TASK_SCALE / 2).roundToInt() + val canvasHeight = (dp.heightPx * TASK_SCALE).roundToInt() + val currentRotation = 0 + val isRtl = false + // portrait/vertical split apps + val dividerSize = 10 + val splitBounds = SplitBounds( + Rect(0, 0, (dp.widthPx - dividerSize) / 2, dp.heightPx), + Rect((dp.widthPx + dividerSize) / 2, 0, dp.widthPx, dp.heightPx), + 0 /*lefTopTaskId*/, 0 /*rightBottomTaskId*/) + mPreviewPositionHelper.setSplitBounds(splitBounds, STAGE_POSITION_BOTTOM_OR_RIGHT) + + mPreviewPositionHelper.updateThumbnailMatrix(previewRect, mThumbnailData, canvasWidth, + canvasHeight, dp.widthPx, dp.heightPx, dp.taskbarSize, dp.isTablet, currentRotation, + isRtl) + params.setProgress(/* fullscreenProgress= */ 1.0f, /* parentScale= */ 1.0f, + /* taskViewScale= */ 1.0f, /* previewWidth= */ 0, dp, mPreviewPositionHelper) + + assertThat(params.mCurrentDrawnInsets.bottom) + .isWithin(1f).of((dp.taskbarSize * TASK_SCALE)) + } + @Test fun setFullProgress_currentDrawnInsets_doNotClipTaskbarSizeFromBottomForPhones() { initializeVarsForPhone() val dp = newDP() val previewRect = Rect(0, 0, 100, 100) - val canvasWidth = dp.widthPx / 2 - val canvasHeight = dp.heightPx / 2 + val canvasWidth = (dp.widthPx * TASK_SCALE).roundToInt() + val canvasHeight = (dp.heightPx * TASK_SCALE).roundToInt() val currentRotation = 0 val isRtl = false From 912a53e677cd158e7fe3bd7351c96e4360e4c2af Mon Sep 17 00:00:00 2001 From: Schneider Victor-tulias Date: Tue, 15 Nov 2022 12:12:17 -0800 Subject: [PATCH 225/429] Fix null-pointer exception in all set activity first reveal animation Fixes: 259296310 Test: started all set activity and started the first reveal animation Change-Id: I371f62be81e7f28ce5ecee150abb5d294bb2264d --- .../android/launcher3/taskbar/TaskbarActivityContext.java | 5 +++-- quickstep/src/com/android/launcher3/taskbar/TaskbarView.java | 1 + .../com/android/launcher3/taskbar/TaskbarViewController.java | 1 + 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 3c9e96f295..79b8c60ef8 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -920,12 +920,13 @@ public class TaskbarActivityContext extends BaseTaskbarContext { } mControllers.taskbarStashController.addUnstashToHotseatAnimation(fullAnimation, duration); - if (!FeatureFlags.ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT.get()) { + View allAppsButton = mControllers.taskbarViewController.getAllAppsButtonView(); + if (allAppsButton != null && !FeatureFlags.ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT.get()) { ValueAnimator alphaOverride = ValueAnimator.ofFloat(0, 1); alphaOverride.setDuration(duration); alphaOverride.addUpdateListener(a -> { // Override the alpha updates in the icon alignment animation. - mControllers.taskbarViewController.getAllAppsButtonView().setAlpha(0); + allAppsButton.setAlpha(0); }); fullAnimation.play(alphaOverride); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java index fe38bb1275..c4eeca7beb 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java @@ -422,6 +422,7 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar /** * Returns the all apps button in the taskbar. */ + @Nullable public View getAllAppsButtonView() { return mAllAppsButton; } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 80a31b4b44..9936d27951 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -240,6 +240,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar return mTaskbarView.getIconViews(); } + @Nullable public View getAllAppsButtonView() { return mTaskbarView.getAllAppsButtonView(); } From deaff5fbb476b991a2439c56a84052f36fe61e2b Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 15 Nov 2022 10:35:07 -0800 Subject: [PATCH 226/429] Move feature flags that have been changed to the top of the list. Bug: 259270717 Test: change flag, check that its at the top of the sorted list Change-Id: Ib10882e8de625471ef430a2f3162b85f9c6e1c1d --- .../android/launcher3/config/FeatureFlags.java | 18 +++++++++++++++--- .../launcher3/config/FlagTogglerPrefUi.java | 11 ++++++++--- 2 files changed, 23 insertions(+), 6 deletions(-) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 3a580203c6..526e93d5b3 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -17,6 +17,7 @@ package com.android.launcher3.config; import android.content.Context; +import android.content.SharedPreferences; import com.android.launcher3.BuildConfig; import com.android.launcher3.Utilities; @@ -331,7 +332,15 @@ public final class FeatureFlags { for (DebugFlag flag : sDebugFlags) { flag.initialize(context); } - sDebugFlags.sort((f1, f2) -> f1.key.compareToIgnoreCase(f2.key)); + + sDebugFlags.sort((f1, f2) -> { + // Sort first by any prefs that the user has changed, then alphabetically. + int changeComparison = Boolean.compare(f2.mHasBeenChangedAtLeastOnce, + f1.mHasBeenChangedAtLeastOnce); + return changeComparison != 0 + ? changeComparison + : f1.key.compareToIgnoreCase(f2.key); + }); } } @@ -387,6 +396,7 @@ public final class FeatureFlags { public static class DebugFlag extends BooleanFlag { public final String description; + protected boolean mHasBeenChangedAtLeastOnce; protected boolean mCurrentValue; public DebugFlag(String key, boolean defaultValue, String description) { @@ -404,8 +414,10 @@ public final class FeatureFlags { } public void initialize(Context context) { - mCurrentValue = context.getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE) - .getBoolean(key, defaultValue); + SharedPreferences prefs = + context.getSharedPreferences(FLAGS_PREF_NAME, Context.MODE_PRIVATE); + mHasBeenChangedAtLeastOnce = prefs.contains(key); + mCurrentValue = prefs.getBoolean(key, defaultValue); } @Override diff --git a/src/com/android/launcher3/config/FlagTogglerPrefUi.java b/src/com/android/launcher3/config/FlagTogglerPrefUi.java index 6729f7434f..2eb6e6df9a 100644 --- a/src/com/android/launcher3/config/FlagTogglerPrefUi.java +++ b/src/com/android/launcher3/config/FlagTogglerPrefUi.java @@ -52,12 +52,17 @@ public final class FlagTogglerPrefUi { public void putBoolean(String key, boolean value) { for (DebugFlag flag : FeatureFlags.getDebugFlags()) { if (flag.key.equals(key)) { - SharedPreferences.Editor editor = mContext.getSharedPreferences( - FLAGS_PREF_NAME, Context.MODE_PRIVATE).edit(); - if (value == flag.defaultValue) { + SharedPreferences prefs = mContext.getSharedPreferences( + FLAGS_PREF_NAME, Context.MODE_PRIVATE); + SharedPreferences.Editor editor = prefs.edit(); + // We keep the key in the prefs even if it has the default value, because it's a + // signal that it has been changed at one point. + if (!prefs.contains(key) && value == flag.defaultValue) { editor.remove(key).apply(); + flag.mHasBeenChangedAtLeastOnce = false; } else { editor.putBoolean(key, value).apply(); + flag.mHasBeenChangedAtLeastOnce = true; } updateMenu(); } From c7e76005e0c2934688b7efd3849a395489fa4b5c Mon Sep 17 00:00:00 2001 From: Federico Baron Date: Fri, 11 Nov 2022 11:38:40 -0800 Subject: [PATCH 227/429] Fix spring-loaded folder animation offset bug The folder close animation is offset due incorrect scaling in SpringLoaded mode. We fix the folder offset by scaling offsetX() and offsetY() by the scale of the workspace in spring loaded mode (scaleRelativeToDragLayer), and the offset of the preview icons is fixed by dividing previewItemOffsetX by initialScale rather than initialScale / scaleRelativeToDragLayer Fix: 255420905 Test: manual Change-Id: I305c1047c14c4c9f1b4c3bd0143e9bb764c71524 --- .../android/launcher3/folder/FolderAnimationManager.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/com/android/launcher3/folder/FolderAnimationManager.java b/src/com/android/launcher3/folder/FolderAnimationManager.java index d5ef9df111..dbbe5ed288 100644 --- a/src/com/android/launcher3/folder/FolderAnimationManager.java +++ b/src/com/android/launcher3/folder/FolderAnimationManager.java @@ -168,9 +168,11 @@ public class FolderAnimationManager { final int paddingOffsetY = (int) (mContent.getPaddingTop() * initialScale); int initialX = folderIconPos.left + mFolder.getPaddingLeft() - + mPreviewBackground.getOffsetX() - paddingOffsetX - previewItemOffsetX; + + Math.round(mPreviewBackground.getOffsetX() * scaleRelativeToDragLayer) + - paddingOffsetX - previewItemOffsetX; int initialY = folderIconPos.top + mFolder.getPaddingTop() - + mPreviewBackground.getOffsetY() - paddingOffsetY; + + Math.round(mPreviewBackground.getOffsetY() * scaleRelativeToDragLayer) + - paddingOffsetY; final float xDistance = initialX - lp.x; final float yDistance = initialY - lp.y; @@ -313,7 +315,7 @@ public class FolderAnimationManager { addPreviewItemAnimators(a, initialScale / scaleRelativeToDragLayer, // Background can have a scaled radius in drag and drop mode, so we need to add the // difference to keep the preview items centered. - previewItemOffsetX + radiusDiff, radiusDiff); + (int) (previewItemOffsetX / scaleRelativeToDragLayer) + radiusDiff, radiusDiff); return a; } From f9a6ac241a6d2725823b2661a7342acd1d9874ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebasti=C3=A1n=20Franco?= Date: Tue, 15 Nov 2022 22:56:37 +0000 Subject: [PATCH 228/429] Revert "Revert "Reorder widgets no longer overlaps when no space..." Revert "Revert "Reorder widgets no longer overlaps when no space..." Revert submission 20479526-revert-20427045-258023561-BPDASTWITO Reason for revert: Fix the issue that caused the first revert. Reverted Changes: Icecfd1d34:Revert "Reorder widgets no longer overlaps when no... I4cc552588:Revert "Reorder widgets no longer overlaps when no... Change-Id: I47c4cde42c19f50e2834660d843a8e2ae571c03c --- src/com/android/launcher3/CellLayout.java | 51 ++++++++++++------- src/com/android/launcher3/Workspace.java | 3 +- .../launcher3/folder/FolderPagedView.java | 2 +- 3 files changed, 35 insertions(+), 21 deletions(-) diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index de2a1f91ed..e500e59369 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -1651,8 +1651,19 @@ public class CellLayout extends ViewGroup { } } - private ItemConfiguration findConfigurationNoShuffle(int pixelX, int pixelY, int minSpanX, int minSpanY, - int spanX, int spanY, View dragView, ItemConfiguration solution) { + /** + * Returns a "reorder" where we simply drop the item in the closest empty space, without moving + * any other item in the way. + * + * @param pixelX X coordinate in pixels in the screen + * @param pixelY Y coordinate in pixels in the screen + * @param spanX horizontal cell span + * @param spanY vertical cell span + * @return the configuration that represents the found reorder + */ + private ItemConfiguration closestEmptySpaceReorder(int pixelX, int pixelY, int minSpanX, + int minSpanY, int spanX, int spanY) { + ItemConfiguration solution = new ItemConfiguration(); int[] result = new int[2]; int[] resultSpan = new int[2]; findNearestVacantArea(pixelX, pixelY, minSpanX, minSpanY, spanX, spanY, result, @@ -1697,7 +1708,7 @@ public class CellLayout extends ViewGroup { boolean isNearestDropLocationOccupied(int pixelX, int pixelY, int spanX, int spanY, View dragView, int[] result) { - result = findNearestArea(pixelX, pixelY, spanX, spanY, result); + result = findNearestAreaIgnoreOccupied(pixelX, pixelY, spanX, spanY, result); getViewsIntersectingRegion(result[0], result[1], spanX, spanY, dragView, null, mIntersectingViews); return !mIntersectingViews.isEmpty(); @@ -2247,7 +2258,8 @@ public class CellLayout extends ViewGroup { //TODO(adamcohen) b/151776141 use the items visual center for the direction vector int[] targetDestination = new int[2]; - findNearestArea(dragViewCenterX, dragViewCenterY, spanX, spanY, targetDestination); + findNearestAreaIgnoreOccupied(dragViewCenterX, dragViewCenterY, spanX, spanY, + targetDestination); Rect dragRect = new Rect(); cellToRect(targetDestination[0], targetDestination[1], spanX, spanY, dragRect); dragRect.offset(dragViewCenterX - dragRect.centerX(), dragViewCenterY - dragRect.centerY()); @@ -2400,7 +2412,7 @@ public class CellLayout extends ViewGroup { // We find the nearest cell into which we would place the dragged item, assuming there's // nothing in its way. int result[] = new int[2]; - result = findNearestArea(pixelX, pixelY, spanX, spanY, result); + result = findNearestAreaIgnoreOccupied(pixelX, pixelY, spanX, spanY, result); boolean success; // First we try the exact nearest position of the item being dragged, @@ -2445,19 +2457,21 @@ public class CellLayout extends ViewGroup { } /** - * Returns a "reorder" where we simply drop the item in the closest empty space, without moving - * any other item in the way. + * Returns a "reorder" if there is empty space without rearranging anything. * * @param pixelX X coordinate in pixels in the screen * @param pixelY Y coordinate in pixels in the screen * @param spanX horizontal cell span * @param spanY vertical cell span + * @param dragView view being dragged in reorder * @return the configuration that represents the found reorder */ - public ItemConfiguration closestEmptySpaceReorder(int pixelX, int pixelY, int spanX, - int spanY) { + public ItemConfiguration dropInPlaceSolution(int pixelX, int pixelY, int spanX, + int spanY, View dragView) { int[] result = new int[2]; - result = findNearestArea(pixelX, pixelY, spanX, spanY, result); + if (isNearestDropLocationOccupied(pixelX, pixelY, spanX, spanY, dragView, result)) { + result[0] = result[1] = -1; + } ItemConfiguration solution = new ItemConfiguration(); copyCurrentStateToSolution(solution, false); solution.isSolution = result[0] != -1; @@ -2490,25 +2504,25 @@ public class CellLayout extends ViewGroup { int spanX, int spanY, View dragView) { getDirectionVectorForDrop(pixelX, pixelY, spanX, spanY, dragView, mDirectionVector); - ItemConfiguration closestSpaceSolution = closestEmptySpaceReorder(pixelX, pixelY, spanX, - spanY); + ItemConfiguration dropInPlaceSolution = dropInPlaceSolution(pixelX, pixelY, spanX, spanY, + dragView); // Find a solution involving pushing / displacing any items in the way ItemConfiguration swapSolution = findReorderSolution(pixelX, pixelY, minSpanX, minSpanY, spanX, spanY, mDirectionVector, dragView, true, new ItemConfiguration()); // We attempt the approach which doesn't shuffle views at all - ItemConfiguration noShuffleSolution = findConfigurationNoShuffle(pixelX, pixelY, minSpanX, - minSpanY, spanX, spanY, dragView, new ItemConfiguration()); + ItemConfiguration closestSpaceSolution = closestEmptySpaceReorder(pixelX, pixelY, minSpanX, + minSpanY, spanX, spanY); // If the reorder solution requires resizing (shrinking) the item being dropped, we instead // favor a solution in which the item is not resized, but - if (swapSolution.isSolution && swapSolution.area() >= noShuffleSolution.area()) { + if (swapSolution.isSolution && swapSolution.area() >= closestSpaceSolution.area()) { return swapSolution; - } else if (noShuffleSolution.isSolution) { - return noShuffleSolution; } else if (closestSpaceSolution.isSolution) { return closestSpaceSolution; + } else if (dropInPlaceSolution.isSolution) { + return dropInPlaceSolution; } return null; } @@ -2665,7 +2679,8 @@ public class CellLayout extends ViewGroup { * @return The X, Y cell of a vacant area that can contain this object, * nearest the requested location. */ - public int[] findNearestArea(int pixelX, int pixelY, int spanX, int spanY, int[] result) { + public int[] findNearestAreaIgnoreOccupied(int pixelX, int pixelY, int spanX, int spanY, + int[] result) { return findNearestArea(pixelX, pixelY, spanX, spanY, spanX, spanY, true, result, null); } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 27e1ba143b..b31db82ab3 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -2615,7 +2615,6 @@ public class Workspace extends PagedView setDragMode(DRAG_MODE_REORDER); } - boolean resize = resultSpan[0] != spanX || resultSpan[1] != spanY; mDragTargetLayout.visualizeDropLocation(mTargetCell[0], mTargetCell[1], resultSpan[0], resultSpan[1], dragObject); } @@ -2972,7 +2971,7 @@ public class Workspace extends PagedView */ @Thunk int[] findNearestArea(int pixelX, int pixelY, int spanX, int spanY, CellLayout layout, int[] recycle) { - return layout.findNearestArea( + return layout.findNearestAreaIgnoreOccupied( pixelX, pixelY, spanX, spanY, recycle); } diff --git a/src/com/android/launcher3/folder/FolderPagedView.java b/src/com/android/launcher3/folder/FolderPagedView.java index efd511de37..b87ab17cb3 100644 --- a/src/com/android/launcher3/folder/FolderPagedView.java +++ b/src/com/android/launcher3/folder/FolderPagedView.java @@ -365,7 +365,7 @@ public class FolderPagedView extends PagedView implements Cli public int findNearestArea(int pixelX, int pixelY) { int pageIndex = getNextPage(); CellLayout page = getPageAt(pageIndex); - page.findNearestArea(pixelX, pixelY, 1, 1, sTmpArray); + page.findNearestAreaIgnoreOccupied(pixelX, pixelY, 1, 1, sTmpArray); if (mFolder.isLayoutRtl()) { sTmpArray[0] = page.getCountX() - sTmpArray[0] - 1; } From 9c74327e13b18a550dda6feec3f7651ed80edaa9 Mon Sep 17 00:00:00 2001 From: Sebastian Franco Date: Tue, 15 Nov 2022 15:03:25 -0800 Subject: [PATCH 229/429] Fixing the revert by not continuing the reorder if the solution is null. Fix: 258023561 Bug: 259234533 Test: atest testAddDeleteShortcutOnHotseat Change-Id: I63a2abf8a80e16fb45f4bbb3b2de413ef77b5e0c --- src/com/android/launcher3/CellLayout.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/CellLayout.java b/src/com/android/launcher3/CellLayout.java index e500e59369..691184afc0 100644 --- a/src/com/android/launcher3/CellLayout.java +++ b/src/com/android/launcher3/CellLayout.java @@ -2559,8 +2559,8 @@ public class CellLayout extends ViewGroup { result[1] = finalSolution.cellY; resultSpan[0] = finalSolution.spanX; resultSpan[1] = finalSolution.spanY; + performReorder(finalSolution, dragView, mode); } - performReorder(finalSolution, dragView, mode); return result; } From 0d69c8dde936f9fbb72e7fd835dc78c119b220ec Mon Sep 17 00:00:00 2001 From: Holly Sun Date: Wed, 19 Oct 2022 17:40:52 -0700 Subject: [PATCH 230/429] Add feature flag to control whether to inject fallback app results when AiAi fails to return app corpus results. Also add simple prefix matching method. Bug: 255355348 Test: manual Change-Id: I35f2089924d774f3bcc1c05638a5d6b45ed7443f --- .../search/StringMatcherUtility.java | 121 +++++++++++------- .../search/StringMatcherUtilityTest.java | 49 ++++++- 2 files changed, 119 insertions(+), 51 deletions(-) diff --git a/src/com/android/launcher3/search/StringMatcherUtility.java b/src/com/android/launcher3/search/StringMatcherUtility.java index acab52bbe8..c66f3a19e4 100644 --- a/src/com/android/launcher3/search/StringMatcherUtility.java +++ b/src/com/android/launcher3/search/StringMatcherUtility.java @@ -24,8 +24,8 @@ import java.text.Collator; public class StringMatcherUtility { /** - * Returns {@code true} is {@code query} is a prefix substring of a complete word/phrase in - * {@code target}. + * Returns {@code true} if {@code query} is a prefix of a substring in {@code target}. How to + * break target to valid substring is defined in the given {@code matcher}. */ public static boolean matches(String query, String target, StringMatcher matcher) { int queryLength = query.length(); @@ -50,7 +50,7 @@ public class StringMatcherUtility { thisType = nextType; nextType = i < (targetLength - 1) ? Character.getType(target.codePointAt(i + 1)) : Character.UNASSIGNED; - if (isBreak(thisType, lastType, nextType) + if (matcher.isBreak(thisType, lastType, nextType) && matcher.matches(query, target.substring(i, i + queryLength))) { return true; } @@ -58,52 +58,6 @@ public class StringMatcherUtility { return false; } - /** - * Returns true if the current point should be a break point. Following cases - * are considered as break points: - * 1) Any non space character after a space character - * 2) Any digit after a non-digit character - * 3) Any capital character after a digit or small character - * 4) Any capital character before a small character - */ - private static boolean isBreak(int thisType, int prevType, int nextType) { - switch (prevType) { - case Character.UNASSIGNED: - case Character.SPACE_SEPARATOR: - case Character.LINE_SEPARATOR: - case Character.PARAGRAPH_SEPARATOR: - return true; - } - switch (thisType) { - case Character.UPPERCASE_LETTER: - if (nextType == Character.UPPERCASE_LETTER) { - return true; - } - // Follow through - case Character.TITLECASE_LETTER: - // Break point if previous was not a upper case - return prevType != Character.UPPERCASE_LETTER; - case Character.LOWERCASE_LETTER: - // Break point if previous was not a letter. - return prevType > Character.OTHER_LETTER || prevType <= Character.UNASSIGNED; - case Character.DECIMAL_DIGIT_NUMBER: - case Character.LETTER_NUMBER: - case Character.OTHER_NUMBER: - // Break point if previous was not a number - return !(prevType == Character.DECIMAL_DIGIT_NUMBER - || prevType == Character.LETTER_NUMBER - || prevType == Character.OTHER_NUMBER); - case Character.MATH_SYMBOL: - case Character.CURRENCY_SYMBOL: - case Character.OTHER_PUNCTUATION: - case Character.DASH_PUNCTUATION: - // Always a break point for a symbol - return true; - default: - return false; - } - } - /** * Performs locale sensitive string comparison using {@link Collator}. */ @@ -142,6 +96,75 @@ public class StringMatcherUtility { public static StringMatcher getInstance() { return new StringMatcher(); } + + /** + * Returns true if the current point should be a break point. + * + * Following cases are considered as break points: + * 1) Any non space character after a space character + * 2) Any digit after a non-digit character + * 3) Any capital character after a digit or small character + * 4) Any capital character before a small character + * + * E.g., "YouTube" matches the input "you" and "tube", but not "out". + */ + protected boolean isBreak(int thisType, int prevType, int nextType) { + switch (prevType) { + case Character.UNASSIGNED: + case Character.SPACE_SEPARATOR: + case Character.LINE_SEPARATOR: + case Character.PARAGRAPH_SEPARATOR: + return true; + } + switch (thisType) { + case Character.UPPERCASE_LETTER: + if (nextType == Character.UPPERCASE_LETTER) { + return true; + } + // Follow through + case Character.TITLECASE_LETTER: + // Break point if previous was not a upper case + return prevType != Character.UPPERCASE_LETTER; + case Character.LOWERCASE_LETTER: + // Break point if previous was not a letter. + return prevType > Character.OTHER_LETTER || prevType <= Character.UNASSIGNED; + case Character.DECIMAL_DIGIT_NUMBER: + case Character.LETTER_NUMBER: + case Character.OTHER_NUMBER: + // Break point if previous was not a number + return !(prevType == Character.DECIMAL_DIGIT_NUMBER + || prevType == Character.LETTER_NUMBER + || prevType == Character.OTHER_NUMBER); + case Character.MATH_SYMBOL: + case Character.CURRENCY_SYMBOL: + case Character.OTHER_PUNCTUATION: + case Character.DASH_PUNCTUATION: + // Always a break point for a symbol + return true; + default: + return false; + } + } + } + + /** + * Subclass of {@code StringMatcher} using simple space break for prefix matching. + * E.g., "YouTube" matches the input "you". "Play Store" matches the input "play". + */ + public static class StringMatcherSpace extends StringMatcher { + + public static StringMatcherSpace getInstance() { + return new StringMatcherSpace(); + } + + /** + * The first character or any character after a space is considered as a break point. + * Returns true if the current point should be a break point. + */ + @Override + protected boolean isBreak(int thisType, int prevType, int nextType) { + return prevType == Character.UNASSIGNED || prevType == Character.SPACE_SEPARATOR; + } } /** diff --git a/tests/src/com/android/launcher3/search/StringMatcherUtilityTest.java b/tests/src/com/android/launcher3/search/StringMatcherUtilityTest.java index 413f404406..3b53255550 100644 --- a/tests/src/com/android/launcher3/search/StringMatcherUtilityTest.java +++ b/tests/src/com/android/launcher3/search/StringMatcherUtilityTest.java @@ -24,6 +24,7 @@ import androidx.test.filters.SmallTest; import androidx.test.runner.AndroidJUnit4; import com.android.launcher3.search.StringMatcherUtility.StringMatcher; +import com.android.launcher3.search.StringMatcherUtility.StringMatcherSpace; import org.junit.Test; import org.junit.runner.RunWith; @@ -34,11 +35,12 @@ import org.junit.runner.RunWith; @SmallTest @RunWith(AndroidJUnit4.class) public class StringMatcherUtilityTest { - private static final StringMatcher MATCHER = - StringMatcher.getInstance(); + private static final StringMatcher MATCHER = StringMatcher.getInstance(); + private static final StringMatcherSpace MATCHER_SPACE = StringMatcherSpace.getInstance(); @Test public void testMatches() { + assertTrue(matches("white", "white cow", MATCHER)); assertTrue(matches("white ", "white cow", MATCHER)); assertTrue(matches("white c", "white cow", MATCHER)); assertTrue(matches("cow", "white cow", MATCHER)); @@ -93,4 +95,47 @@ public class StringMatcherUtilityTest { assertFalse(matches("ㄷ", "로드라이브", MATCHER)); assertFalse(matches("åç", "abc", MATCHER)); } + + @Test + public void testMatchesWithSpaceBreakOnly() { + assertTrue(matches("white", "white cow", MATCHER_SPACE)); + assertTrue(matches("white ", "white cow", MATCHER_SPACE)); + assertTrue(matches("white c", "white cow", MATCHER_SPACE)); + assertTrue(matches("cow", "white cow", MATCHER_SPACE)); + assertTrue(matches("cow", "whitecow cow", MATCHER_SPACE)); + + assertFalse(matches("cow", "whiteCow", MATCHER_SPACE)); + assertFalse(matches("cow", "whiteCOW", MATCHER_SPACE)); + assertFalse(matches("cow", "whitecowCOW", MATCHER_SPACE)); + assertFalse(matches("cow", "white2cow", MATCHER_SPACE)); + assertFalse(matches("cow", "whitecow", MATCHER_SPACE)); + assertFalse(matches("cow", "whitEcow", MATCHER_SPACE)); + assertFalse(matches("cow", "whitecowCow", MATCHER_SPACE)); + assertFalse(matches("cow", "whitecowcow", MATCHER_SPACE)); + assertFalse(matches("cow", "whit ecowcow", MATCHER_SPACE)); + + assertFalse(matches("dog", "cats&dogs", MATCHER_SPACE)); + assertFalse(matches("dog", "cats&Dogs", MATCHER_SPACE)); + assertFalse(matches("&", "cats&Dogs", MATCHER_SPACE)); + + assertFalse(matches("43", "2+43", MATCHER_SPACE)); + assertFalse(matches("3", "2+43", MATCHER_SPACE)); + + assertTrue(matches("q", "Q", MATCHER_SPACE)); + assertTrue(matches("q", " Q", MATCHER_SPACE)); + + // match lower case words + assertTrue(matches("e", "elephant", MATCHER_SPACE)); + assertTrue(matches("eL", "Elephant", MATCHER_SPACE)); + + assertTrue(matches("电", "电子邮件", MATCHER_SPACE)); + assertTrue(matches("电子", "电子邮件", MATCHER_SPACE)); + assertTrue(matches("子", "电子邮件", MATCHER_SPACE)); + assertTrue(matches("邮件", "电子邮件", MATCHER_SPACE)); + + assertFalse(matches("ba", "Bot", MATCHER_SPACE)); + assertFalse(matches("ba", "bot", MATCHER_SPACE)); + assertFalse(matches("phant", "elephant", MATCHER_SPACE)); + assertFalse(matches("elephants", "elephant", MATCHER_SPACE)); + } } From 7b9433e6bc2cf64e67c48e297b0d3b3f2a765d5f Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Tue, 15 Nov 2022 19:35:45 -0800 Subject: [PATCH 231/429] Adds flag to show 2 rows of predicted apps in All Apps 0 state. Test: Manual Bug: 251593164 Change-Id: Id1c295eda4d1e3ff39285435fc15b3f5ac298dea --- src/com/android/launcher3/config/FeatureFlags.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 3e59e2b25d..10eacb04c3 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -269,6 +269,10 @@ public final class FeatureFlags { "ENABLE_SEARCH_RESULT_BACKGROUND_DRAWABLES", false, "Enable option to replace decorator-based search result backgrounds with drawables"); + public static final BooleanFlag TWO_PREDICTED_ROWS_ALL_APPS_SEARCH = new DeviceFlag( + "TWO_PREDICTED_ROWS_ALL_APPS_SEARCH", false, + "Use 2 rows of app predictions in All Apps search zero-state"); + public static final BooleanFlag ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS = new DeviceFlag( "ENABLE_SHOW_KEYBOARD_OPTION_IN_ALL_APPS", true, "Enable option to show keyboard when going to all-apps"); From 7e0f5d8a57cb7cebe9957e1c6cc2aba7c2013c0a Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Sun, 9 Oct 2022 23:39:24 -0700 Subject: [PATCH 232/429] Implement split from workspace to workspace Fixes: 239824922 Test: https://recall.googleplex.com/projects/f46cfe9c-8076-4efe-bf8a-b1cc4f1f5e1b/sessions/b745433d-cba7-4f7a-a28d-4223d9950c0b Change-Id: I9bfd5844bb9ccb6e65e77fedb7fbccb37692f812 --- .../popup/QuickstepSystemShortcut.java | 58 ++++++++++++++-- .../uioverrides/QuickstepLauncher.java | 19 ++++-- .../com/android/quickstep/SystemUiProxy.java | 28 ++++++++ .../util/SplitSelectStateController.java | 14 ++-- .../util/SplitToWorkspaceController.java | 66 +++++++++++++++++++ .../SplitWithKeyboardShortcutController.java | 27 -------- .../android/quickstep/views/RecentsView.java | 2 +- .../launcher3/config/FeatureFlags.java | 4 ++ 8 files changed, 175 insertions(+), 43 deletions(-) create mode 100644 quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java diff --git a/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java b/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java index 7c3281a046..7cf8201767 100644 --- a/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java +++ b/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java @@ -15,20 +15,29 @@ */ package com.android.launcher3.popup; +import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE; import static com.android.launcher3.util.SplitConfigurationOptions.getLogEventForPosition; +import static com.android.quickstep.util.SplitAnimationTimings.TABLET_HOME_TO_SPLIT; import android.content.Intent; import android.graphics.Bitmap; +import android.graphics.Rect; +import android.graphics.RectF; import android.graphics.drawable.BitmapDrawable; import android.graphics.drawable.Drawable; import android.util.Log; import android.view.View; +import com.android.launcher3.AbstractFloatingView; +import com.android.launcher3.R; +import com.android.launcher3.anim.PendingAnimation; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; +import com.android.quickstep.util.SplitSelectStateController; +import com.android.quickstep.views.FloatingTaskView; import com.android.quickstep.views.RecentsView; public interface QuickstepSystemShortcut { @@ -44,6 +53,10 @@ public interface QuickstepSystemShortcut { class SplitSelectSystemShortcut extends SystemShortcut { + private final int mSplitPlaceholderSize; + private final int mSplitPlaceholderInset; + + private final Rect mTempRect = new Rect(); private final SplitPositionOption mPosition; public SplitSelectSystemShortcut(QuickstepLauncher launcher, ItemInfo itemInfo, @@ -51,6 +64,11 @@ public interface QuickstepSystemShortcut { super(position.iconResId, position.textResId, launcher, itemInfo, originalView); mPosition = position; + + mSplitPlaceholderSize = launcher.getResources().getDimensionPixelSize( + R.dimen.split_placeholder_size); + mSplitPlaceholderInset = launcher.getResources().getDimensionPixelSize( + R.dimen.split_placeholder_inset); } @Override @@ -72,11 +90,39 @@ public interface QuickstepSystemShortcut { return; } - RecentsView recentsView = mTarget.getOverviewPanel(); StatsLogManager.EventEnum splitEvent = getLogEventForPosition(mPosition.stagePosition); - recentsView.initiateSplitSelect( - new SplitSelectSource(mOriginalView, new BitmapDrawable(bitmap), intent, - mPosition, mItemInfo, splitEvent)); + SplitSelectSource source = new SplitSelectSource(mOriginalView, + new BitmapDrawable(bitmap), intent, mPosition, mItemInfo, splitEvent); + if (ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) { + startSplitToHome(source); + } else { + RecentsView recentsView = mTarget.getOverviewPanel(); + recentsView.initiateSplitSelect(source); + } + } + + private void startSplitToHome(SplitSelectSource source) { + AbstractFloatingView.closeAllOpenViews(mTarget); + + SplitSelectStateController controller = mTarget.getSplitSelectStateController(); + controller.setInitialTaskSelect(source.intent, source.position.stagePosition, + source.itemInfo, source.splitEvent); + + RecentsView recentsView = mTarget.getOverviewPanel(); + recentsView.getPagedOrientationHandler().getInitialSplitPlaceholderBounds( + mSplitPlaceholderSize, mSplitPlaceholderInset, mTarget.getDeviceProfile(), + controller.getActiveSplitStagePosition(), mTempRect); + + PendingAnimation anim = new PendingAnimation(TABLET_HOME_TO_SPLIT.getDuration()); + RectF startingTaskRect = new RectF(); + FloatingTaskView floatingTaskView = FloatingTaskView.getFloatingTaskView(mTarget, + source.view, null /* thumbnail */, + source.drawable, startingTaskRect); + floatingTaskView.setAlpha(1); + floatingTaskView.addStagingAnimation(anim, startingTaskRect, mTempRect, + false /* fadeWithThumbnail */, true /* isStagedTask */); + controller.setFirstFloatingTaskView(floatingTaskView); + anim.buildAnim().start(); } } @@ -86,7 +132,7 @@ public interface QuickstepSystemShortcut { public final Drawable drawable; public final Intent intent; public final SplitPositionOption position; - public final ItemInfo mItemInfo; + public final ItemInfo itemInfo; public final StatsLogManager.EventEnum splitEvent; public SplitSelectSource(View view, Drawable drawable, Intent intent, @@ -96,7 +142,7 @@ public interface QuickstepSystemShortcut { this.drawable = drawable; this.intent = intent; this.position = position; - this.mItemInfo = itemInfo; + this.itemInfo = itemInfo; this.splitEvent = splitEvent; } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 9813c8a987..2d1a6cac38 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -96,6 +96,7 @@ import com.android.launcher3.logging.StatsLogManager.StatsLogger; import com.android.launcher3.model.BgDataModel.FixedContainerItems; import com.android.launcher3.model.WellbeingModel; import com.android.launcher3.model.data.ItemInfo; +import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.popup.SystemShortcut; import com.android.launcher3.proxy.ProxyActivityStarter; import com.android.launcher3.proxy.StartActivityParams; @@ -136,6 +137,7 @@ import com.android.quickstep.util.QuickstepOnboardingPrefs; import com.android.quickstep.util.RemoteAnimationProvider; import com.android.quickstep.util.RemoteFadeOutAnimationListener; import com.android.quickstep.util.SplitSelectStateController; +import com.android.quickstep.util.SplitToWorkspaceController; import com.android.quickstep.util.SplitWithKeyboardShortcutController; import com.android.quickstep.util.TISBindHelper; import com.android.quickstep.views.OverviewActionsView; @@ -182,7 +184,10 @@ public class QuickstepLauncher extends Launcher { private @Nullable RotationChangeProvider mRotationChangeProvider; private @Nullable LauncherUnfoldAnimationController mLauncherUnfoldAnimationController; + private SplitSelectStateController mSplitSelectStateController; private SplitWithKeyboardShortcutController mSplitWithKeyboardShortcutController; + private SplitToWorkspaceController mSplitToWorkspaceController; + /** * If Launcher restarted while in the middle of an Overview split select, it needs this data to * recover. In all other cases this will remain null. @@ -199,12 +204,14 @@ public class QuickstepLauncher extends Launcher { mActionsView = findViewById(R.id.overview_actions_view); RecentsView overviewPanel = getOverviewPanel(); - SplitSelectStateController controller = + mSplitSelectStateController = new SplitSelectStateController(this, mHandler, getStateManager(), getDepthController(), getStatsLogManager()); - overviewPanel.init(mActionsView, controller); + overviewPanel.init(mActionsView, mSplitSelectStateController); mSplitWithKeyboardShortcutController = new SplitWithKeyboardShortcutController(this, - controller); + mSplitSelectStateController); + mSplitToWorkspaceController = new SplitToWorkspaceController(this, + mSplitSelectStateController); mActionsView.updateDimension(getDeviceProfile(), overviewPanel.getLastComputedTaskSize()); mActionsView.updateVerticalMargin(DisplayController.getNavigationMode(this)); @@ -330,7 +337,7 @@ public class QuickstepLauncher extends Launcher { } protected void onItemClicked(View view) { - if (!mSplitWithKeyboardShortcutController.handleSecondAppSelectionForSplit(view)) { + if (!mSplitToWorkspaceController.handleSecondAppSelectionForSplit(view)) { QuickstepLauncher.super.getItemOnClickListener().onClick(view); } } @@ -724,6 +731,10 @@ public class QuickstepLauncher extends Launcher { return mTaskbarUIController; } + public SplitSelectStateController getSplitSelectStateController() { + return mSplitSelectStateController; + } + public T getActionsView() { return (T) mActionsView; } diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index ef7c6dca11..bb973342d5 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -561,6 +561,20 @@ public class SystemUiProxy implements ISystemUiProxy { } } + public void startIntents(PendingIntent pendingIntent1, Bundle options1, + PendingIntent pendingIntent2, Bundle options2, + @SplitConfigurationOptions.StagePosition int splitPosition, + float splitRatio, RemoteTransition remoteTransition, InstanceId instanceId) { + if (mSystemUiProxy != null) { + try { + mSplitScreen.startIntents(pendingIntent1, options1, pendingIntent2, options2, + splitPosition, splitRatio, remoteTransition, instanceId); + } catch (RemoteException e) { + Log.w(TAG, "Failed call startIntents"); + } + } + } + public void startShortcutAndTask(ShortcutInfo shortcutInfo, Bundle options1, int taskId, Bundle options2, @SplitConfigurationOptions.StagePosition int splitPosition, float splitRatio, RemoteTransition remoteTransition, InstanceId instanceId) { @@ -617,6 +631,20 @@ public class SystemUiProxy implements ISystemUiProxy { } } + public void startIntentsWithLegacyTransition(PendingIntent pendingIntent1, Bundle options1, + PendingIntent pendingIntent2, Bundle options2, + @SplitConfigurationOptions.StagePosition int sidePosition, float splitRatio, + RemoteAnimationAdapter adapter, InstanceId instanceId) { + if (mSystemUiProxy != null) { + try { + mSplitScreen.startIntentsWithLegacyTransition(pendingIntent1, options1, + pendingIntent2, options2, sidePosition, splitRatio, adapter, instanceId); + } catch (RemoteException e) { + Log.w(TAG, "Failed call startIntentsWithLegacyTransition"); + } + } + } + public void startShortcut(String packageName, String shortcutId, int position, Bundle options, UserHandle user, InstanceId instanceId) { if (mSplitScreen != null) { diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java index 4a74ac663b..c263fe8656 100644 --- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java +++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java @@ -37,6 +37,7 @@ import android.os.Handler; import android.os.IBinder; import android.os.RemoteException; import android.os.UserHandle; +import android.text.TextUtils; import android.util.Log; import android.util.Pair; import android.view.RemoteAnimationAdapter; @@ -207,8 +208,8 @@ public class SplitSelectStateController { * fill in intent with a taskId2 are set. * @param intent1 is null when split is initiated from Overview * @param stagePosition representing location of task1 - * @param shellInstanceId loggingId to be used by shell, will be non-null for actions that create - * a split instance, null for cases that bring existing instaces to the + * @param shellInstanceId loggingId to be used by shell, will be non-null for actions that + * create a split instance, null for cases that bring existing instaces to the * foreground (quickswitch, launching previous pairs from overview) */ public void launchTasks(int taskId1, @Nullable Intent intent1, int taskId2, @@ -238,7 +239,9 @@ public class SplitSelectStateController { getOppositeStagePosition(stagePosition), splitRatio, remoteTransition, shellInstanceId); } else { - // TODO: the case when both split apps are started from an intent. + mSystemUiProxy.startIntents(getPendingIntent(intent1), options1.toBundle(), + getPendingIntent(intent2), null /* options2 */, stagePosition, + splitRatio, remoteTransition, shellInstanceId); } } else { final RemoteSplitLaunchAnimationRunner animationRunner = @@ -259,7 +262,9 @@ public class SplitSelectStateController { getOppositeStagePosition(stagePosition), splitRatio, adapter, shellInstanceId); } else { - // TODO: the case when both split apps are started from an intent. + mSystemUiProxy.startIntentsWithLegacyTransition(getPendingIntent(intent1), + options1.toBundle(), getPendingIntent(intent2), null /* options2 */, + stagePosition, splitRatio, adapter, shellInstanceId); } } } @@ -305,7 +310,6 @@ public class SplitSelectStateController { : PendingIntent.getActivity(mContext, 0, intent, FLAG_MUTABLE)); } - public @StagePosition int getActiveSplitStagePosition() { return mStagePosition; } diff --git a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java new file mode 100644 index 0000000000..e8a4b0a324 --- /dev/null +++ b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2022 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_SPLIT_FROM_FULLSCREEN_WITH_KEYBOARD_SHORTCUTS; +import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE; + +import android.content.Intent; +import android.view.View; + +import com.android.launcher3.Launcher; +import com.android.launcher3.model.data.WorkspaceItemInfo; + +/** Handles when the stage split lands on the home screen. */ +public class SplitToWorkspaceController { + + private final Launcher mLauncher; + private final SplitSelectStateController mController; + + public SplitToWorkspaceController(Launcher launcher, SplitSelectStateController controller) { + mLauncher = launcher; + mController = controller; + } + + /** + * Handles second app selection from stage split. If the item can't be opened in split or + * it's not in stage split state, we pass it onto Launcher's default item click handler. + */ + public boolean handleSecondAppSelectionForSplit(View view) { + if ((!ENABLE_SPLIT_FROM_FULLSCREEN_WITH_KEYBOARD_SHORTCUTS.get() + && !ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE.get()) + || !mController.isSplitSelectActive()) { + return false; + } + Object tag = view.getTag(); + Intent intent; + if (tag instanceof WorkspaceItemInfo) { + final WorkspaceItemInfo workspaceItemInfo = (WorkspaceItemInfo) tag; + intent = workspaceItemInfo.intent; + } else if (tag instanceof com.android.launcher3.model.data.AppInfo) { + final com.android.launcher3.model.data.AppInfo appInfo = + (com.android.launcher3.model.data.AppInfo) tag; + intent = appInfo.intent; + } else { + return false; + } + mController.setSecondTask(intent); + mController.launchSplitTasks(aBoolean -> mLauncher.getDragLayer().removeView( + mController.getFirstFloatingTaskView())); + return true; + } +} diff --git a/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java b/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java index 3587bd1da5..24d832640f 100644 --- a/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java +++ b/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java @@ -101,33 +101,6 @@ public class SplitWithKeyboardShortcutController { }); } - /** - * Handles second app selection from stage split. If the item can't be opened in split or - * it's not in stage split state, we pass it onto Launcher's default item click handler. - */ - public boolean handleSecondAppSelectionForSplit(View view) { - if (!ENABLE_SPLIT_FROM_FULLSCREEN_WITH_KEYBOARD_SHORTCUTS.get() - || !mController.isSplitSelectActive()) { - return false; - } - Object tag = view.getTag(); - Intent intent; - if (tag instanceof WorkspaceItemInfo) { - final WorkspaceItemInfo workspaceItemInfo = (WorkspaceItemInfo) tag; - intent = workspaceItemInfo.intent; - } else if (tag instanceof com.android.launcher3.model.data.AppInfo) { - final com.android.launcher3.model.data.AppInfo appInfo = - (com.android.launcher3.model.data.AppInfo) tag; - intent = appInfo.intent; - } else { - return false; - } - mController.setSecondTask(intent); - mController.launchSplitTasks(aBoolean -> mLauncher.getDragLayer().removeView( - mController.getFirstFloatingTaskView())); - return true; - } - public void onDestroy() { mOverviewComponentObserver.onDestroy(); } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index ff0c984b6d..ce84869932 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -4232,7 +4232,7 @@ public abstract class RecentsView Date: Wed, 16 Nov 2022 02:38:36 -0800 Subject: [PATCH 233/429] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Idc8d0b1ff108bc98af48e961ee661579124da526 --- quickstep/res/values-af/strings.xml | 5 +- quickstep/res/values-am/strings.xml | 5 +- quickstep/res/values-ar/strings.xml | 5 +- quickstep/res/values-as/strings.xml | 5 +- quickstep/res/values-az/strings.xml | 5 +- quickstep/res/values-b+sr+Latn/strings.xml | 5 +- quickstep/res/values-be/strings.xml | 5 +- quickstep/res/values-bg/strings.xml | 5 +- quickstep/res/values-bn/strings.xml | 5 +- quickstep/res/values-bs/strings.xml | 5 +- quickstep/res/values-ca/strings.xml | 5 +- quickstep/res/values-cs/strings.xml | 5 +- quickstep/res/values-da/strings.xml | 5 +- quickstep/res/values-de/strings.xml | 5 +- quickstep/res/values-el/strings.xml | 5 +- quickstep/res/values-en-rAU/strings.xml | 5 +- quickstep/res/values-en-rCA/strings.xml | 55 ++++++++++++---------- quickstep/res/values-en-rGB/strings.xml | 5 +- quickstep/res/values-en-rIN/strings.xml | 5 +- quickstep/res/values-en-rXC/strings.xml | 5 +- quickstep/res/values-es-rUS/strings.xml | 5 +- quickstep/res/values-es/strings.xml | 5 +- quickstep/res/values-et/strings.xml | 5 +- quickstep/res/values-eu/strings.xml | 5 +- quickstep/res/values-fa/strings.xml | 5 +- quickstep/res/values-fi/strings.xml | 5 +- quickstep/res/values-fr-rCA/strings.xml | 5 +- quickstep/res/values-fr/strings.xml | 5 +- quickstep/res/values-gl/strings.xml | 5 +- quickstep/res/values-gu/strings.xml | 5 +- quickstep/res/values-hi/strings.xml | 5 +- quickstep/res/values-hr/strings.xml | 5 +- quickstep/res/values-hu/strings.xml | 5 +- quickstep/res/values-hy/strings.xml | 5 +- quickstep/res/values-in/strings.xml | 5 +- quickstep/res/values-is/strings.xml | 5 +- quickstep/res/values-it/strings.xml | 5 +- quickstep/res/values-iw/strings.xml | 5 +- quickstep/res/values-ja/strings.xml | 5 +- quickstep/res/values-ka/strings.xml | 5 +- quickstep/res/values-kk/strings.xml | 5 +- quickstep/res/values-km/strings.xml | 5 +- quickstep/res/values-kn/strings.xml | 5 +- quickstep/res/values-ko/strings.xml | 5 +- quickstep/res/values-ky/strings.xml | 5 +- quickstep/res/values-lo/strings.xml | 5 +- quickstep/res/values-lt/strings.xml | 5 +- quickstep/res/values-lv/strings.xml | 5 +- quickstep/res/values-mk/strings.xml | 5 +- quickstep/res/values-ml/strings.xml | 5 +- quickstep/res/values-mn/strings.xml | 5 +- quickstep/res/values-mr/strings.xml | 5 +- quickstep/res/values-ms/strings.xml | 5 +- quickstep/res/values-my/strings.xml | 5 +- quickstep/res/values-nb/strings.xml | 5 +- quickstep/res/values-ne/strings.xml | 5 +- quickstep/res/values-nl/strings.xml | 5 +- quickstep/res/values-or/strings.xml | 5 +- quickstep/res/values-pa/strings.xml | 5 +- quickstep/res/values-pl/strings.xml | 5 +- quickstep/res/values-pt-rPT/strings.xml | 5 +- quickstep/res/values-pt/strings.xml | 5 +- quickstep/res/values-ro/strings.xml | 5 +- quickstep/res/values-ru/strings.xml | 5 +- quickstep/res/values-si/strings.xml | 5 +- quickstep/res/values-sk/strings.xml | 5 +- quickstep/res/values-sl/strings.xml | 5 +- quickstep/res/values-sq/strings.xml | 5 +- quickstep/res/values-sr/strings.xml | 5 +- quickstep/res/values-sv/strings.xml | 5 +- quickstep/res/values-sw/strings.xml | 5 +- quickstep/res/values-ta/strings.xml | 5 +- quickstep/res/values-te/strings.xml | 5 +- quickstep/res/values-th/strings.xml | 5 +- quickstep/res/values-tl/strings.xml | 5 +- quickstep/res/values-tr/strings.xml | 5 +- quickstep/res/values-uk/strings.xml | 5 +- quickstep/res/values-ur/strings.xml | 5 +- quickstep/res/values-uz/strings.xml | 5 +- quickstep/res/values-vi/strings.xml | 5 +- quickstep/res/values-zh-rCN/strings.xml | 5 +- quickstep/res/values-zh-rHK/strings.xml | 5 +- quickstep/res/values-zh-rTW/strings.xml | 5 +- quickstep/res/values-zu/strings.xml | 5 +- 84 files changed, 361 insertions(+), 109 deletions(-) diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml index 34805eae3d..8bfca3f1dc 100644 --- a/quickstep/res/values-af/strings.xml +++ b/quickstep/res/values-af/strings.xml @@ -77,6 +77,8 @@ "Tutoriaal %1$d/%2$d" "Gereed!" "Swiep op om na die tuisskerm toe te gaan" + + "Jy is gereed om jou foon te begin gebruik" "Jy is gereed om jou tablet te begin gebruik" "Stelselnavigasie-instellings" @@ -84,7 +86,8 @@ "Skermkiekie" "Verdeel" "Probeer ander program om verdeelde skerm te gebruik" - "Program steun nie verdeelde skerm nie." + + "Jou organisasie laat nie hierdie program toe nie" "Slaan navigasietutoriaal oor?" "Jy kan dit later in die %1$s-program kry" diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml index 1789c2b8dd..bc4209ee0f 100644 --- a/quickstep/res/values-am/strings.xml +++ b/quickstep/res/values-am/strings.xml @@ -77,6 +77,8 @@ "አጋዥ ሥልጠና %1$d/%2$d" "ሁሉም ዝግጁ!" "ወደ መነሻ ለመሄድ በጣት ወደ ላይ ማንሸራተት" + + "ስልክዎን መጠቀም ለመጀመር ዝግጁ ነዎት" "ጡባዊዎን መጠቀም ለመጀመር ዝግጁ ነዎት" "የስርዓት አሰሳ ቅንብሮች" @@ -84,7 +86,8 @@ "ቅጽበታዊ ገጽ እይታ" "ክፈል" "የተከፈለ ማያን ለመጠቀም ሌላ መተግበሪያ መታ ያድርጉ" - "መተግበሪያው የተከፈለ ማያ ገጽን አይደግፍም።" + + "ይህ ድርጊት በመተግበሪያው ወይም በእርስዎ ድርጅት አይፈቀድም" "የአሰሳ አጋዥ ሥልጠናን ይዝለሉ?" "ይህን በኋላ በ%1$s መተግበሪያው ውስጥ ማግኘት ይችላሉ" diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml index f9755d2d37..b461230676 100644 --- a/quickstep/res/values-ar/strings.xml +++ b/quickstep/res/values-ar/strings.xml @@ -77,6 +77,8 @@ "الدليل التوجيهي %1$d من إجمالي %2$d" "اكتملت عملية الإعداد" "مرِّر سريعًا للأعلى للانتقال إلى الشاشة الرئيسية." + + "يمكنك الآن بدء استخدام هاتفك." "يمكنك الآن بدء استخدام جهازك اللوحي." "إعدادات التنقّل داخل النظام" @@ -84,7 +86,8 @@ "لقطة شاشة" "تقسيم" "انقر على تطبيق آخر لاستخدام وضع تقسيم الشاشة." - "التطبيق لا يتيح تقسيم الشاشة." + + "لا يسمح التطبيق أو لا تسمح مؤسستك بهذا الإجراء." "هل تريد تخطي الدليل التوجيهي؟" "يمكنك العثور على هذا الدليل التوجيهي لاحقًا في التطبيق \"%1$s\"" diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml index ec47dd4570..3bae94e157 100644 --- a/quickstep/res/values-as/strings.xml +++ b/quickstep/res/values-as/strings.xml @@ -77,6 +77,8 @@ "টিউট’ৰিয়েল %1$d/%2$d" "সকলো সাজু!" "গৃহ স্ক্ৰীনলৈ যাবলৈ ওপৰলৈ ছোৱাইপ কৰক" + + "আপুনি আপোনাৰ ফ’নটো ব্যৱহাৰ কৰিবলৈ সাজু" "আপুনি আপোনাৰ টেবলেটটো ব্যৱহাৰ কৰিবলৈ সাজু" "ছিষ্টেম নেভিগেশ্বনৰ ছেটিং" @@ -84,7 +86,8 @@ "স্ক্ৰীনশ্বট" "বিভাজন কৰক" "বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰিবলৈ অন্য এটা এপত টিপক" - "এপ্‌টোৱে বিভাজিত স্ক্ৰীন সমৰ্থন নকৰে।" + + "এপ্‌টোৱে অথবা আপোনাৰ প্ৰতিষ্ঠানে এই কাৰ্যটোৰ অনুমতি নিদিয়ে" "নেভিগেশ্বনৰ টিউট’ৰিয়েল এৰিব বিচাৰে নেকি?" "আপুনি এয়া পাছত %1$s এপ্‌টোত বিচাৰিব পাৰিব" diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml index 7d15232fd6..ff01f86f2b 100644 --- a/quickstep/res/values-az/strings.xml +++ b/quickstep/res/values-az/strings.xml @@ -77,6 +77,8 @@ "Dərslik %1$d/%2$d" "Hər şey hazırdır!" "Əsas səhifəyə keçmək üçün yuxarı çəkin" + + "Telefondan istifadəyə başlamağa hazırsınız" "Planşetdən istifadəyə başlamağa hazırsınız" "Sistem naviqasiya ayarları" @@ -84,7 +86,8 @@ "Skrinşot" "Ayırın" "Bölmə ekranını istifadə etmək üçün başqa tətbiqə toxunun" - "Tətbiq ekran bölünməsini dəstəkləmir." + + "Bu əməliyyata tətbiq və ya təşkilatınız tərəfindən icazə verilmir" "Naviqasiya dərsliyi ötürülsün?" "Bunu sonra %1$s tətbiqində tapa bilərsiniz" diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml index 638795369c..881237cf42 100644 --- a/quickstep/res/values-b+sr+Latn/strings.xml +++ b/quickstep/res/values-b+sr+Latn/strings.xml @@ -77,6 +77,8 @@ "Vodič %1$d/%2$d" "Gotovo!" "Prevucite nagore da biste otvorili početni ekran" + + "Spremni ste da počnete da koristite telefon" "Spremni ste da počnete da koristite tablet" "Podešavanja kretanja kroz sistem" @@ -84,7 +86,8 @@ "Snimak ekrana" "Podeli" "Dodirnite drugu aplikaciju za podeljeni ekran" - "Aplikacija ne podržava podeljeni ekran." + + "Aplikacija ili organizacija ne dozvoljavaju ovu radnju" "Želite da preskočite vodič za kretanje?" "Možete da pronađete ovo kasnije u aplikaciji %1$s" diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml index 5e5f147b16..db280f2d95 100644 --- a/quickstep/res/values-be/strings.xml +++ b/quickstep/res/values-be/strings.xml @@ -77,6 +77,8 @@ "Дапаможнік %1$d/%2$d" "Гатова!" "Каб перайсці на галоўны экран, правядзіце пальцам уверх" + + "Вы можаце пачаць карыстанне тэлефонам" "Вы можаце пачаць карыстанне планшэтам" "Налады навігацыі ў сістэме" @@ -84,7 +86,8 @@ "Здымак экрана" "Падзелены экран" "Для падзеленага экрана націсніце на іншую праграму" - "Праграма не падтрымлівае рэжым падзеленага экрана." + + "Гэта дзеянне не дазволена праграмай ці вашай арганізацыяй" "Прапусціць дапаможнік па навігацыі?" "Знайсці дапаможнік можна ў праграме \"%1$s\"" diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml index ca61151db2..375fa6a8b4 100644 --- a/quickstep/res/values-bg/strings.xml +++ b/quickstep/res/values-bg/strings.xml @@ -77,6 +77,8 @@ "Урок %1$d/%2$d" "Готово!" "Прекарайте пръст нагоре, за да отворите началния екран" + + "Можете да започнете да използвате телефона си" "Можете да започнете да използвате таблета си" "Настройки за навигиране в системата" @@ -84,7 +86,8 @@ "Екранна снимка" "Разделяне на екрана" "Докоснете друго прил., за да ползвате разд. екран" - "Приложението не поддържа разделен екран." + + "Това действие не е разрешено от приложението или организацията ви" "Пропускане на урока за навигиране?" "Урокът е налице в приложението %1$s" diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml index 268e73667f..24d2f1a2f5 100644 --- a/quickstep/res/values-bn/strings.xml +++ b/quickstep/res/values-bn/strings.xml @@ -77,6 +77,8 @@ "টিউটোরিয়াল %1$d/%2$d" "সব রেডি!" "হোম স্ক্রিনে যেতে উপরের দিকে সোয়াইপ করুন" + + "এবারে আপনি ফোন ব্যবহার করতে পারবেন" "এবারে আপনি ট্যাবলেট ব্যবহার করতে পারবেন" "সিস্টেম নেভিগেশন সেটিংস" @@ -84,7 +86,8 @@ "স্ক্রিনশট নিন" "স্প্লিট" "স্প্লিটস্ক্রিন ব্যবহার করতে অন্য অ্যাপে ট্যাপ করুন" - "স্প্লিট-স্ক্রিনে এই অ্যাপ কাজ করে না।" + + "এই অ্যাপ বা আপনার প্রতিষ্ঠান এই অ্যাকশনটি পারফর্ম করার অনুমতি দেয়নি" "নেভিগেশন টিউটোরিয়াল এড়িয়ে যেতে চান?" "আপনি %1$s অ্যাপে পরে এটি খুঁজে পাবেন" diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml index 1ff0817246..208e457ef6 100644 --- a/quickstep/res/values-bs/strings.xml +++ b/quickstep/res/values-bs/strings.xml @@ -77,6 +77,8 @@ "Vodič %1$d/%2$d" "Sve je spremno!" "Prevucite prema gore da odete na početni ekran" + + "Sve je spremno da počnete koristiti telefon" "Sve je spremno da počnete koristiti tablet" "Postavke navigiranja sistemom" @@ -84,7 +86,8 @@ "Snimak ekrana" "Podijeli" "Dodirnite drugu apl. da koristite podijeljeni ekran" - "Aplikacija ne podržava podijeljeni ekran." + + "Ovu radnju ne dozvoljava aplikacija ili vaša organizacija" "Preskočiti vodič za navigiranje?" "Možete ga pronaći kasnije u aplikaciji %1$s" diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml index 4957aee817..2eb14927a3 100644 --- a/quickstep/res/values-ca/strings.xml +++ b/quickstep/res/values-ca/strings.xml @@ -77,6 +77,8 @@ "Tutorial %1$d/%2$d" "Tot a punt!" "Llisca cap amunt per anar a la pàgina d\'inici" + + "Ja pots començar a utilitzar el telèfon" "Ja pots començar a utilitzar la tauleta" "Configuració de navegació del sistema" @@ -84,7 +86,8 @@ "Captura de pantalla" "Divideix" "Toca una altra aplicació per dividir la pantalla" - "L\'aplicació no admet la pantalla dividida." + + "L\'aplicació o la teva organització no permeten aquesta acció" "Vols ometre el tutorial de navegació?" "Pots trobar-lo més tard a l\'aplicació %1$s" diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml index fa707ac652..e337de0cab 100644 --- a/quickstep/res/values-cs/strings.xml +++ b/quickstep/res/values-cs/strings.xml @@ -77,6 +77,8 @@ "Výukový program %1$d/%2$d" "Hotovo!" "Přejetím nahoru se vrátíte na plochu" + + "Jste připraveni začít používat telefon" "Jste připraveni začít používat tablet" "Nastavení navigace v systému" @@ -84,7 +86,8 @@ "Snímek obrazovky" "Rozdělit" "Klepnutím na jinou aplikaci rozdělíte obrazovku" - "Aplikace nepodporuje režim rozdělené obrazovky." + + "Aplikace nebo organizace zakazuje tuto akci" "Přeskočit výukový program k navigaci?" "Program později najdete v aplikaci %1$s" diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml index d88061d399..2c9591a21c 100644 --- a/quickstep/res/values-da/strings.xml +++ b/quickstep/res/values-da/strings.xml @@ -77,6 +77,8 @@ "Selvstudie %1$d/%2$d" "Alt er parat!" "Stryg opad for at gå til startsiden" + + "Du er klar til at bruge din telefon" "Du er klar til at bruge din tablet" "Indstillinger for systemnavigation" @@ -84,7 +86,8 @@ "Screenshot" "Opdel" "Tryk på en anden app for at bruge opdelt skærm" - "Appen understøtter ikke opdelt skærm." + + "Appen eller din organisation tillader ikke denne handling" "Vil du springe selvstudiet for navigation over?" "Du kan finde dette senere i appen %1$s" diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml index 3728b35ee3..d0b898384f 100644 --- a/quickstep/res/values-de/strings.xml +++ b/quickstep/res/values-de/strings.xml @@ -77,6 +77,8 @@ "Anleitung %1$d/%2$d" "Fertig!" "Nach oben wischen, um den Startbildschirm aufzurufen" + + "Du kannst dein Smartphone jetzt verwenden" "Du kannst dein Tablet jetzt verwenden" "Einstellungen der Systemsteuerung" @@ -84,7 +86,8 @@ "Screenshot" "Teilen" "Für „Bildschirm teilen“ auf weitere App tippen" - "„Geteilter Bildschirm“ wird v. d. App nicht unterstützt." + + "Die App oder deine Organisation lässt diese Aktion nicht zu" "Navigationstutorial überspringen?" "Du findest es später auch in der %1$s App" diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml index 5ff882e967..a2ab151c5b 100644 --- a/quickstep/res/values-el/strings.xml +++ b/quickstep/res/values-el/strings.xml @@ -77,6 +77,8 @@ "Οδηγός %1$d/%2$d" "Όλα έτοιμα!" "Σύρετε προς τα πάνω για μετάβαση στην αρχική οθόνη." + + "Είστε έτοιμοι να ξεκινήσετε να χρησιμοποιείτε το τηλέφωνό σας" "Είστε έτοιμοι να ξεκινήσετε να χρησιμοποιείτε το tablet." "Ρυθμίσεις πλοήγησης συστήματος" @@ -84,7 +86,8 @@ "Στιγμιότυπο οθόνης" "Διαχωρισμός" "Πατήστε άλλη εφαρμογή για χρήση διαχωρισμού οθόνης" - "Η εφαρμογή δεν υποστηρίζει διαχωρισμό οθόνης." + + "Αυτή η ενέργεια δεν επιτρέπεται από την εφαρμογή ή τον οργανισμό σας." "Παράβλεψη οδηγού πλοήγησης;" "Βρείτε τον αργότερα στην εφαρμογή %1$s" diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml index 5b378b41ac..19b0c3c65c 100644 --- a/quickstep/res/values-en-rAU/strings.xml +++ b/quickstep/res/values-en-rAU/strings.xml @@ -77,6 +77,8 @@ "Tutorial %1$d/%2$d" "Ready!" "Swipe up to go home" + + "You’re ready to start using your phone" "You’re ready to start using your tablet" "System navigation settings" @@ -84,7 +86,8 @@ "Screenshot" "Split" "Tap another app to use split-screen" - "App does not support split-screen." + + "This action isn\'t allowed by the app or your organisation" "Skip navigation tutorial?" "You can find this later in the %1$s app" diff --git a/quickstep/res/values-en-rCA/strings.xml b/quickstep/res/values-en-rCA/strings.xml index ab0a8e9a4b..f6498c3be2 100644 --- a/quickstep/res/values-en-rCA/strings.xml +++ b/quickstep/res/values-en-rCA/strings.xml @@ -25,18 +25,18 @@ "App usage settings" "Clear all" "Recent apps" - "Task closed" + "Task Closed" "%1$s, %2$s" "< 1 minute" "%1$s left today" "App suggestions" "Your predicted apps" - "Get app suggestions on the bottom row of your home screen" - "Get app suggestions on the favourites row of your home screen" - "Easily access your most-used apps directly from the home screen. Suggestions will change based on your routines. Apps on the bottom row will move up to your home screen." - "Easily access your most-used apps directly from the home screen. Suggestions will change based on your routines. Apps in the favourites row will move to your home screen." + "Get app suggestions on the bottom row of your Home screen" + "Get app suggestions on favorites row of your Home screen" + "Easily access your most-used apps right on the Home screen. Suggestions will change based on your routines. Apps on the bottom row will move up to your Home screen." + "Easily access your most-used apps right on the Home screen. Suggestions will change based on your routines. Apps in favorites row will move to your Home screen." "Get app suggestions" - "No, thanks" + "No thanks" "Settings" "Most-used apps appear here, and change based on routines" "Drag apps off the bottom row to get app suggestions" @@ -44,47 +44,50 @@ "App suggestions enabled" "App suggestions are disabled" "Predicted app: %1$s" - "Make sure that you swipe from the far-right or far-left edge." - "Make sure that you swipe from the right or left edge to the middle of the screen and let go." - "You learned how to swipe from the right to go back. Next, learn how to switch apps." + "Make sure you swipe from the far-right or far-left edge." + "Make sure you swipe from the right or left edge to the middle of the screen and let go." + "You learned how to swipe from the right to go back. Next up, learn how to switch apps." "You completed the go back gesture." - "Make sure that you don\'t swipe too close to the bottom of the screen." - "To change sensitivity of the back gesture, go to Settings" + "Make sure you don\'t swipe too close to the bottom of the screen." + "To change the sensitivity of the back gesture, go to Settings" "Swipe to go back" "To go back to the last screen, swipe from the left or right edge to the middle of the screen." - "To go back to the last screen, swipe with two fingers from the left or right edge to the middle of the screen." - "Make sure that you swipe up from the bottom edge of the screen." - "Make sure that you don\'t pause before letting go." - "Make sure that you swipe straight up." - "You completed the go home gesture. Next, learn how to go back." - "You completed the go home gesture." + "To go back to the last screen, swipe with 2 fingers from the left or right edge to the middle of the screen." + "Make sure you swipe up from the bottom edge of the screen." + "Make sure you don\'t pause before letting go." + "Make sure you swipe straight up." + "You completed the go Home gesture. Next up, learn how to go back." + "You completed the go Home gesture." "Swipe to go home" - "Swipe up from the bottom of your screen. This gesture always takes you to the home screen." - "Swipe up with two fingers from the bottom of the screen. This gesture always takes you to the home screen." - "Make sure that you swipe up from the bottom edge of the screen." + "Swipe up from the bottom of your screen. This gesture always takes you to the Home screen." + "Swipe up with 2 fingers from the bottom of the screen. This gesture always takes you to the Home screen." + "Make sure you swipe up from the bottom edge of the screen." "Try holding the window for longer before releasing." - "Make sure that you swipe straight up, then pause." + "Make sure you swipe straight up, then pause." "You learned how to use gestures. To turn off gestures, go to Settings." "You completed the switch apps gesture." "Swipe to switch apps" "To switch between apps, swipe up from the bottom of your screen, hold, then release." - "To switch between apps, swipe up with two fingers from the bottom of your screen, hold, then release." + "To switch between apps, swipe up with 2 fingers from the bottom of your screen, hold, then release." "All set" "Done" "Settings" "Try again" "Nice!" "Tutorial %1$d/%2$d" - "Ready!" - "Swipe up to go home" + "All set!" + "Swipe up to go Home" + + "You’re ready to start using your phone" "You’re ready to start using your tablet" "System navigation settings" "Share" "Screenshot" "Split" - "Tap another app to use split-screen" - "App does not support split-screen." + "Tap another app to use splitscreen" + + "This action isn\'t allowed by the app or your organization" "Skip navigation tutorial?" "You can find this later in the %1$s app" diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml index 5b378b41ac..19b0c3c65c 100644 --- a/quickstep/res/values-en-rGB/strings.xml +++ b/quickstep/res/values-en-rGB/strings.xml @@ -77,6 +77,8 @@ "Tutorial %1$d/%2$d" "Ready!" "Swipe up to go home" + + "You’re ready to start using your phone" "You’re ready to start using your tablet" "System navigation settings" @@ -84,7 +86,8 @@ "Screenshot" "Split" "Tap another app to use split-screen" - "App does not support split-screen." + + "This action isn\'t allowed by the app or your organisation" "Skip navigation tutorial?" "You can find this later in the %1$s app" diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml index 5b378b41ac..19b0c3c65c 100644 --- a/quickstep/res/values-en-rIN/strings.xml +++ b/quickstep/res/values-en-rIN/strings.xml @@ -77,6 +77,8 @@ "Tutorial %1$d/%2$d" "Ready!" "Swipe up to go home" + + "You’re ready to start using your phone" "You’re ready to start using your tablet" "System navigation settings" @@ -84,7 +86,8 @@ "Screenshot" "Split" "Tap another app to use split-screen" - "App does not support split-screen." + + "This action isn\'t allowed by the app or your organisation" "Skip navigation tutorial?" "You can find this later in the %1$s app" diff --git a/quickstep/res/values-en-rXC/strings.xml b/quickstep/res/values-en-rXC/strings.xml index f0b2066d3f..55b99c862c 100644 --- a/quickstep/res/values-en-rXC/strings.xml +++ b/quickstep/res/values-en-rXC/strings.xml @@ -77,6 +77,8 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‏‎‎‏‏‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎Tutorial ‎‏‎‎‏‏‎%1$d‎‏‎‎‏‏‏‎/‎‏‎‎‏‏‎%2$d‎‏‎‎‏‏‏‎‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‎‏‎‎‎‎‎‎‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎All set!‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‎‎‎‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎Swipe up to go Home‎‏‎‎‏‎" + + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‏‏‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‎You’re ready to start using your phone‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎You’re ready to start using your tablet‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‏‏‎""‎‏‎‎‏‏‏‎System navigation settings‎‏‎‎‏‏‎""‎‏‎‎‏‏‏‎‎‏‎‎‏‎" @@ -84,7 +86,8 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‎Screenshot‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‎Split‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎Tap another app to use splitscreen‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‏‎‏‎‏‏‎‎‏‏‎‏‏‎‎‏‎‏‏‏‎‎‏‎‏‏‏‎‎‎‎‏‏‏‎‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‏‏‎‎‏‎‎‏‎‎App does not support split-screen.‎‏‎‎‏‎" + + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎This action isn\'t allowed by the app or your organization‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‎‎Skip navigation tutorial?‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‏‏‎‎You can find this later in the ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ app‎‏‎‎‏‎" diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml index b9bb70f36f..7bb40e9ebf 100644 --- a/quickstep/res/values-es-rUS/strings.xml +++ b/quickstep/res/values-es-rUS/strings.xml @@ -77,6 +77,8 @@ "Instructivo %1$d/%2$d" "Todo listo" "Desliza el dedo hacia arriba para ir a la pantalla principal" + + "Ya puedes empezar a usar tu teléfono" "Ya puedes empezar a usar tu tablet" "Configuración de navegación del sistema" @@ -84,7 +86,8 @@ "Captura de pantalla" "Pantalla dividida" "Presiona otra app para usar la pantalla dividida" - "La app no es compatible con la función de pantalla dividida." + + "La app o tu organización no permiten realizar esta acción" "¿Omitir el instructivo de navegación?" "Puedes encontrarlo en la app de %1$s" diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml index f3d7a31623..6610768d77 100644 --- a/quickstep/res/values-es/strings.xml +++ b/quickstep/res/values-es/strings.xml @@ -77,6 +77,8 @@ "Tutorial %1$d/%2$d" "¡Ya está!" "Desliza el dedo hacia arriba para ir a la pantalla de inicio" + + "Ya puedes empezar a usar tu teléfono" "Ya puedes empezar a usar tu tablet" "Ajustes de navegación del sistema" @@ -84,7 +86,8 @@ "Hacer captura" "Dividir" "Toca otra aplicación para usar la pantalla dividida" - "La aplicación no admite la pantalla dividida." + + "No puedes hacerlo porque la aplicación o tu organización no lo permiten" "¿Saltar tutorial de navegación?" "Puedes consultarlo en otro momento en la aplicación %1$s" diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml index 73c1c1da38..67f4e1c04e 100644 --- a/quickstep/res/values-et/strings.xml +++ b/quickstep/res/values-et/strings.xml @@ -77,6 +77,8 @@ "Õpetus %1$d/%2$d" "Valmis!" "Avakuvale liikumiseks pühkige üles" + + "Olete valmis oma telefoni kasutama." "Olete valmis oma tahvelarvutit kasutama" "Süsteemi navigeerimisseaded" @@ -84,7 +86,8 @@ "Ekraanipilt" "Eralda" "Jagatud kuva kasutamiseks puudutage muud rakendust" - "Rakendus ei toeta jagatud ekraani." + + "Rakendus või teie organisatsioon on selle toimingu keelanud" "Kas jätta navigeerimise õpetused vahele?" "Leiate selle hiljem rakendusest %1$s" diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml index 5b83633565..0185bb9202 100644 --- a/quickstep/res/values-eu/strings.xml +++ b/quickstep/res/values-eu/strings.xml @@ -77,6 +77,8 @@ "Tutoriala: %1$d/%2$d" "Dena prest!" "Pasatu hatza gora hasierako pantailara joateko" + + "Prest zaude telefonoa erabiltzen hasteko" "Prest zaude tableta erabiltzen hasteko" "Sisteman nabigatzeko ezarpenak" @@ -84,7 +86,8 @@ "Atera pantaila-argazki bat" "Zatitu" "Sakatu beste aplikazio bat pantaila zatitzeko" - "Aplikazioak ez du onartzen pantaila zatitua." + + "Aplikazioak edo erakundeak ez du eman ekintza hori gauzatzeko baimena" "Nabigazio-tutoriala saltatu nahi duzu?" "%1$s aplikazioan dago eskuragarri tutoriala" diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml index a64a876980..44c9975f3f 100644 --- a/quickstep/res/values-fa/strings.xml +++ b/quickstep/res/values-fa/strings.xml @@ -77,6 +77,8 @@ "آموزش گام‌به‌گام %1$d/%2$d" "همه چیز آماده است!" "برای رفتن به «صفحه اصلی»، تند به‌بالا بکشید" + + "آماده‌اید از تلفنتان استفاده کنید" "آماده‌اید از رایانه لوحی‌تان استفاده کنید" "تنظیمات پیمایش سیستم" @@ -84,7 +86,8 @@ "نماگرفت" "دونیمه" "برای استفاده از صفحهٔ دونیمه، روی برنامه دیگری ضربه بزنید" - "برنامه از صفحهٔ دونیمه پشتیبانی نمی‌کند." + + "برنامه یا سازمان شما اجازه نمی‌دهد این کنش انجام شود." "آموزش گام‌به‌گام پیمایش رد شود؟" "می‌توانید آن را بعداً در برنامه %1$s پیدا کنید" diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml index 08a9248692..adff666707 100644 --- a/quickstep/res/values-fi/strings.xml +++ b/quickstep/res/values-fi/strings.xml @@ -77,6 +77,8 @@ "Ohje %1$d/%2$d" "Valmis" "Siirry aloitusnäytölle pyyhkäisemällä ylös" + + "Olet valmis aloittamaan puhelimen käytön" "Olet valmis aloittamaan tabletin käytön" "Järjestelmän navigointiasetukset" @@ -84,7 +86,8 @@ "Kuvakaappaus" "Jaa" "Avaa jaettu näyttö napauttamalla toista sovellusta" - "Sovellus ei tue jaetun näytön tilaa." + + "Sovellus tai organisaatio ei salli tätä toimintoa" "Ohitetaanko navigointiohje?" "Löydät tämän myöhemmin sovelluksesta: %1$s" diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml index 6199a1421a..63f1a1a337 100644 --- a/quickstep/res/values-fr-rCA/strings.xml +++ b/quickstep/res/values-fr-rCA/strings.xml @@ -77,6 +77,8 @@ "Étape %1$d sur %2$d du tutoriel" "Tout est prêt!" "Balayez l\'écran vers le haut pour accéder à l\'écran d\'accueil" + + "Vous êtes maintenant prêt à utiliser votre téléphone" "Vous êtes maintenant prêt à utiliser votre tablette" "Paramètres de navigation du système" @@ -84,7 +86,8 @@ "Capture d\'écran" "Séparé" "Touchez une autre appli pour partager l\'écran" - "L\'appli n\'est pas compatible avec l\'écran partagé." + + "L\'application ou votre organisation n\'autorise pas cette action" "Ignorer le tutoriel sur la navigation?" "Vous trouverez le tutoriel dans l\'application %1$s" diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml index c66da27883..5eccc91df1 100644 --- a/quickstep/res/values-fr/strings.xml +++ b/quickstep/res/values-fr/strings.xml @@ -77,6 +77,8 @@ "Tutoriel %1$d sur %2$d" "Tout est prêt !" "Balayez l\'écran vers le haut pour revenir à l\'accueil" + + "Vous pouvez maintenant utiliser votre téléphone" "Vous pouvez maintenant utiliser votre tablette" "Paramètres de navigation système" @@ -84,7 +86,8 @@ "Capture d\'écran" "Partager" "Appuyez sur autre appli pour utiliser écran partagé" - "Appli incompatible avec l\'écran partagé." + + "Cette action n\'est pas autorisée par l\'application ou par votre organisation" "Ignorer le tutoriel de navigation ?" "Vous le retrouverez dans l\'appli %1$s" diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml index 9946f17b4b..95c8761c98 100644 --- a/quickstep/res/values-gl/strings.xml +++ b/quickstep/res/values-gl/strings.xml @@ -77,6 +77,8 @@ "Titorial %1$d/%2$d" "Todo listo" "Pasa o dedo cara arriba para ir á pantalla de inicio" + + "Xa podes comezar a utilizar o teléfono" "Todo está listo para comezar a utilizar a tableta" "Configuración da navegación do sistema" @@ -84,7 +86,8 @@ "Facer captura" "Dividir" "Para usar a pantalla dividida, toca outra app" - "A app non admite a función de pantalla dividida." + + "A aplicación ou a túa organización non permite realizar esta acción" "Queres omitir o titorial de navegación?" "Podes atopalo máis tarde na aplicación %1$s" diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml index 3439410d37..051077da0d 100644 --- a/quickstep/res/values-gu/strings.xml +++ b/quickstep/res/values-gu/strings.xml @@ -77,6 +77,8 @@ "ટ્યૂટૉરિઅલ %1$d/%2$d" "બધું સેટ થઈ ગયું!" "હોમપેજ પર જવા માટે ઉપરની તરફ સ્વાઇપ કરો" + + "તમે તમારા ફોનનો ઉપયોગ કરવા માટે તૈયાર છો" "તમે તમારા ટૅબ્લેટનો ઉપયોગ કરવા માટે તૈયાર છો" "સિસ્ટમના નૅવિગેશન સેટિંગ" @@ -84,7 +86,8 @@ "સ્ક્રીનશૉટ" "વિભાજિત કરો" "સ્પલિટસ્ક્રીનના વપરાશ માટે, કોઈ અન્ય ઍપ પર ટૅપ કરો" - "ઍપ સ્ક્રીન-વિભાજનને સપોર્ટ કરતી નથી." + + "ઍપ કે તમારી સંસ્થા દ્વારા આ ક્રિયા કરવાની મંજૂરી નથી" "નૅવિગેશન ટ્યૂટૉરિઅલ છોડી દઈએ?" "તમે આને પછીથી %1$s ઍપમાં જોઈ શકો છો" diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml index be5a2776b4..434845ff8f 100644 --- a/quickstep/res/values-hi/strings.xml +++ b/quickstep/res/values-hi/strings.xml @@ -77,6 +77,8 @@ "ट्यूटोरियल %1$d/%2$d" "हो गया!" "होम स्क्रीन पर जाने के लिए, ऊपर की ओर स्वाइप करें" + + "अब आपका फ़ोन, इस्तेमाल के लिए तैयार है" "आप टैबलेट को इस्तेमाल करने के लिए तैयार हैं" "सिस्टम नेविगेशन सेटिंग" @@ -84,7 +86,8 @@ "स्क्रीनशॉट लें" "स्प्लिट स्क्रीन मोड" "स्प्लिट स्क्रीन मोड के लिए, दूसरे ऐप पर टैप करें" - "यह ऐप्लिकेशन, स्प्लिट स्क्रीन पर काम नहीं करता है." + + "ऐप्लिकेशन या आपका संगठन इस कार्रवाई की अनुमति नहीं देता" "क्या आपको नेविगेशन ट्यूटोरियल छोड़ना है?" "इसे बाद में %1$s ऐप्लिकेशन पर देखा जा सकता है" diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml index 620ba51788..681105e3d3 100644 --- a/quickstep/res/values-hr/strings.xml +++ b/quickstep/res/values-hr/strings.xml @@ -77,6 +77,8 @@ "Vodič %1$d/%2$d" "Sve je spremno!" "Prijeđite prstom prema gore da biste otvorili početni zaslon" + + "Spremni ste za početak upotrebe telefona" "Spremni ste za početak upotrebe tableta" "Postavke navigacije sustavom" @@ -84,7 +86,8 @@ "Snimka zaslona" "Podijeli" "Dodirnite drugu aplikaciju za podijeljeni zaslon" - "Aplikacija ne podržava podijeljeni zaslon." + + "Aplikacija ili vaša organizacija ne dopuštaju ovu radnju" "Želite li preskočiti vodič za kretanje?" "Kasnije ga možete pronaći u aplikaciji %1$s" diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml index 61f0a3b31a..46e4b2bd69 100644 --- a/quickstep/res/values-hu/strings.xml +++ b/quickstep/res/values-hu/strings.xml @@ -77,6 +77,8 @@ "Útmutató (%2$d/%1$d.)" "Kész is!" "Felfelé csúsztatva megjelenik a Kezdőképernyő" + + "Készen áll a telefon használatára" "Készen áll a táblagép használatára" "Rendszer-navigációs beállítások" @@ -84,7 +86,8 @@ "Képernyőkép" "Felosztás" "Koppintson másik appra a képernyőmegosztáshoz" - "Az alkalmazás nem támogatja az osztott képernyőt." + + "Az alkalmazás vagy az Ön szervezete nem engedélyezi ezt a műveletet" "Kihagyja a navigáció bemutatóját?" "Ezt később megtalálhatja a(z) %1$s alkalmazásban" diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml index 0f9356a42d..cc49954127 100644 --- a/quickstep/res/values-hy/strings.xml +++ b/quickstep/res/values-hy/strings.xml @@ -77,6 +77,8 @@ "Ուղեցույց %1$d/%2$d" "Պատրաստ է" "Մատը սահեցրեք վերև՝ հիմնական էկրան անցնելու համար" + + "Դուք արդեն կարող եք օգտագործել ձեր հեռախոսը" "Դուք արդեն կարող եք օգտագործել ձեր պլանշետը" "Նավիգացիայի համակարգային կարգավորումներ" @@ -84,7 +86,8 @@ "Սքրինշոթ անել" "Տրոհել" "Հպեք այլ հավելվածի՝ էկրանը տրոհելու համար" - "Հավելվածը չի աջակցում էկրանի տրոհումը։" + + "Այս գործողությունն արգելված է հավելվածի կամ ձեր կազմակերպության կողմից" "Բաց թողնե՞լ նավիգացիայի ուղեցույցը" "Հետագայում սա կարող եք գտնել «%1$s» հավելվածում" diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml index b95871f9f6..9012ba6cd9 100644 --- a/quickstep/res/values-in/strings.xml +++ b/quickstep/res/values-in/strings.xml @@ -77,6 +77,8 @@ "Tutorial %1$d/%2$d" "Semua siap." "Geser ke atas untuk beralih ke Layar utama" + + "Anda sudah siap untuk mulai menggunakan ponsel" "Anda sudah siap untuk mulai menggunakan tablet" "Setelan navigasi sistem" @@ -84,7 +86,8 @@ "Screenshot" "Pisahkan" "Ketuk aplikasi lain untuk menggunakan layar terpisah" - "Aplikasi tidak mendukung layar terpisah." + + "Tindakan ini tidak diizinkan oleh aplikasi atau organisasi Anda" "Lewati tutorial gestur?" "Anda dapat menemukan tutorial ini di lain waktu di aplikasi %1$s" diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml index 5730900804..d7f2075cfe 100644 --- a/quickstep/res/values-is/strings.xml +++ b/quickstep/res/values-is/strings.xml @@ -77,6 +77,8 @@ "Leiðsögn %1$d/%2$d" "Allt tilbúið!" "Strjúktu upp til að fara á heimaskjáinn" + + "Þú getur byrjað að nota símann" "Þú getur byrjað að nota spjaldtölvuna" "Stillingar kerfisstjórnunar" @@ -84,7 +86,8 @@ "Skjámynd" "Skipta" "Ýttu á annað forrit til að nota skjáskiptingu" - "Forritið styður ekki að skjánum sé skipt." + + "Forritið eða fyrirtækið leyfir ekki þessa aðgerð" "Sleppa flettileiðsögn?" "Þú getur fundið þetta síðar í forritinu %1$s" diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml index 7e04cf66ab..7df4dee155 100644 --- a/quickstep/res/values-it/strings.xml +++ b/quickstep/res/values-it/strings.xml @@ -77,6 +77,8 @@ "Tutorial %1$d/%2$d" "Finito." "Scorri verso l\'alto per andare alla schermata Home" + + "Puoi iniziare a usare il tuo telefono" "Puoi iniziare a usare il tuo tablet" "Impostazioni Navigazione del sistema" @@ -84,7 +86,8 @@ "Screenshot" "Dividi" "Tocca un\'altra app per usare lo schermo diviso" - "L\'app non supporta la modalità Schermo diviso." + + "Questa azione non è consentita dall\'app o dall\'organizzazione" "Saltare il tutorial di navigazione?" "Puoi trovarlo in un secondo momento nell\'app %1$s" diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml index 56148e79ff..899011a35a 100644 --- a/quickstep/res/values-iw/strings.xml +++ b/quickstep/res/values-iw/strings.xml @@ -77,6 +77,8 @@ "מדריך %1$d/%2$d" "הכול מוכן!" "כדי לעבור לדף הבית, מחליקים כלפי מעלה" + + "הכול מוכן ואפשר להתחיל להשתמש בטלפון" "הכול מוכן ואפשר להתחיל להשתמש בטאבלט" "הגדרות הניווט של המערכת" @@ -84,7 +86,8 @@ "צילום מסך" "פיצול" "צריך להקיש על אפליקציה אחרת כדי להשתמש במסך מפוצל" - "האפליקציה אינה תומכת במסך מפוצל." + + "האפליקציה או הארגון שלך אינם מתירים את הפעולה הזאת" "לדלג על המדריך לניווט?" "ניתן למצוא את המדריך מאוחר יותר באפליקציה %1$s" diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml index 013939f900..3614e2db4d 100644 --- a/quickstep/res/values-ja/strings.xml +++ b/quickstep/res/values-ja/strings.xml @@ -77,6 +77,8 @@ "チュートリアル %1$d/%2$d" "設定完了" "ホームに移動するには上にスワイプします" + + "スマートフォンを使用する準備ができました" "これでタブレットが使えるようになりました" "システム ナビゲーションの設定" @@ -84,7 +86,8 @@ "スクリーンショット" "分割" "分割画面を使用するには、他のアプリをタップします" - "アプリで分割画面がサポートされていません。" + + "この操作はアプリまたは組織で許可されていません" "操作チュートリアルをスキップしますか?" "チュートリアルは後から %1$s アプリで確認できます" diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml index d54ac881c3..b862c6f5d8 100644 --- a/quickstep/res/values-ka/strings.xml +++ b/quickstep/res/values-ka/strings.xml @@ -77,6 +77,8 @@ "სახელმძღვანელო %1$d/%2$d" "მზადაა!" "მთავარ გვერდზე გადასასვლელად გადაფურცლეთ ზევით" + + "მზად ხართ ტელეფონის გამოსაყენებლად" "მზად ხართ ტაბლეტის გამოსაყენებლად" "სისტემის ნავიგაციის პარამეტრები" @@ -84,7 +86,8 @@ "ეკრანის ანაბეჭდი" "გაყოფა" "შეეხეთ სხვა აპს ეკრანის გასაყოფად" - "ეკრანის გაყოფა არ არის მხარდაჭერილი აპის მიერ." + + "ეს მოქმედება არ არის დაშვებული აპის ან თქვენი ორგანიზაციის მიერ" "გსურთ, გამოტოვოთ ნავიგაციის სახელმძღვანელო?" "ამის მოგვიანებით პოვნა %1$s აპში შეგიძლიათ" diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml index bfa2a5cf37..8f42ff6c53 100644 --- a/quickstep/res/values-kk/strings.xml +++ b/quickstep/res/values-kk/strings.xml @@ -77,6 +77,8 @@ "Оқулық: %1$d/%2$d" "Бәрі дайын!" "Негізгі экранға өту үшін жоғары қарай сырғытыңыз." + + "Телефоныңыз пайдалануға дайын." "Планшетіңіз пайдалануға дайын." "Навигацияның жүйелік параметрлері" @@ -84,7 +86,8 @@ "Скриншот" "Бөлу" "Экранды бөлу режимін пайдалану үшін басқа қолданбаны түртіңіз." - "Қолданбада экранды бөлу мүмкін емес." + + "Бұл әрекетке қолданба не ұйым рұқсат етпейді." "Қимылдар оқулығын өткізіп жіберу керек пе?" "Мұны кейін %1$s қолданбасынан таба аласыз." diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml index 4a78d9d79a..d1ed52899b 100644 --- a/quickstep/res/values-km/strings.xml +++ b/quickstep/res/values-km/strings.xml @@ -77,6 +77,8 @@ "មេរៀនទី %1$d/%2$d" "រួចហើយ!" "អូសឡើងលើ ដើម្បី​ទៅកាន់​អេក្រង់ដើម" + + "អ្នក​អាច​ចាប់ផ្ដើម​ប្រើ​ទូរសព្ទ​របស់អ្នក​បានហើយ" "អ្នកអាចចាប់ផ្ដើមប្រើថេប្លេតរបស់អ្នកបានហើយ" "ការកំណត់​ការរុករក​ប្រព័ន្ធ" @@ -84,7 +86,8 @@ "រូបថតអេក្រង់" "បំបែក" "ចុចកម្មវិធី​ផ្សេងទៀត ដើម្បីប្រើមុខងារ​បំបែកអេក្រង់" - "កម្មវិធីមិនអាចប្រើមុខងារ​បំបែកអេក្រង់បានទេ។" + + "សកម្មភាពនេះ​មិនត្រូវបានអនុញ្ញាតដោយកម្មវិធី​ ឬ​ស្ថាប័ន​របស់អ្នកទេ" "រំលង​មេរៀន​អំពី​ការរុករក​ឬ?" "អ្នកអាចស្វែងរកមេរៀននេះនៅពេលក្រោយក្នុងកម្មវិធី %1$s" diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml index 91a12f86b7..99fb8ba089 100644 --- a/quickstep/res/values-kn/strings.xml +++ b/quickstep/res/values-kn/strings.xml @@ -77,6 +77,8 @@ "ಟ್ಯುಟೋರಿಯಲ್ %1$d/%2$d" "ಎಲ್ಲವೂ ಸಿದ್ಧವಾಗಿದೆ!" "ಮುಖಪುಟಕ್ಕೆ ಹೋಗಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ" + + "ನಿಮ್ಮ ಫೋನ್ ಬಳಸುವುದನ್ನು ಪ್ರಾರಂಭಿಸಲು ನೀವು ಸಿದ್ದರಾಗಿರುವಿರಿ" "ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌‌ ಬಳಸುವುದನ್ನು ಪ್ರಾರಂಭಿಸಲು ನೀವು ಸಿದ್ದರಾಗಿರುವಿರಿ" "ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಶನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು" @@ -84,7 +86,8 @@ "ಸ್ಕ್ರೀನ್‌ಶಾಟ್" "ವಿಭಜಿಸಿ" "ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬಳಸಲು ಬೇರೊಂದು ಆ್ಯಪ್ ಮೇಲೆ ಟ್ಯಾಪ್ ಮಾಡಿ" - "ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಆ್ಯಪ್ ಬೆಂಬಲಿಸುವುದಿಲ್ಲ." + + "ಆ್ಯಪ್ ಅಥವಾ ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಕ್ರಿಯೆಯನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ" "ನ್ಯಾವಿಗೇಶನ್ ಟ್ಯುಟೋರಿಯಲ್ ಸ್ಕಿಪ್ ಮಾಡಬೇಕೇ?" "%1$s ಆ್ಯಪ್‌ನಲ್ಲಿ ಇದನ್ನು ನಂತರ ಕಾಣಬಹುದು" diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml index bfe98f9780..8af2ef782e 100644 --- a/quickstep/res/values-ko/strings.xml +++ b/quickstep/res/values-ko/strings.xml @@ -77,6 +77,8 @@ "튜토리얼 %1$d/%2$d" "설정 완료" "위로 스와이프하여 홈으로 이동" + + "휴대전화를 사용할 준비가 되었습니다." "태블릿을 사용할 준비가 되었습니다." "시스템 탐색 설정" @@ -84,7 +86,8 @@ "스크린샷" "분할" "다른 앱을 탭하여 화면 분할 사용" - "앱이 화면 분할을 지원하지 않습니다." + + "이 작업은 앱 또는 조직에서 허용되지 않습니다." "이동 방법 튜토리얼을 건너뛰시겠습니까?" "이 튜토리얼은 %1$s 앱에서 다시 볼 수 있습니다." diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml index 5472eadc8b..b7721f4d91 100644 --- a/quickstep/res/values-ky/strings.xml +++ b/quickstep/res/values-ky/strings.xml @@ -77,6 +77,8 @@ "Үйрөткүч: %1$d/%2$d" "Бүттү!" "Башкы бетке өтүү үчүн экранды өйдө сүрүңүз" + + "Телефонуңузду колдоно берсеңиз болот" "Планшетиңизди колдоно берсеңиз болот" "Өтүү аракетинин системалык параметрлери" @@ -84,7 +86,8 @@ "Скриншот" "Бөлүү" "Экранды бөлүү үчүн башка колдонмону таптап коюңуз" - "Колдонмодо экран бөлүнбөйт." + + "Бул аракетти аткарууга колдонмо же ишканаңыз тыюу салган" "Жаңсоолор үйрөткүчүн өткөрүп жибересизби?" "Аны кийин %1$s колдонмосунан табасыз" diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml index 7d87ec483e..a1d8640631 100644 --- a/quickstep/res/values-lo/strings.xml +++ b/quickstep/res/values-lo/strings.xml @@ -77,6 +77,8 @@ "ການສອນການນຳໃຊ້ທີ %1$d/%2$d" "ຮຽບຮ້ອຍໝົດແລ້ວ!" "ປັດຂຶ້ນເພື່ອໄປຫາໜ້າຫຼັກ" + + "ທ່ານພ້ອມເລີ່ມຕົ້ນໃຊ້ໂທລະສັບຂອງທ່ານແລ້ວ" "ທ່ານພ້ອມເລີ່ມຕົ້ນໃຊ້ແທັບເລັດຂອງທ່ານແລ້ວ" "ການຕັ້ງຄ່າການນຳທາງລະບົບ" @@ -84,7 +86,8 @@ "ຮູບໜ້າຈໍ" "ແບ່ງ" "ແຕະແອັບອື່ນເພື່ອໃຊ້ການແຍກໜ້າຈໍ" - "ແອັບບໍ່ຮອງຮັບການແບ່ງໜ້າຈໍ." + + "ແອັບ ຫຼື ອົງການຂອງທ່ານບໍ່ອະນຸຍາດໃຫ້ໃຊ້ຄຳສັ່ງນີ້" "ຂ້າມການສອນການນຳໃຊ້ການນຳທາງບໍ?" "ທ່ານສາມາດຊອກສ່ວນນີ້ພາຍຫຼັງໄດ້ໃນແອັບ %1$s" diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml index b60146f35d..0ee9f0a2a7 100644 --- a/quickstep/res/values-lt/strings.xml +++ b/quickstep/res/values-lt/strings.xml @@ -77,6 +77,8 @@ "Mokymo programa: %1$d%2$d" "Paruošta!" "Perbraukite aukštyn, kad grįžtumėte į pagrindinį ekraną" + + "Esate pasiruošę pradėti naudoti telefoną" "Esate pasiruošę pradėti naudoti planšetinį kompiuterį" "Sistemos naršymo nustatymai" @@ -84,7 +86,8 @@ "Ekrano kopija" "Išskaidymo režimas" "Pal. kitą progr., kad gal. naud. išsk. ekr. rež." - "Programoje nepalaikomas išskaidyto ekrano režimas." + + "Jūsų organizacijoje arba naudojant šią programą neleidžiama atlikti šio veiksmo" "Praleisti naršymo mokymo programą?" "Tai galėsite rasti vėliau programoje „%1$s“" diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml index d3c3b80cad..27460f43e7 100644 --- a/quickstep/res/values-lv/strings.xml +++ b/quickstep/res/values-lv/strings.xml @@ -77,6 +77,8 @@ "%1$d. mācību darbība no %2$d" "Gatavs!" "Velciet augšup, lai pārietu uz sākuma ekrānu." + + "Varat sākt izmantot savu tālruni" "Varat sākt izmantot savu planšetdatoru" "Sistēmas navigācijas iestatījumi" @@ -84,7 +86,8 @@ "Veikt ekrānuzņēmumu" "Sadalīt" "Piesk. citai lietotnei, lai izm. ekrāna sadalīšanu" - "Lietotnē netiek atbalstīta ekrāna sadalīšana." + + "Lietotne vai jūsu organizācija neatļauj veikt šo darbību." "Vai izlaist navigācijas mācības?" "Varēsiet to vēlāk atrast lietotnē %1$s." diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml index 7ac9ad0f9e..38ec94bf8d 100644 --- a/quickstep/res/values-mk/strings.xml +++ b/quickstep/res/values-mk/strings.xml @@ -77,6 +77,8 @@ "Упатство %1$d/%2$d" "Готово!" "Повлечете нагоре за да појдете на почетниот екран" + + "Спремни сте да почнете да го користите телефонот" "Спремни сте да почнете да го користите таблетот" "Поставки за системска навигација" @@ -84,7 +86,8 @@ "Слика од екранот" "Раздели" "Допрете друга апликација за да користите поделен екран" - "Апликацијата не поддржува поделен екран." + + "Апликацијата или вашата организација не го дозволува дејствово" "Да се прескокне упатството за навигација?" "Ова може да го најдете подоцна во апликацијата %1$s" diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml index 90fc5138b4..bc7efb9395 100644 --- a/quickstep/res/values-ml/strings.xml +++ b/quickstep/res/values-ml/strings.xml @@ -77,6 +77,8 @@ "ട്യൂട്ടോറിയൽ %1$d/%2$d" "എല്ലാം സജ്ജീകരിച്ചു!" "ഹോമിലേക്ക് പോകാൻ മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക" + + "ഫോൺ ഉപയോഗിച്ച് തുടങ്ങാൻ നിങ്ങൾ തയ്യാറാണ്" "ടാബ്‌ലെറ്റ് ഉപയോഗിച്ച് തുടങ്ങാൻ നിങ്ങൾ തയ്യാറാണ്" "സിസ്‌റ്റം നാവിഗേഷൻ ക്രമീകരണം" @@ -84,7 +86,8 @@ "സ്ക്രീൻഷോട്ട്" "വിഭജിക്കുക" "സ്പ്ലിറ്റ് സ്ക്രീനിനായി മറ്റൊരു ആപ്പ് ടാപ്പുചെയ്യൂ" - "സ്പ്ലിറ്റ്-സ്ക്രീനിനെ ആപ്പ് പിന്തുണയ്ക്കുന്നില്ല." + + "ഈ നടപടി എടുക്കുന്നത് ആപ്പോ നിങ്ങളുടെ സ്ഥാപനമോ അനുവദിക്കുന്നില്ല" "നാവിഗേഷൻ ട്യൂട്ടോറിയൽ ഒഴിവാക്കണോ?" "%1$s ആപ്പിൽ നിങ്ങൾക്ക് ഇത് പിന്നീട് കാണാനാകും" diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml index c435528b66..45e66e4c6e 100644 --- a/quickstep/res/values-mn/strings.xml +++ b/quickstep/res/values-mn/strings.xml @@ -77,6 +77,8 @@ "%1$d/%2$d практик хичээл" "Тохируулж дууслаа!" "Нүүр хуудас руу очихын тулд дээш шударна уу" + + "Та утсаа ашиглаж эхлэхэд бэлэн боллоо" "Та таблетаа ашиглаж эхлэхэд бэлэн боллоо" "Системийн навигацын тохиргоо" @@ -84,7 +86,8 @@ "Дэлгэцийн агшин дарах" "Хуваах" "Дэлгэц хуваахыг ашиглах бол өөр аппыг товшино уу" - "Апп дэлгэцийг хуваах горимыг дэмждэггүй." + + "Энэ үйлдлийг апп эсвэл танай байгууллага зөвшөөрдөггүй" "Навигацын практик хичээлийг алгасах уу?" "Та үүнийг дараа нь %1$s аппаас олох боломжтой" diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml index fc9027133b..f6f8c142df 100644 --- a/quickstep/res/values-mr/strings.xml +++ b/quickstep/res/values-mr/strings.xml @@ -77,6 +77,8 @@ "ट्यूटोरियल %1$d/%2$d" "सर्व तयार आहे!" "होम वर जाण्यासाठी वरती स्वाइप करा" + + "तुम्ही तुमचा फोन वापरण्यास सुरुवात करू शकता" "तुम्ही तुमचा टॅबलेट वापरण्यास सुरुवात करू शकता" "सिस्टीम नेव्हिगेशन सेटिंग्ज" @@ -84,7 +86,8 @@ "स्क्रीनशॉट" "स्प्लिट" "स्प्लिटस्क्रीन वापरण्यासाठी दुसऱ्या ॲपवर टॅप करा" - "अ‍ॅप हे स्प्लिट-स्क्रीनला सपोर्ट करत नाही." + + "अ‍ॅप किंवा तुमच्या संस्थेद्वारे ही क्रिया करण्याची अनुमती नाही" "नेव्हिगेशन ट्यूटोरियल वगळायचे आहे का?" "तुम्हाला हे नंतर %1$s ॲपमध्ये मिळेल" diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml index 5d3f4a8896..d173790e28 100644 --- a/quickstep/res/values-ms/strings.xml +++ b/quickstep/res/values-ms/strings.xml @@ -77,6 +77,8 @@ "Tutorial %1$d/%2$d" "Siap!" "Leret ke atas untuk kembali ke Laman Utama" + + "Anda sudah sedia untuk mula menggunakan telefon anda" "Anda bersedia untuk mula menggunakan tablet anda" "Tetapan navigasi sistem" @@ -84,7 +86,8 @@ "Tangkapan skrin" "Pisah" "Ketik apl lain untuk menggunakan skrin pisah" - "Apl tidak menyokong skrin pisah." + + "Tindakan ini tidak dibenarkan oleh apl atau organisasi anda" "Langkau tutorial navigasi?" "Anda boleh mendapatkan tutorial ini kemudian dalam apl %1$s" diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml index 8f6af710ee..20441d1771 100644 --- a/quickstep/res/values-my/strings.xml +++ b/quickstep/res/values-my/strings.xml @@ -77,6 +77,8 @@ "ရှင်းလင်းပို့ချချက် %1$d/%2$d" "အားလုံး အဆင်သင့်ပါ။" "ပင်မစာမျက်နှာသို့သွားရန် အပေါ်သို့ ပွတ်ဆွဲပါ" + + "သင့်ဖုန်း စသုံးရန် အသင့်ဖြစ်ပါပြီ" "သင့်တက်ဘလက်ကို စသုံးရန် အသင့်ဖြစ်ပါပြီ" "စနစ် လမ်းညွှန် ဆက်တင်များ" @@ -84,7 +86,8 @@ "ဖန်သားပြင်ဓာတ်ပုံ" "ခွဲထုတ်ရန်" "မျက်နှာပြင်ခွဲ၍ပြသရန် အက်ပ်နောက်တစ်ခုကို တို့ပါ" - "အက်ပ်တွင် မျက်နှာပြင် ခွဲ၍ပြသခြင်း သုံး၍မရပါ။" + + "ဤလုပ်ဆောင်ချက်ကို အက်ပ် သို့မဟုတ် သင်၏အဖွဲ့အစည်းက ခွင့်မပြုပါ" "လမ်းညွှန်ခြင်း ရှင်းလင်းပို့ချချက်ကို ကျော်မလား။" "၎င်းကို နောက်မှ %1$s အက်ပ်တွင် ရှာနိုင်သည်" diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml index eff2e3ca92..4045c7c80a 100644 --- a/quickstep/res/values-nb/strings.xml +++ b/quickstep/res/values-nb/strings.xml @@ -77,6 +77,8 @@ "Veiledning %1$d/%2$d" "Alt er klart!" "Sveip opp for å gå til startskjermen" + + "Du er klar til å begynne å bruke telefonen" "Du er klar til å begynne å bruke nettbrettet" "Innstillinger for systemnavigasjon" @@ -84,7 +86,8 @@ "Skjermdump" "Del opp" "Trykk på en annen app for å bruke delt skjerm" - "Appen støtter ikke delt skjerm." + + "Appen eller organisasjonen din tillater ikke denne handlingen" "Vil du hoppe over navigeringsveiledningen?" "Du kan finne dette i %1$s-appen senere" diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml index 3a23567b74..fe081fec42 100644 --- a/quickstep/res/values-ne/strings.xml +++ b/quickstep/res/values-ne/strings.xml @@ -77,6 +77,8 @@ "ट्युटोरियल %1$d/%2$d" "सबै तयार भयो!" "होममा जान माथितिर स्वाइप गर्नुहोस्" + + "तपाईं आफ्नो फोन चलाउन थाल्न सक्नुहुन्छ" "तपाईं अब आफ्नो ट्याब्लेट चलाउन थाल्न सक्नुहुन्छ" "सिस्टम नेभिगेसनसम्बन्धी सेटिङ" @@ -84,7 +86,8 @@ "स्क्रिनसट" "स्प्लिट गर्नुहोस्" "स्प्लिटक्रिन प्रयोग गर्न अर्को एपमा ट्याप गर्नुहोस्" - "यो एपको स्क्रिन विभाजन गर्न मिल्दैन।" + + "यो एप वा तपाईंको सङ्गठनले यो कारबाही गर्ने अनुमति दिँदैन" "नेभिगेसन ट्युटोरियल स्किप गर्ने हो?" "तपाईं पछि %1$s नामक एपमा गई यो ट्युटोरियल भेट्टाउन सक्नुहुन्छ" diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml index 650e3403d0..543983310e 100644 --- a/quickstep/res/values-nl/strings.xml +++ b/quickstep/res/values-nl/strings.xml @@ -77,6 +77,8 @@ "Tutorial %1$d/%2$d" "Klaar" "Swipe omhoog om naar het startscherm te gaan" + + "Je bent klaar om je telefoon te gebruiken" "Je bent klaar om je tablet te gebruiken" "Navigatie-instellingen van systeem" @@ -84,7 +86,8 @@ "Screenshot" "Splitsen" "Tik op nog een app om je scherm te splitsen" - "App ondersteunt geen gesplitst scherm." + + "Deze actie wordt niet toegestaan door de app of je organisatie" "Navigatietutorial overslaan?" "Je vindt dit later terug in de app %1$s" diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml index 5016399d95..aa998bab5f 100644 --- a/quickstep/res/values-or/strings.xml +++ b/quickstep/res/values-or/strings.xml @@ -77,6 +77,8 @@ "ଟ୍ୟୁଟୋରିଆଲ୍ %1$d/%2$d" "ସମ୍ପୂର୍ଣ୍ଣ ଭାବେ ପ୍ରସ୍ତୁତ!" "ହୋମକୁ ଯିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ କରନ୍ତୁ" + + "ଆପଣ ଆପଣଙ୍କ ଫୋନ୍ ବ୍ୟବହାର କରିବା ପାଇଁ ପ୍ରସ୍ତୁତ ଅଛନ୍ତି" "ଆପଣ ଆପଣଙ୍କ ଟାବଲେଟ ବ୍ୟବହାର କରିବା ଆରମ୍ଭ କରିବାକୁ ପ୍ରସ୍ତୁତ ଅଛନ୍ତି" "ସିଷ୍ଟମ ନାଭିଗେସନ ସେଟିଂସ" @@ -84,7 +86,8 @@ "ସ୍କ୍ରିନସଟ୍" "ସ୍ପ୍ଲିଟ୍" "ସ୍ପ୍ଲିଟସ୍କ୍ରିନ ବ୍ୟବହାର କରିବାକୁ ଅନ୍ୟ ଏକ ଆପରେ ଟାପ କର" - "ସ୍ପ୍ଲିଟ-ସ୍କ୍ରିନକୁ ଆପ ସମର୍ଥନ କରେ ନାହିଁ।" + + "ଆପ୍ କିମ୍ବା ଆପଣଙ୍କ ସଂସ୍ଥା ଦ୍ୱାରା ଏହି କାର୍ଯ୍ୟକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ" "ନାଭିଗେସନ୍ ଟ୍ୟୁଟୋରିଆଲକୁ ବାଦ୍ ଦେବେ?" "ଆପଣ ପରେ ଏହାକୁ %1$s ଆପରେ ପାଇପାରିବେ" diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml index 7d1d2b5f66..4bcf4d6ae2 100644 --- a/quickstep/res/values-pa/strings.xml +++ b/quickstep/res/values-pa/strings.xml @@ -77,6 +77,8 @@ "ਟਿਊਟੋਰੀਅਲ %1$d/%2$d" "ਪੂਰੀ ਤਰ੍ਹਾਂ ਤਿਆਰ!" "ਹੋਮ \'ਤੇ ਜਾਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ" + + "ਤੁਸੀਂ ਆਪਣਾ ਫ਼ੋਨ ਵਰਤਣ ਲਈ ਤਿਆਰ ਹੋ" "ਤੁਸੀਂ ਆਪਣਾ ਟੈਬਲੈੱਟ ਵਰਤਣ ਲਈ ਤਿਆਰ ਹੋ" "ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਸੈਟਿੰਗਾਂ" @@ -84,7 +86,8 @@ "ਸਕ੍ਰੀਨਸ਼ਾਟ" "ਸਪਲਿਟ" "ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਰਤਣ ਲਈ ਕਿਸੇ ਹੋਰ ਐਪ \'ਤੇ ਟੈਪ ਕਰੋ" - "ਐਪ ਸਪਲਿਟ-ਸਕ੍ਰੀਨ ਦਾ ਸਮਰਥਨ ਨਹੀਂ ਕਰਦੀ।" + + "ਐਪ ਜਾਂ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਇਸ ਕਾਰਵਾਈ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ" "ਕੀ ਨੈਵੀਗੇਸ਼ਨ ਟਿਊਟੋਰੀਅਲ ਨੂੰ ਛੱਡਣਾ ਹੈ?" "ਤੁਸੀਂ ਇਸਨੂੰ ਬਾਅਦ ਵਿੱਚ %1$s ਐਪ ਵਿੱਚ ਲੱਭ ਸਕਦੇ ਹੋ" diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml index 3c73de487f..0394bb7f72 100644 --- a/quickstep/res/values-pl/strings.xml +++ b/quickstep/res/values-pl/strings.xml @@ -77,6 +77,8 @@ "Samouczek %1$d/%2$d" "Wszystko gotowe" "Aby przejść na ekran główny, przesuń palcem w górę" + + "Teraz możesz zacząć używać telefonu" "Teraz możesz zacząć używać tabletu" "Ustawienia nawigacji w systemie" @@ -84,7 +86,8 @@ "Zrzut ekranu" "Podziel" "Kliknij drugą aplikację, aby podzielić ekran" - "Aplikacja nie obsługuje podzielonego ekranu." + + "Nie możesz wykonać tego działania, bo nie zezwala na to aplikacja lub Twoja organizacja" "Pominąć samouczek nawigacji?" "Znajdziesz to później w aplikacji %1$s" diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml index 5e01dc187f..47bc834b64 100644 --- a/quickstep/res/values-pt-rPT/strings.xml +++ b/quickstep/res/values-pt-rPT/strings.xml @@ -77,6 +77,8 @@ "Tutorial %1$d/%2$d" "Tudo pronto!" "Deslize rapidamente para cima para aceder ao ecrã principal" + + "Já pode começar a utilizar o seu telemóvel" "Já pode começar a usar o seu tablet" "Definições de navegação do sistema" @@ -84,7 +86,8 @@ "Fazer captura de ecrã" "Dividir" "Toque noutra app para utilizar o ecrã dividido" - "A app não é compatível com o ecrã dividido." + + "Esta ação não é permitida pela app ou a sua entidade." "Ignorar o tutorial de navegação?" "Pode encontrar isto mais tarde na app %1$s" diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml index fad2170e85..6a366089f1 100644 --- a/quickstep/res/values-pt/strings.xml +++ b/quickstep/res/values-pt/strings.xml @@ -77,6 +77,8 @@ "Tutorial %1$d/%2$d" "Tudo pronto!" "Deslize para cima para acessar a tela inicial" + + "Você já pode começar a usar seu smartphone" "Você já pode começar a usar seu tablet" "Configurações de navegação do sistema" @@ -84,7 +86,8 @@ "Capturar tela" "Dividir" "Toque em outro app para dividir a tela" - "O app não tem suporte para a divisão de tela." + + "Essa ação não é permitida pelo app ou pela organização" "Pular o tutorial de navegação?" "Veja o tutorial mais tarde no app %1$s" diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml index 8b8c187033..9856a6c1e1 100644 --- a/quickstep/res/values-ro/strings.xml +++ b/quickstep/res/values-ro/strings.xml @@ -77,6 +77,8 @@ "Tutorialul %1$d / %2$d" "Gata!" "Glisează în sus pentru a accesa ecranul de pornire" + + "Ești gata să folosești telefonul" "Ești gata să folosești tableta" "Setările de navigare ale sistemului" @@ -84,7 +86,8 @@ "Captură de ecran" "Împărțit" "Atinge altă aplicație pentru ecranul împărțit" - "Aplicația nu acceptă ecranul împărțit." + + "Această acțiune nu este permisă de aplicație sau de organizația ta" "Omiți tutorialul de navigare?" "Îl poți găsi mai târziu în aplicația %1$s" diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml index e078ba0aad..de3343e10a 100644 --- a/quickstep/res/values-ru/strings.xml +++ b/quickstep/res/values-ru/strings.xml @@ -77,6 +77,8 @@ "Руководство (шаг %1$d из %2$d)" "Готово!" "Чтобы перейти на главный экран, проведите вверх." + + "Теперь вы можете использовать телефон." "Теперь вы можете использовать планшет." "Системные настройки навигации" @@ -84,7 +86,8 @@ "Скриншот" "Разделить" "Для разделения экрана нажмите на другое приложение." - "Приложение не поддерживает разделение экрана." + + "Это действие заблокировано приложением или организацией." "Пропустить руководство по жестам?" "Его можно найти в приложении \"%1$s\"." diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml index f890548f58..509490c612 100644 --- a/quickstep/res/values-si/strings.xml +++ b/quickstep/res/values-si/strings.xml @@ -77,6 +77,8 @@ "නිබන්ධනය %1$d/%2$d" "සියල්ල සූදානම්!" "මුල් පිටුවට යාමට ඉහළට ස්වයිප් කරන්න" + + "ඔබ ඔබගේ දුරකථනය භාවිත කිරීම පටන් ගැනීමට සූදානම්" "ඔබ ඔබගේ ටැබ්ලටය භාවිත කිරීම පටන් ගැනීමට සූදානම්" "පද්ධති සංචාලන සැකසීම්" @@ -84,7 +86,8 @@ "තිර රුව" "බෙදන්න" "බෙදුම් තිරය භාවිත කිරීමට තවත් යෙදුමක් තට්ටු කරන්න" - "යෙදුම බෙදුම් තිරය සඳහා සහාය නොදක්වයි." + + "මෙම ක්‍රියාව යෙදුම හෝ ඔබේ සංවිධානය මගින් ඉඩ නොදේ" "නිබන්ධනය සංචාලනය මඟ හරින්නද?" "ඔබට මෙය පසුව %1$s යෙදුම තුළ සොයා ගත හැකිය" diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml index cdf33391ee..f9372def02 100644 --- a/quickstep/res/values-sk/strings.xml +++ b/quickstep/res/values-sk/strings.xml @@ -77,6 +77,8 @@ "Návod %1$d/%2$d" "Hotovo" "Potiahnutím nahor prejdete na plochu" + + "Telefón môžete začať používať" "Tablet môžete začať používať" "Nastavenia navigácie systémom" @@ -84,7 +86,8 @@ "Snímka obrazovky" "Rozdeliť" "Rozdel. obrazovku spustíte klepnutím na inú aplik." - "Aplikácia nepodporuje rozdelenú obrazovku." + + "Aplikácia alebo vaša organizácia túto akciu nepovoľuje" "Chcete preskočiť návod na navigáciu?" "Tento návod nájdete v aplikácii %1$s" diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml index 3e7c5ce681..0a5a271462 100644 --- a/quickstep/res/values-sl/strings.xml +++ b/quickstep/res/values-sl/strings.xml @@ -77,6 +77,8 @@ "Vadnica %1$d/%2$d" "Končano" "Povlecite navzgor za začetni zaslon" + + "Pripravljeni ste, da začnete uporabljati telefon" "Pripravljeni ste, da začnete uporabljati tablični računalnik." "Nastavitve krmarjenja po sistemu" @@ -84,7 +86,8 @@ "Posnetek zaslona" "Razdeli" "Za uporabo razdeljenega zaslona se dotaknite še ene aplikacije." - "Aplikacija ne podpira načina razdeljenega zaslona." + + "Aplikacija ali vaša organizacija ne dovoljuje tega dejanja" "Želite preskočiti vadnico za krmarjenje?" "To lahko pozneje najdete v aplikaciji %1$s." diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml index 04b7bc152f..f326693364 100644 --- a/quickstep/res/values-sq/strings.xml +++ b/quickstep/res/values-sq/strings.xml @@ -77,6 +77,8 @@ "Udhëzuesi %1$d/%2$d" "Plotësisht gati!" "Rrëshqit shpejt lart për të shkuar tek \"Ekrani bazë\"" + + "Je gati për të filluar përdorimin e telefonit tënd" "Je gati që të fillosh të përdorësh tabletin" "Cilësimet e navigimit të sistemit" @@ -84,7 +86,8 @@ "Pamja e ekranit" "Ndaj" "Trokit aplikacion tjetër e përdor ekranin e ndarë" - "Aplikacioni nuk mbështet ekranin e ndarë." + + "Ky veprim nuk lejohet nga aplikacioni ose organizata jote" "Të kapërcehet udhëzuesi i navigimit?" "Këtë mund ta gjesh më vonë tek aplikacioni \"%1$s\"" diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml index 215fde9100..518023aeac 100644 --- a/quickstep/res/values-sr/strings.xml +++ b/quickstep/res/values-sr/strings.xml @@ -77,6 +77,8 @@ "Водич %1$d/%2$d" "Готово!" "Превуците нагоре да бисте отворили почетни екран" + + "Спремни сте да почнете да користите телефон" "Спремни сте да почнете да користите таблет" "Подешавања кретања кроз систем" @@ -84,7 +86,8 @@ "Снимак екрана" "Подели" "Додирните другу апликацију за подељени екран" - "Апликација не подржава подељени екран." + + "Апликација или организација не дозвољавају ову радњу" "Желите да прескочите водич за кретање?" "Можете да пронађете ово касније у апликацији %1$s" diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml index e7c0226337..2d9db938d3 100644 --- a/quickstep/res/values-sv/strings.xml +++ b/quickstep/res/values-sv/strings.xml @@ -77,6 +77,8 @@ "Självstudie %1$d/%2$d" "Klart!" "Svep uppåt för att öppna startskärmen" + + "Nu kan du börja använda telefonen" "Nu kan du börja använda surfplattan" "Systemnavigeringsinställningar" @@ -84,7 +86,8 @@ "Skärmbild" "Delat" "Tryck på en annan app för att använda delad skärm" - "Appen har inte stöd för delad skärm." + + "Appen eller organisationen tillåter inte den här åtgärden" "Vill du hoppa över självstudierna?" "Du hittar det här igen i %1$s-appen" diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml index b1a178e9b3..aadf378f1f 100644 --- a/quickstep/res/values-sw/strings.xml +++ b/quickstep/res/values-sw/strings.xml @@ -77,6 +77,8 @@ "Mafunzo ya %1$d kati ya %2$d" "Tayari!" "Telezesha kidole juu ili uende kwenye skrini ya kwanza" + + "Uko tayari kuanza kutumia simu yako" "Uko tayari kuanza kutumia kompyuta kibao yako" "Mipangilio ya usogezaji kwenye mfumo" @@ -84,7 +86,8 @@ "Picha ya skrini" "Iliyogawanywa" "Gusa programu nyingine ili utumie skrini iliyogawanywa" - "Programu haiwezi kutumia skrini iliyogawanywa." + + "Kitendo hiki hakiruhusiwi na programu au shirika lako" "Ungependa kuruka mafunzo ya usogezaji?" "Utapata mafunzo haya baadaye katika programu ya %1$s" diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml index 431ae3cce5..77c3c37d98 100644 --- a/quickstep/res/values-ta/strings.xml +++ b/quickstep/res/values-ta/strings.xml @@ -77,6 +77,8 @@ "பயிற்சி %1$d/%2$d" "அனைத்தையும் அமைத்துவிட்டீர்கள்!" "முகப்புத் திரைக்குச் செல்ல மேல்நோக்கி ஸ்வைப் செய்யுங்கள்" + + "மொபைலைப் பயன்படுத்தத் தயாராகிவிட்டீர்கள்" "உங்கள் டேப்லெட்டைப் பயன்படுத்தத் தயாராகிவிட்டீர்கள்" "சிஸ்டம் வழிசெலுத்தல் அமைப்புகள்" @@ -84,7 +86,8 @@ "ஸ்கிரீன்ஷாட்" "பிரி" "ஸ்பிளிட் ஸ்கிரீனுக்கு மற்றொரு ஆப்ஸைத் தட்டவும்" - "திரைப் பிரிப்பு அம்சத்தை ஆப்ஸ் ஆதரிக்கவில்லை." + + "ஆப்ஸோ உங்கள் நிறுவனமோ இந்த செயலை அனுமதிப்பதில்லை" "வழிகாட்டுதல் பயிற்சியைத் தவிர்க்கவா?" "%1$s ஆப்ஸில் பிறகு இதைக் கண்டறியலாம்" diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml index 7b6dedf757..052ca5d477 100644 --- a/quickstep/res/values-te/strings.xml +++ b/quickstep/res/values-te/strings.xml @@ -77,6 +77,8 @@ "ట్యుటోరియల్ %1$d/%2$d" "అంతా సెట్ అయింది!" "మొదటి స్క్రీన్‌కు వెళ్లడానికి పైకి స్వైప్ చేయండి" + + "మీరు మీ ఫోన్‌ను ఉపయోగించడానికి సిద్ధంగా ఉన్నారు" "మీరు మీ టాబ్లెట్‌ను ఉపయోగించడానికి సిద్ధంగా ఉన్నారు" "సిస్టమ్ నావిగేషన్ సెట్టింగ్‌లు" @@ -84,7 +86,8 @@ "స్క్రీన్‌షాట్" "స్ప్లిట్ చేయండి" "స్క్రీన్ విభజనను ఉపయోగించడానికి మరొక యాప్ నొక్కండి" - "యాప్‌లో స్ప్లిట్-స్క్రీన్ పని చేయదు." + + "ఈ చర్యను యాప్ గానీ, మీ సంస్థ గానీ అనుమతించవు" "నావిగేషన్ ట్యుటోరియల్‌ను స్కిప్ చేయాలా?" "%1$s యాప్‌లో మీరు తర్వాత కనుగొనవచ్చు" diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml index 4d5794b8a7..13f0e12c90 100644 --- a/quickstep/res/values-th/strings.xml +++ b/quickstep/res/values-th/strings.xml @@ -77,6 +77,8 @@ "บทแนะนำ %1$d/%2$d" "เรียบร้อยแล้ว" "ปัดขึ้นเพื่อไปที่หน้าแรก" + + "คุณเริ่มใช้โทรศัพท์ได้แล้ว" "คุณเริ่มใช้แท็บเล็ตได้แล้ว" "การตั้งค่าการนำทางของระบบ" @@ -84,7 +86,8 @@ "ภาพหน้าจอ" "แยก" "แตะที่แอปอื่นเพื่อใช้แบ่งหน้าจอ" - "แอปไม่รองรับการแบ่งหน้าจอ" + + "แอปหรือองค์กรของคุณไม่อนุญาตการดำเนินการนี้" "ข้ามบทแนะนำการนำทางไหม" "คุณดูบทแนะนำนี้ได้ภายหลังในแอป \"%1$s\"" diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml index 6699ed876d..68b39025fd 100644 --- a/quickstep/res/values-tl/strings.xml +++ b/quickstep/res/values-tl/strings.xml @@ -77,6 +77,8 @@ "Tutorial %1$d/%2$d" "Handa na ang lahat!" "Mag-swipe pataas para pumunta sa Home" + + "Handa mo nang simulan ang paggamit sa iyong telepono" "Handa mo nang simulan ang paggamit sa iyong tablet" "Mga setting ng navigation ng system" @@ -84,7 +86,8 @@ "Screenshot" "Split" "Mag-tap ng ibang app para gamitin ang splitscreen" - "Hindi sinusuportahan ng app ang split-screen." + + "Hindi pinapayagan ng app o ng iyong organisasyon ang pagkilos na ito" "Laktawan ang tutorial sa pag-navigate?" "Makikita mo ito sa %1$s app sa ibang pagkakataon" diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml index 24e25ff5bb..c7f7ac9b28 100644 --- a/quickstep/res/values-tr/strings.xml +++ b/quickstep/res/values-tr/strings.xml @@ -77,6 +77,8 @@ "Eğitim %1$d/%2$d" "İşlem tamam!" "Ana ekrana gitmek için yukarı kaydırın" + + "Telefonunuzu kullanmaya hazırsınız" "Tabletinizi kullanmaya hazırsınız" "Sistem gezinme ayarları" @@ -84,7 +86,8 @@ "Ekran görüntüsü" "Böl" "Bölünmüş ekran için başka bir uygulamaya dokunun" - "Uygulama bölünmüş ekranı desteklemiyor." + + "Uygulamanız veya kuruluşunuz bu işleme izin vermiyor" "Gezinme eğitimi atlansın mı?" "Bunu daha sonra %1$s uygulamasında bulabilirsiniz" diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml index 8dd65e2cf0..173f637f09 100644 --- a/quickstep/res/values-uk/strings.xml +++ b/quickstep/res/values-uk/strings.xml @@ -77,6 +77,8 @@ "Навчальний посібник %1$d/%2$d" "Готово." "Щоб перейти на головний екран, проведіть пальцем угору" + + "Тепер ви можете користуватися телефоном" "Тепер ви можете користуватися планшетом" "Системні налаштування навігації" @@ -84,7 +86,8 @@ "Знімок екрана" "Розділити" "Щоб розділити екран, виберіть ще один додаток" - "Додаток не підтримує розділення екрана." + + "Ця дія заборонена додатком або адміністратором організації" "Пропустити посібник із навігації?" "Ви знайдете його пізніше в додатку %1$s" diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml index 2d9a1e30f2..89e518b0ed 100644 --- a/quickstep/res/values-ur/strings.xml +++ b/quickstep/res/values-ur/strings.xml @@ -77,6 +77,8 @@ "ٹیوٹوریل %1$d/%2$d" "سب کچھ تیار ہے!" "ہوم پر جانے کے لیے اوپر سوائپ کریں" + + "آپ اپنا فون استعمال شروع کرنے کے لیے تیار ہیں" "آپ اپنے ٹیبلیٹ کا استعمال شروع کرنے کے لیے تیار ہیں" "سسٹم نیویگیشن کی ترتیبات" @@ -84,7 +86,8 @@ "اسکرین شاٹ" "اسپلٹ" "اسپلٹ اسکرین کا استعمال کرنے کیلئے دوسری ایپ پر تھپتھپائیں" - "ایپ سپلٹ اسکرین کو سپورٹ نہیں کرتی۔" + + "ایپ یا آپ کی تنظیم کی جانب سے اس کارروائی کی اجازت نہیں ہے" "نیویگیشن کا ٹیوٹوریل نظر انداز کریں؟" "آپ اسے بعد میں %1$s ایپ میں تلاش کر سکتے ہیں" diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml index 9446325829..56a76d5f58 100644 --- a/quickstep/res/values-uz/strings.xml +++ b/quickstep/res/values-uz/strings.xml @@ -77,6 +77,8 @@ "Darslik: %1$d/%2$d" "Hammasi tayyor!" "Boshiga qaytish uchun tepaga suring" + + "Telefoningiz xizmatga tayyor" "Planshetingiz xizmatga tayyor" "Tizim navigatsiya sozlamalari" @@ -84,7 +86,8 @@ "Skrinshot" "Ajratish" "Ekranni ikkiga ajratish uchun boshqa ilovani bosing" - "Bu ilovada ekranni ikkiga ajratish ishlamaydi." + + "Bu amal ilova yoki tashkilotingiz tomonidan taqiqlangan" "Navigatsiya darsi yopilsinmi?" "Bu darslar %1$s ilovasida chiqadi" diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml index 55027aeda3..3b17966f88 100644 --- a/quickstep/res/values-vi/strings.xml +++ b/quickstep/res/values-vi/strings.xml @@ -77,6 +77,8 @@ "Hướng dẫn %1$d/%2$d" "Đã hoàn tất!" "Vuốt lên để chuyển đến Màn hình chính" + + "Vậy là bạn đã sẵn sàng sử dụng điện thoại của mình" "Bạn đã sẵn sàng sử dụng máy tính bảng" "Chế độ cài đặt di chuyển trên hệ thống" @@ -84,7 +86,8 @@ "Chụp ảnh màn hình" "Chia đôi màn hình" "Nhấn vào một ứng dụng khác để dùng màn hình chia đôi" - "Ứng dụng không hỗ trợ chia đôi màn hình." + + "Ứng dụng hoặc tổ chức của bạn không cho phép thực hiện hành động này" "Bỏ qua phần hướng dẫn thao tác?" "Bạn có thể tìm lại phần hướng dẫn này trong ứng dụng %1$s" diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml index debf23a9cc..0ff369e38d 100644 --- a/quickstep/res/values-zh-rCN/strings.xml +++ b/quickstep/res/values-zh-rCN/strings.xml @@ -77,6 +77,8 @@ "教程 %1$d/%2$d" "大功告成!" "向上滑动即可转到主屏幕" + + "您可以开始使用手机了" "您可以开始使用平板电脑了" "系统导航设置" @@ -84,7 +86,8 @@ "屏幕截图" "拆分" "点按另一个应用即可使用分屏" - "应用不支持分屏。" + + "该应用或您所在的单位不允许执行此操作" "要跳过导航教程吗?" "您之后可以在“%1$s”应用中找到此教程" diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml index c7a44e7d3f..ff648dfe62 100644 --- a/quickstep/res/values-zh-rHK/strings.xml +++ b/quickstep/res/values-zh-rHK/strings.xml @@ -77,6 +77,8 @@ "教學課程 %1$d/%2$d" "設定完成!" "向上滑動即可前往主畫面" + + "您可以開始使用手機了" "您可以開始使用平板電腦了" "系統導覽設定" @@ -84,7 +86,8 @@ "螢幕截圖" "分割" "輕按其他應用程式以使用分割螢幕" - "應用程式不支援分割螢幕。" + + "應用程式或您的機構不允許此操作" "要略過手勢操作教學課程嗎?" "您之後可以在「%1$s」應用程式找到這些說明" diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml index 15d5de5ecb..23bee1757a 100644 --- a/quickstep/res/values-zh-rTW/strings.xml +++ b/quickstep/res/values-zh-rTW/strings.xml @@ -77,6 +77,8 @@ "教學課程 %1$d/%2$d" "設定完成!" "向上滑動即可前往主畫面" + + "你可以開始使用手機了" "你可以開始使用平板電腦了" "系統操作機制設定" @@ -84,7 +86,8 @@ "螢幕截圖" "分割" "輕觸另一個應用程式即可使用分割畫面" - "這個應用程式不支援分割畫面。" + + "這個應用程式或貴機構不允許執行這個動作" "要略過手勢操作教學課程嗎?" "你之後可以在「%1$s」應用程式找到這些說明" diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml index 3db58360db..46ba92994f 100644 --- a/quickstep/res/values-zu/strings.xml +++ b/quickstep/res/values-zu/strings.xml @@ -77,6 +77,8 @@ "Okokufundisa %1$d/%2$d" "Konke kusethiwe!" "Swayiphela phezulu ukuze uye Ekhaya" + + "Usulungele ukuqala ukusebenzisa ifoni yakho" "Usulungele ukuqala ukusebenzisa ithebulethi yakho" "Amasethingi wokuzulazula isistimu" @@ -84,7 +86,8 @@ "Isithombe-skrini" "Hlukanisa" "Thepha enye i-app ukuze usebenzise isikrini sokuhlukanisa" - "Uhlelo lokusebenza alusekeli isikrini esihlukanisiwe." + + "Lesi senzo asivunyelwanga uhlelo lokusebenza noma inhlangano yakho" "Yeqa isifundo sokuzulazula?" "Lokhu ungakuthola kamuva ku-app ye-%1$s" From 91235e9169516f059a8ac8b0653fe5473c68ac11 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 16 Nov 2022 02:39:22 -0800 Subject: [PATCH 234/429] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ie6806240014abdb72e330a6c6041de01360ad6ec --- go/quickstep/res/values-en-rCA/strings.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/go/quickstep/res/values-en-rCA/strings.xml b/go/quickstep/res/values-en-rCA/strings.xml index 676ac43284..664bd94219 100644 --- a/go/quickstep/res/values-en-rCA/strings.xml +++ b/go/quickstep/res/values-en-rCA/strings.xml @@ -1,19 +1,19 @@ - "Share app" + "Share App" "Listen" "Translate" "Lens" - "OK" + "GOT IT" "CANCEL" "SETTINGS" "Translate or listen to text on screen" - "Information such as text on your screen, web addresses and screenshots may be shared with Google.\n\nTo change what information you share, go to ""Settings > Apps > Default apps > Digital assistant app""." + "Information such as text on your screen, web addresses, and screenshots may be shared with Google.\n\nTo change what information you share, go to ""Settings > Apps > Default apps > Digital assistant app""." "Choose an assistant to use this feature" - "To listen to or translate text on your screen, choose a digital assistant app in settings" + "To listen to or translate text on your screen, choose a digital assistant app in Settings" "Change your assistant to use this feature" - "To listen to or translate text on your screen, change your digital assistant app in settings" + "To listen to or translate text on your screen, change your digital assistant app in Settings" "Tap here to listen to text on this screen" "Tap here to translate text on this screen" "This app can’t be shared" From 70e0c71cd1b4c94b0b6f6545064d06f0d9f5c0a6 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 16 Nov 2022 02:40:28 -0800 Subject: [PATCH 235/429] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: I7eda4dbb8c5c8f9fee5beca5c0aab3dd7e9392f3 --- res/values-en-rCA/strings.xml | 42 +++++++++++++++++------------------ 1 file changed, 21 insertions(+), 21 deletions(-) diff --git a/res/values-en-rCA/strings.xml b/res/values-en-rCA/strings.xml index 4f15eb5777..aa29d8dc2f 100644 --- a/res/values-en-rCA/strings.xml +++ b/res/values-en-rCA/strings.xml @@ -32,12 +32,12 @@ "Split left" "Split right" "App info for %1$s" - "Touch and hold to move a widget." + "Touch & hold to move a widget." "Double-tap & hold to move a widget or use custom actions." "%1$d × %2$d" "%1$d wide by %2$d high" "%1$s widget" - "Touch and hold the widget to move it around the home screen" + "Touch & hold the widget to move it around the home screen" "Add to home screen" "%1$s widget added to home screen" "{count,plural, =1{# widget}other{# widgets}}" @@ -54,18 +54,18 @@ "Useful info at your fingertips" "To get info without opening apps, you can add widgets to your home screen" "Tap to change widget settings" - "OK" + "Got it" "Change widget settings" "Search apps" "Loading apps…" - "No apps found matching \'%1$s\'" + "No apps found matching \"%1$s\"" "App" "All apps" "Notifications" "Touch & hold to move a shortcut." "Double-tap & hold to move a shortcut or use custom actions." "No room on this home screen" - "No more room in the Favourites tray" + "No more room in the Favorites tray" "Apps list" "Search results" "Personal apps list" @@ -75,13 +75,13 @@ "App info" "Install" "Don\'t suggest app" - "Pin prediction" + "Pin Prediction" "install shortcuts" "Allows an app to add shortcuts without user intervention." - "read Home settings and shortcuts" - "Allows the app to read the settings and shortcuts in Home." - "write Home settings and shortcuts" - "Allows the app to change the settings and shortcuts in Home." + "read home settings and shortcuts" + "Allows the app to read the settings and shortcuts in home." + "write home settings and shortcuts" + "Allows the app to change the settings and shortcuts in home." "%1$s is not allowed to make phone calls" "Can\'t load widget" "Widget settings" @@ -101,7 +101,7 @@ "Folder: %1$s, %2$d items" "Folder: %1$s, %2$d or more items" "Wallpapers" - "Wallpaper and style" + "Wallpaper & style" "Home settings" "Disabled by your admin" "Allow home screen rotation" @@ -113,7 +113,7 @@ "To show Notification Dots, turn on app notifications for %1$s" "Change settings" "Show notification dots" - "Developer options" + "Developer Options" "Add app icons to home screen" "For new apps" "Unknown" @@ -125,7 +125,7 @@ "%1$s downloading, %2$s complete" "%1$s waiting to install" "App update required" - "The app for this icon isn\'t updated. You can update manually to re-enable this shortcut or remove the icon." + "The app for this icon isn\'t updated. You can update manually to re-enable this shortcut, or remove the icon." "Update" "Remove" "Widgets list" @@ -138,7 +138,7 @@ "Move item" "Move to row %1$s column %2$s in %3$s" "Move to position %1$s" - "Move to favourites position %1$s" + "Move to favorites position %1$s" "Item moved" "Add to folder: %1$s" "Add to folder with %1$s" @@ -146,13 +146,13 @@ "Create folder with: %1$s" "Folder created" "Move to home screen" - "Re-size" + "Resize" "Increase width" "Increase height" "Decrease width" "Decrease height" - "Widget re-sized to width %1$s height %2$s" - "Short cuts" + "Widget resized to width %1$s height %2$s" + "Shortcuts" "Shortcuts and notifications" "Dismiss" "Close" @@ -161,12 +161,12 @@ "Work" "Work profile" "Work apps are badged and visible to your IT admin" - "OK" + "Got it" "Work apps are paused" - "Your work apps can’t send you notifications, use your battery or access your location" - "Work apps are off. Your work apps can’t send you notifications, use your battery or access your location" + "Your work apps can’t send you notifications, use your battery, or access your location" + "Work apps are off. Your work apps can’t send you notifications, use your battery, or access your location" "Work apps are badged and visible to your IT admin" - "OK" + "Got it" "Pause work apps" "Turn on work apps" "Filter" From c8c81a3425d4c6562bf29a902616e9f3268ce3db Mon Sep 17 00:00:00 2001 From: Sam Dubey Date: Wed, 16 Nov 2022 10:22:12 +0000 Subject: [PATCH 236/429] Revert "Allow transient taskbar to unstash over soft ime" This reverts commit 9787ae6ad9be6caf2a0d4c5f3ec1a1e950772bda. Reason for revert: Breaking launcher tests on Tablet Bug: 259347305 Change-Id: Idfd9e412f143370b6b8a4c6f86aac94d17bc1846 --- .../launcher3/taskbar/TaskbarStashController.java | 9 --------- 1 file changed, 9 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 5b0b3a2219..72ae1d1c31 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -745,11 +745,6 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba mIsImeShowing = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_IME_SHOWING); mIsImeSwitcherShowing = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_IME_SWITCHER_SHOWING); if (!mIsSystemGestureInProgress) { - if (mIsImeShowing || mIsImeSwitcherShowing) { - // Hide taskbar when IME is shown. - updateStateForFlag(FLAG_STASHED_IN_APP_AUTO, true); - } - updateStateForFlag(FLAG_STASHED_IN_APP_IME, shouldStashForIme()); animDuration = TASKBAR_STASH_DURATION_FOR_IME; startDelay = getTaskbarStashStartDelayForIme(); @@ -763,12 +758,8 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba * * in small screen AND * * 3 button nav AND * * landscape (or seascape) - * We do not stash if taskbar is transient */ private boolean shouldStashForIme() { - if (DisplayController.isTransientTaskbar(mActivity)) { - return false; - } return (mIsImeShowing || mIsImeSwitcherShowing) && !(isPhoneMode() && mActivity.isThreeButtonNav() && mActivity.getDeviceProfile().isLandscape); From 182d1e93dda2e538f6ae8e2ca036d95757f374ec Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Wed, 16 Nov 2022 08:01:50 -0800 Subject: [PATCH 237/429] Check NPE and log error condition for enableTransientTaskbar in test harness. Fixes: 259337908 Bug: 257549303 Test: TaplTestsTaskbar Change-Id: Ifa929dca18437ae101cf3290feda4209790604d2 --- .../quickstep/QuickstepTestInformationHandler.java | 12 ++++++++++-- .../launcher3/testing/shared/TestProtocol.java | 1 + 2 files changed, 11 insertions(+), 2 deletions(-) diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java index 6f124b8418..65614ba966 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -1,5 +1,6 @@ package com.android.quickstep; +import static com.android.launcher3.testing.shared.TestProtocol.NPE_TRANSIENT_TASKBAR; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import android.app.Activity; @@ -7,6 +8,7 @@ import android.content.Context; import android.content.res.Resources; import android.graphics.Rect; import android.os.Bundle; +import android.util.Log; import androidx.annotation.Nullable; @@ -184,9 +186,15 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { private void enableTransientTaskbar( TouchInteractionService.TISBinder tisBinder, boolean enable) { - // Allow null-pointer to catch illegal states. TaskbarActivityContext context = tisBinder.getTaskbarManager().getCurrentActivityContext(); - DisplayController.INSTANCE.get(context).enableTransientTaskbarForTests(enable); + if (context == null) { + if (TestProtocol.sDebugTracing) { + Log.d(NPE_TRANSIENT_TASKBAR, "enableTransientTaskbar: enable=" + enable, + new Exception()); + } + } else { + DisplayController.INSTANCE.get(context).enableTransientTaskbarForTests(enable); + } } /** diff --git a/src/com/android/launcher3/testing/shared/TestProtocol.java b/src/com/android/launcher3/testing/shared/TestProtocol.java index 7586d0bc31..46e5891117 100644 --- a/src/com/android/launcher3/testing/shared/TestProtocol.java +++ b/src/com/android/launcher3/testing/shared/TestProtocol.java @@ -148,6 +148,7 @@ public final class TestProtocol { public static final String MISSING_PROMISE_ICON = "b/202985412"; public static final String TASKBAR_IN_APP_STATE = "b/227657604"; public static final String INCORRECT_INFO_UPDATED = "b/239465630"; + public static final String NPE_TRANSIENT_TASKBAR = "b/257549303"; public static final String REQUEST_EMULATE_DISPLAY = "emulate-display"; public static final String REQUEST_STOP_EMULATE_DISPLAY = "stop-emulate-display"; From f641ddd27e82f8d7fb8f0d28aea1c1f115bce55a Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Wed, 16 Nov 2022 16:12:22 +0000 Subject: [PATCH 238/429] Revert "Revert "Allow transient taskbar to unstash over soft ime"" This reverts commit c8c81a3425d4c6562bf29a902616e9f3268ce3db. Reason for revert: fix tests by not auto stashing when ime comes up, but still allow taskbar to show if user initiaties it Bug: 255818649 Change-Id: Id3ab27dcc205e5a72dbd0481e3eabc10b2e1b643 Test: pull up ime, swipe to reveal taskbar --- .../com/android/launcher3/taskbar/TaskbarStashController.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 72ae1d1c31..b7f12c1201 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -758,8 +758,12 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba * * in small screen AND * * 3 button nav AND * * landscape (or seascape) + * We do not stash if taskbar is transient */ private boolean shouldStashForIme() { + if (DisplayController.isTransientTaskbar(mActivity)) { + return false; + } return (mIsImeShowing || mIsImeSwitcherShowing) && !(isPhoneMode() && mActivity.isThreeButtonNav() && mActivity.getDeviceProfile().isLandscape); From 905e0f16378fc36aedad00b70d922455013eb5e4 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Mon, 14 Nov 2022 21:55:37 +0000 Subject: [PATCH 239/429] Update overview to fit transient taskbar Bug: 245320601 Test: manual Change-Id: Ie2085811ef25dc03a3765559c9a0ee37e38aa38e --- src/com/android/launcher3/DeviceProfile.java | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index c91e3ebcf4..3cb3461f8f 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -255,6 +255,7 @@ public class DeviceProfile { public boolean isTaskbarPresentInApps; public int taskbarSize; public int stashedTaskbarSize; + public int transientTaskbarMargin; // DragController public int flingToDeleteThresholdVelocity; @@ -320,6 +321,8 @@ public class DeviceProfile { taskbarSize = res.getDimensionPixelSize(R.dimen.transient_taskbar_size); stashedTaskbarSize = res.getDimensionPixelSize(R.dimen.transient_taskbar_stashed_size); + transientTaskbarMargin = + res.getDimensionPixelSize(R.dimen.transient_taskbar_margin); } else { taskbarSize = res.getDimensionPixelSize(R.dimen.taskbar_size); stashedTaskbarSize = res.getDimensionPixelSize(R.dimen.taskbar_stashed_size); @@ -1305,15 +1308,15 @@ public class DeviceProfile { * Returns the number of pixels required below OverviewActions excluding insets. */ public int getOverviewActionsClaimedSpaceBelow() { - if (isTaskbarPresent && !isGestureMode - // If taskbar is in overview, overview action has dedicated space above nav buttons - && !FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get()) { - // Align vertically to where nav buttons are. - return ((taskbarSize - overviewActionsHeight) / 2) + getTaskbarOffsetY(); - } - if (isTaskbarPresent) { - return FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get() ? taskbarSize : stashedTaskbarSize; + if (FeatureFlags.ENABLE_TASKBAR_IN_OVERVIEW.get()) { + return taskbarSize + transientTaskbarMargin; + } + + return isGestureMode + ? stashedTaskbarSize + // Align vertically to where nav buttons are. + : ((taskbarSize - overviewActionsHeight) / 2) + getTaskbarOffsetY(); } return mInsets.bottom; } From 6abdd5c73531c0bd145613a33fbdd0d653a5bddc Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Wed, 16 Nov 2022 13:57:28 -0800 Subject: [PATCH 240/429] Removing unnecessary event dispatching via touch-controller. Instead using a poll method similar to other touch controllers Bug: 259447608 Test: Verified on device Change-Id: I5c29c7c1b87acb668ea93e9f44fb685379de54fb --- .../NoButtonNavbarToOverviewTouchController.java | 16 ++++++---------- .../android/quickstep/BaseActivityInterface.java | 3 --- .../quickstep/FallbackActivityInterface.java | 5 ----- .../quickstep/LauncherActivityInterface.java | 9 --------- .../quickstep/OverviewComponentObserver.java | 5 ----- src/com/android/launcher3/Launcher.java | 8 -------- .../android/launcher3/dragndrop/DragLayer.java | 11 ----------- .../android/launcher3/util/TouchController.java | 5 ----- 8 files changed, 6 insertions(+), 56 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java index 918b3c1bf8..f343f525b5 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonNavbarToOverviewTouchController.java @@ -26,6 +26,7 @@ import static com.android.launcher3.Utilities.EDGE_NAV_BAR; import static com.android.launcher3.anim.AnimatorListeners.forSuccessCallback; import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; import static com.android.quickstep.util.VibratorWrapper.OVERVIEW_HAPTIC; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_ONE_HANDED_ACTIVE; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_OVERVIEW_DISABLED; import android.animation.ObjectAnimator; @@ -86,6 +87,11 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch @Override protected boolean canInterceptTouch(MotionEvent ev) { mDidTouchStartInNavBar = (ev.getEdgeFlags() & EDGE_NAV_BAR) != 0; + boolean isOneHandedModeActive = (SystemUiProxy.INSTANCE.get(mLauncher) + .getLastSystemUiStateFlags() & SYSUI_STATE_ONE_HANDED_ACTIVE) != 0; + // Reset touch slop multiplier to default 1.0f if one-handed-mode is not active + mDetector.setTouchSlopMultiplier( + isOneHandedModeActive ? ONE_HANDED_ACTIVATED_SLOP_MULTIPLIER : 1f /* default */); return super.canInterceptTouch(ev) && !mLauncher.isInState(HINT_STATE); } @@ -277,14 +283,4 @@ public class NoButtonNavbarToOverviewTouchController extends PortraitStatesTouch private float dpiFromPx(float pixels) { return Utilities.dpiFromPx(pixels, mLauncher.getResources().getDisplayMetrics().densityDpi); } - - @Override - public void onOneHandedModeStateChanged(boolean activated) { - if (activated) { - mDetector.setTouchSlopMultiplier(ONE_HANDED_ACTIVATED_SLOP_MULTIPLIER); - } else { - // Reset touch slop multiplier to default 1.0f - mDetector.setTouchSlopMultiplier(1f /* default */); - } - } } diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java index a62232620d..2c3ba85136 100644 --- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java +++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java @@ -121,9 +121,6 @@ public abstract class BaseActivityInterface callback); diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java index c62220f54b..ae9fb0b385 100644 --- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java +++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java @@ -77,11 +77,6 @@ public final class FallbackActivityInterface extends // set to zero prior to this class becoming active. } - @Override - public void onOneHandedModeStateChanged(boolean activated) { - // Do nothing for FallbackActivityInterface - } - /** 6 */ @Override public AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState, diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java index ecb37474e6..9ff941671b 100644 --- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java +++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java @@ -108,15 +108,6 @@ public final class LauncherActivityInterface extends launcher.onAssistantVisibilityChanged(visibility); } - @Override - public void onOneHandedModeStateChanged(boolean activated) { - Launcher launcher = getCreatedActivity(); - if (launcher == null) { - return; - } - launcher.onOneHandedStateChanged(activated); - } - @Override public AnimationFactory prepareRecentsUI(RecentsAnimationDeviceState deviceState, boolean activityVisible, Consumer callback) { diff --git a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java index 9e3173c1f0..8e07376b14 100644 --- a/quickstep/src/com/android/quickstep/OverviewComponentObserver.java +++ b/quickstep/src/com/android/quickstep/OverviewComponentObserver.java @@ -115,11 +115,6 @@ public final class OverviewComponentObserver { if (mDeviceState.isHomeDisabled() != mIsHomeDisabled) { updateOverviewTargets(); } - - // Notify ALL_APPS touch controller when one handed mode state activated or deactivated - if (mDeviceState.isOneHandedModeEnabled()) { - mActivityInterface.onOneHandedModeStateChanged(mDeviceState.isOneHandedModeActive()); - } } private void updateOverviewTargets(Intent unused) { diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index ab7f6226c9..8453f2c1dc 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -647,14 +647,6 @@ public class Launcher extends StatefulActivity mHotseat.getQsb().setAlpha(1f - visibility); } - /** - * Called when one handed mode activated and deactivated. - * @param activated true if one handed mode activated, false otherwise. - */ - public void onOneHandedStateChanged(boolean activated) { - mDragLayer.onOneHandedModeStateChanged(activated); - } - /** * Returns {@code true} if a new DeviceProfile is initialized, and {@code false} otherwise. */ diff --git a/src/com/android/launcher3/dragndrop/DragLayer.java b/src/com/android/launcher3/dragndrop/DragLayer.java index 1ee7fc1fa3..366870b4c2 100644 --- a/src/com/android/launcher3/dragndrop/DragLayer.java +++ b/src/com/android/launcher3/dragndrop/DragLayer.java @@ -56,7 +56,6 @@ import com.android.launcher3.celllayout.CellLayoutLayoutParams; import com.android.launcher3.folder.Folder; import com.android.launcher3.graphics.Scrim; import com.android.launcher3.keyboard.ViewGroupFocusHelper; -import com.android.launcher3.util.TouchController; import com.android.launcher3.views.BaseDragLayer; import com.android.systemui.plugins.shared.LauncherOverlayManager.LauncherOverlayCallbacks; @@ -474,16 +473,6 @@ public class DragLayer extends BaseDragLayer implements LauncherOverla return mWorkspaceDragScrim; } - /** - * Called when one handed mode state changed. - * @param activated true if one handed mode activated, false otherwise. - */ - public void onOneHandedModeStateChanged(boolean activated) { - for (TouchController controller : mControllers) { - controller.onOneHandedModeStateChanged(activated); - } - } - @Override public void onOverlayScrollChanged(float progress) { float alpha = 1 - Interpolators.DEACCEL_3.getInterpolation(progress); diff --git a/src/com/android/launcher3/util/TouchController.java b/src/com/android/launcher3/util/TouchController.java index 9c397c0f74..fc1d819f78 100644 --- a/src/com/android/launcher3/util/TouchController.java +++ b/src/com/android/launcher3/util/TouchController.java @@ -32,10 +32,5 @@ public interface TouchController { */ boolean onControllerInterceptTouchEvent(MotionEvent ev); - /** - * Called when one handed mode state changed - */ - default void onOneHandedModeStateChanged(boolean activated) { } - default void dump(String prefix, PrintWriter writer) { } } From aa2b872d1c295aef1e56e5a60ada1cc871a7add8 Mon Sep 17 00:00:00 2001 From: Sihua Ma Date: Tue, 25 Oct 2022 15:17:58 -0700 Subject: [PATCH 241/429] Move most of the functions in LauncherAppWidgetHost to LauncherWidgetHolder Test: N/A Bug: 235358918 Change-Id: I343419376491203a195154f2766b12e5def38879 --- .../launcher3/uioverrides/ApiWrapper.java | 4 +- .../QuickstepInteractionHandler.java | 6 +- .../launcher3/AppWidgetsRestoredReceiver.java | 15 +- .../android/launcher3/AutoInstallsLayout.java | 15 +- .../launcher3/DefaultLayoutParser.java | 11 +- src/com/android/launcher3/Launcher.java | 1 + .../android/launcher3/LauncherProvider.java | 111 ++--- .../launcher3/LauncherWidgetHolder.java | 392 ++++++++++++++++-- src/com/android/launcher3/Workspace.java | 2 +- .../launcher3/dragndrop/AddItemActivity.java | 24 +- .../graphics/LauncherPreviewRenderer.java | 4 +- .../launcher3/provider/RestoreDbTask.java | 6 +- .../widget/LauncherAppWidgetHost.java | 364 ++-------------- .../widget/LauncherAppWidgetHostView.java | 11 + .../widget/picker/WidgetsFullSheet.java | 2 +- .../launcher3/uioverrides/ApiWrapper.java | 4 +- .../android/launcher3/util/WidgetUtils.java | 22 +- 17 files changed, 534 insertions(+), 460 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java index 729eea9834..8002c6d525 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java +++ b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java @@ -23,8 +23,8 @@ import android.content.pm.ShortcutInfo; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.launcher3.LauncherWidgetHolder; import com.android.launcher3.Utilities; -import com.android.launcher3.widget.LauncherAppWidgetHost; /** * A wrapper for the hidden API calls @@ -44,7 +44,7 @@ public class ApiWrapper { * @param handler InteractionHandler for the views in the host */ public static void setHostInteractionHandler(@NonNull AppWidgetHost host, - @Nullable LauncherAppWidgetHost.LauncherWidgetInteractionHandler handler) { + @Nullable LauncherWidgetHolder.LauncherWidgetInteractionHandler handler) { host.setInteractionHandler(handler::onInteraction); } } diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java index 2dde6b6148..6a6c824ed8 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java @@ -29,16 +29,16 @@ import android.view.View; import android.widget.RemoteViews; import android.window.SplashScreen; +import com.android.launcher3.LauncherWidgetHolder; import com.android.launcher3.Utilities; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.util.ActivityOptionsWrapper; -import com.android.launcher3.widget.LauncherAppWidgetHost; import com.android.launcher3.widget.LauncherAppWidgetHostView; /** Provides a Quickstep specific animation when launching an activity from an app widget. */ -class QuickstepInteractionHandler implements - LauncherAppWidgetHost.LauncherWidgetInteractionHandler { +class QuickstepInteractionHandler + implements LauncherWidgetHolder.LauncherWidgetInteractionHandler { private static final String TAG = "QuickstepInteractionHandler"; diff --git a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java index 75e89b2944..8604f1acd4 100644 --- a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java +++ b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java @@ -2,7 +2,6 @@ package com.android.launcher3; import static android.os.Process.myUserHandle; -import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.content.BroadcastReceiver; @@ -12,6 +11,7 @@ import android.content.Intent; import android.database.Cursor; import android.util.Log; +import androidx.annotation.NonNull; import androidx.annotation.WorkerThread; import com.android.launcher3.LauncherSettings.Favorites; @@ -21,7 +21,6 @@ import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.pm.UserCache; import com.android.launcher3.provider.RestoreDbTask; import com.android.launcher3.util.ContentWriter; -import com.android.launcher3.widget.LauncherAppWidgetHost; public class AppWidgetsRestoredReceiver extends BroadcastReceiver { @@ -32,7 +31,7 @@ public class AppWidgetsRestoredReceiver extends BroadcastReceiver { if (AppWidgetManager.ACTION_APPWIDGET_HOST_RESTORED.equals(intent.getAction())) { int hostId = intent.getIntExtra(AppWidgetManager.EXTRA_HOST_ID, 0); Log.d(TAG, "Widget ID map received for host:" + hostId); - if (hostId != LauncherAppWidgetHost.APPWIDGET_HOST_ID) { + if (hostId != LauncherWidgetHolder.APPWIDGET_HOST_ID) { return; } @@ -50,11 +49,11 @@ public class AppWidgetsRestoredReceiver extends BroadcastReceiver { * Updates the app widgets whose id has changed during the restore process. */ @WorkerThread - public static void restoreAppWidgetIds(Context context, int[] oldWidgetIds, int[] newWidgetIds) { - AppWidgetHost appWidgetHost = new LauncherAppWidgetHost(context); + public static void restoreAppWidgetIds(Context context, int[] oldWidgetIds, int[] newWidgetIds, + @NonNull LauncherWidgetHolder holder) { if (WidgetsModel.GO_DISABLE_WIDGETS) { Log.e(TAG, "Skipping widget ID remap as widgets not supported"); - appWidgetHost.deleteHost(); + holder.deleteHost(); return; } if (!RestoreDbTask.isPending(context)) { @@ -63,7 +62,7 @@ public class AppWidgetsRestoredReceiver extends BroadcastReceiver { Log.e(TAG, "Skipping widget ID remap as DB already in use"); for (int widgetId : newWidgetIds) { Log.d(TAG, "Deleting widgetId: " + widgetId); - appWidgetHost.deleteAppWidgetId(widgetId); + holder.deleteAppWidgetId(widgetId); } return; } @@ -100,7 +99,7 @@ public class AppWidgetsRestoredReceiver extends BroadcastReceiver { try { if (!cursor.moveToFirst()) { // The widget no long exists. - appWidgetHost.deleteAppWidgetId(newWidgetIds[i]); + holder.deleteAppWidgetId(newWidgetIds[i]); } } finally { cursor.close(); diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java index 64666b0041..0003510ab1 100644 --- a/src/com/android/launcher3/AutoInstallsLayout.java +++ b/src/com/android/launcher3/AutoInstallsLayout.java @@ -16,7 +16,6 @@ package com.android.launcher3; -import android.appwidget.AppWidgetHost; import android.content.ComponentName; import android.content.ContentValues; import android.content.Context; @@ -74,7 +73,7 @@ public class AutoInstallsLayout { private static final String FORMATTED_LAYOUT_RES = "default_layout_%dx%d"; private static final String LAYOUT_RES = "default_layout"; - static AutoInstallsLayout get(Context context, AppWidgetHost appWidgetHost, + static AutoInstallsLayout get(Context context, LauncherWidgetHolder appWidgetHolder, LayoutParserCallback callback) { Pair customizationApkInfo = PackageManagerHelper.findSystemApk( ACTION_LAUNCHER_CUSTOMIZATION, context.getPackageManager()); @@ -109,7 +108,7 @@ public class AutoInstallsLayout { Log.e(TAG, "Layout definition not found in package: " + pkg); return null; } - return new AutoInstallsLayout(context, appWidgetHost, callback, targetRes, layoutId, + return new AutoInstallsLayout(context, appWidgetHolder, callback, targetRes, layoutId, TAG_WORKSPACE); } @@ -156,7 +155,7 @@ public class AutoInstallsLayout { @Thunk final Context mContext; @Thunk - final AppWidgetHost mAppWidgetHost; + final LauncherWidgetHolder mAppWidgetHolder; protected final LayoutParserCallback mCallback; protected final PackageManager mPackageManager; @@ -174,17 +173,17 @@ public class AutoInstallsLayout { protected SQLiteDatabase mDb; - public AutoInstallsLayout(Context context, AppWidgetHost appWidgetHost, + public AutoInstallsLayout(Context context, LauncherWidgetHolder appWidgetHolder, LayoutParserCallback callback, Resources res, int layoutId, String rootTag) { - this(context, appWidgetHost, callback, res, () -> res.getXml(layoutId), rootTag); + this(context, appWidgetHolder, callback, res, () -> res.getXml(layoutId), rootTag); } - public AutoInstallsLayout(Context context, AppWidgetHost appWidgetHost, + public AutoInstallsLayout(Context context, LauncherWidgetHolder appWidgetHolder, LayoutParserCallback callback, Resources res, Supplier initialLayoutSupplier, String rootTag) { mContext = context; - mAppWidgetHost = appWidgetHost; + mAppWidgetHolder = appWidgetHolder; mCallback = callback; mPackageManager = context.getPackageManager(); diff --git a/src/com/android/launcher3/DefaultLayoutParser.java b/src/com/android/launcher3/DefaultLayoutParser.java index 4daca8b109..d8558f0ca6 100644 --- a/src/com/android/launcher3/DefaultLayoutParser.java +++ b/src/com/android/launcher3/DefaultLayoutParser.java @@ -1,6 +1,5 @@ package com.android.launcher3; -import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetManager; import android.content.ComponentName; import android.content.Context; @@ -55,9 +54,9 @@ public class DefaultLayoutParser extends AutoInstallsLayout { private static final String ACTION_APPWIDGET_DEFAULT_WORKSPACE_CONFIGURE = "com.android.launcher.action.APPWIDGET_DEFAULT_WORKSPACE_CONFIGURE"; - public DefaultLayoutParser(Context context, AppWidgetHost appWidgetHost, + public DefaultLayoutParser(Context context, LauncherWidgetHolder appWidgetHolder, LayoutParserCallback callback, Resources sourceRes, int layoutId) { - super(context, appWidgetHost, callback, sourceRes, layoutId, TAG_FAVORITES); + super(context, appWidgetHolder, callback, sourceRes, layoutId, TAG_FAVORITES); } @Override @@ -336,11 +335,11 @@ public class DefaultLayoutParser extends AutoInstallsLayout { final AppWidgetManager appWidgetManager = AppWidgetManager.getInstance(mContext); int insertedId = -1; try { - int appWidgetId = mAppWidgetHost.allocateAppWidgetId(); + int appWidgetId = mAppWidgetHolder.allocateAppWidgetId(); if (!appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId, cn)) { Log.e(TAG, "Unable to bind app widget id " + cn); - mAppWidgetHost.deleteAppWidgetId(appWidgetId); + mAppWidgetHolder.deleteAppWidgetId(appWidgetId); return -1; } @@ -349,7 +348,7 @@ public class DefaultLayoutParser extends AutoInstallsLayout { mValues.put(Favorites._ID, mCallback.generateNewItemId()); insertedId = mCallback.insertAndCheck(mDb, mValues); if (insertedId < 0) { - mAppWidgetHost.deleteAppWidgetId(appWidgetId); + mAppWidgetHolder.deleteAppWidgetId(appWidgetId); return insertedId; } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index ab7f6226c9..de2ef554ad 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -1720,6 +1720,7 @@ public class Launcher extends StatefulActivity } catch (NullPointerException ex) { Log.w(TAG, "problem while stopping AppWidgetHost during Launcher destruction", ex); } + mAppWidgetHolder.destroy(); TextKeyListener.getInstance().release(); clearPendingBinds(); diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java index 58e85fea7e..a6731a5d77 100644 --- a/src/com/android/launcher3/LauncherProvider.java +++ b/src/com/android/launcher3/LauncherProvider.java @@ -22,7 +22,6 @@ import static com.android.launcher3.provider.LauncherDbUtils.tableExists; import android.annotation.TargetApi; import android.app.backup.BackupManager; -import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetManager; import android.content.ComponentName; import android.content.ContentProvider; @@ -55,6 +54,8 @@ import android.text.TextUtils; import android.util.Log; import android.util.Xml; +import androidx.annotation.NonNull; + import com.android.launcher3.AutoInstallsLayout.LayoutParserCallback; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.config.FeatureFlags; @@ -70,7 +71,6 @@ import com.android.launcher3.util.IntSet; import com.android.launcher3.util.NoLocaleSQLiteHelper; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.Thunk; -import com.android.launcher3.widget.LauncherAppWidgetHost; import org.xmlpull.v1.XmlPullParser; @@ -255,17 +255,20 @@ public class LauncherProvider extends ContentProvider { values.getAsString(Favorites.APPWIDGET_PROVIDER)); if (cn != null) { + LauncherWidgetHolder widgetHolder = mOpenHelper.newLauncherWidgetHolder(); try { - AppWidgetHost widgetHost = mOpenHelper.newLauncherWidgetHost(); - int appWidgetId = widgetHost.allocateAppWidgetId(); + int appWidgetId = widgetHolder.allocateAppWidgetId(); values.put(LauncherSettings.Favorites.APPWIDGET_ID, appWidgetId); if (!appWidgetManager.bindAppWidgetIdIfAllowed(appWidgetId,cn)) { - widgetHost.deleteAppWidgetId(appWidgetId); + widgetHolder.deleteAppWidgetId(appWidgetId); return false; } } catch (RuntimeException e) { Log.e(TAG, "Failed to initialize external widget", e); return false; + } finally { + // Necessary to destroy the holder to free up possible activity context + widgetHolder.destroy(); } } else { return false; @@ -533,10 +536,10 @@ public class LauncherProvider extends ContentProvider { if (sp.getBoolean(mOpenHelper.getKey(EMPTY_DATABASE_CREATED), false)) { Log.d(TAG, "loading default workspace"); - AppWidgetHost widgetHost = mOpenHelper.newLauncherWidgetHost(); - AutoInstallsLayout loader = createWorkspaceLoaderFromAppRestriction(widgetHost); + LauncherWidgetHolder widgetHolder = mOpenHelper.newLauncherWidgetHolder(); + AutoInstallsLayout loader = createWorkspaceLoaderFromAppRestriction(widgetHolder); if (loader == null) { - loader = AutoInstallsLayout.get(getContext(),widgetHost, mOpenHelper); + loader = AutoInstallsLayout.get(getContext(), widgetHolder, mOpenHelper); } if (loader == null) { final Partner partner = Partner.get(getContext().getPackageManager()); @@ -545,7 +548,7 @@ public class LauncherProvider extends ContentProvider { int workspaceResId = partnerRes.getIdentifier(Partner.RES_DEFAULT_LAYOUT, "xml", partner.getPackageName()); if (workspaceResId != 0) { - loader = new DefaultLayoutParser(getContext(), widgetHost, + loader = new DefaultLayoutParser(getContext(), widgetHolder, mOpenHelper, partnerRes, workspaceResId); } } @@ -553,7 +556,7 @@ public class LauncherProvider extends ContentProvider { final boolean usingExternallyProvidedLayout = loader != null; if (loader == null) { - loader = getDefaultLayoutParser(widgetHost); + loader = getDefaultLayoutParser(widgetHolder); } // There might be some partially restored DB items, due to buggy restore logic in @@ -565,9 +568,10 @@ public class LauncherProvider extends ContentProvider { // Unable to load external layout. Cleanup and load the internal layout. mOpenHelper.createEmptyDB(mOpenHelper.getWritableDatabase()); mOpenHelper.loadFavorites(mOpenHelper.getWritableDatabase(), - getDefaultLayoutParser(widgetHost)); + getDefaultLayoutParser(widgetHolder)); } clearFlagEmptyDbCreated(); + widgetHolder.destroy(); } } @@ -576,7 +580,8 @@ public class LauncherProvider extends ContentProvider { * * @return the loader if the restrictions are set and the resource exists; null otherwise. */ - private AutoInstallsLayout createWorkspaceLoaderFromAppRestriction(AppWidgetHost widgetHost) { + private AutoInstallsLayout createWorkspaceLoaderFromAppRestriction( + LauncherWidgetHolder widgetHolder) { Context ctx = getContext(); final String authority; if (!TextUtils.isEmpty(mProviderAuthority)) { @@ -602,7 +607,7 @@ public class LauncherProvider extends ContentProvider { parser.setInput(new StringReader(layout)); Log.d(TAG, "Loading layout from " + authority); - return new AutoInstallsLayout(ctx, widgetHost, mOpenHelper, + return new AutoInstallsLayout(ctx, widgetHolder, mOpenHelper, ctx.getPackageManager().getResourcesForApplication(pi.applicationInfo), () -> parser, AutoInstallsLayout.TAG_WORKSPACE); } catch (Exception e) { @@ -621,7 +626,7 @@ public class LauncherProvider extends ContentProvider { .build(); } - private DefaultLayoutParser getDefaultLayoutParser(AppWidgetHost widgetHost) { + private DefaultLayoutParser getDefaultLayoutParser(LauncherWidgetHolder widgetHolder) { InvariantDeviceProfile idp = LauncherAppState.getIDP(getContext()); int defaultLayout = mUseTestWorkspaceLayout ? TEST_WORKSPACE_LAYOUT_RES_XML : idp.defaultLayoutId; @@ -631,7 +636,7 @@ public class LauncherProvider extends ContentProvider { defaultLayout = idp.demoModeLayoutId; } - return new DefaultLayoutParser(getContext(), widgetHost, + return new DefaultLayoutParser(getContext(), widgetHolder, mOpenHelper, getContext().getResources(), defaultLayout); } @@ -932,40 +937,46 @@ public class LauncherProvider extends ContentProvider { */ public void removeGhostWidgets(SQLiteDatabase db) { // Get all existing widget ids. - final AppWidgetHost host = newLauncherWidgetHost(); - final int[] allWidgets; + final LauncherWidgetHolder holder = newLauncherWidgetHolder(); try { - // Although the method was defined in O, it has existed since the beginning of time, - // so it might work on older platforms as well. - allWidgets = host.getAppWidgetIds(); - } catch (IncompatibleClassChangeError e) { - Log.e(TAG, "getAppWidgetIds not supported", e); - return; - } - final IntSet validWidgets = IntSet.wrap(LauncherDbUtils.queryIntArray(false, db, - Favorites.TABLE_NAME, Favorites.APPWIDGET_ID, - "itemType=" + Favorites.ITEM_TYPE_APPWIDGET, null, null)); - boolean isAnyWidgetRemoved = false; - for (int widgetId : allWidgets) { - if (!validWidgets.contains(widgetId)) { - try { - FileLog.d(TAG, "Deleting invalid widget " + widgetId); - host.deleteAppWidgetId(widgetId); - isAnyWidgetRemoved = true; - } catch (RuntimeException e) { - // Ignore + final int[] allWidgets; + try { + // Although the method was defined in O, it has existed since the beginning of + // time, so it might work on older platforms as well. + allWidgets = holder.getAppWidgetIds(); + } catch (IncompatibleClassChangeError e) { + Log.e(TAG, "getAppWidgetIds not supported", e); + // Necessary to destroy the holder to free up possible activity context + holder.destroy(); + return; + } + final IntSet validWidgets = IntSet.wrap(LauncherDbUtils.queryIntArray(false, db, + Favorites.TABLE_NAME, Favorites.APPWIDGET_ID, + "itemType=" + Favorites.ITEM_TYPE_APPWIDGET, null, null)); + boolean isAnyWidgetRemoved = false; + for (int widgetId : allWidgets) { + if (!validWidgets.contains(widgetId)) { + try { + FileLog.d(TAG, "Deleting invalid widget " + widgetId); + holder.deleteAppWidgetId(widgetId); + isAnyWidgetRemoved = true; + } catch (RuntimeException e) { + // Ignore + } } } - } - if (isAnyWidgetRemoved) { - final String allWidgetsIds = Arrays.stream(allWidgets).mapToObj(String::valueOf) - .collect(Collectors.joining(",", "[", "]")); - final String validWidgetsIds = Arrays.stream( - validWidgets.getArray().toArray()).mapToObj(String::valueOf) - .collect(Collectors.joining(",", "[", "]")); - FileLog.d(TAG, "One or more widgets was removed. db_path=" + db.getPath() - + " allWidgetsIds=" + allWidgetsIds - + ", validWidgetsIds=" + validWidgetsIds); + if (isAnyWidgetRemoved) { + final String allWidgetsIds = Arrays.stream(allWidgets).mapToObj(String::valueOf) + .collect(Collectors.joining(",", "[", "]")); + final String validWidgetsIds = Arrays.stream( + validWidgets.getArray().toArray()).mapToObj(String::valueOf) + .collect(Collectors.joining(",", "[", "]")); + FileLog.d(TAG, "One or more widgets was removed. db_path=" + db.getPath() + + " allWidgetsIds=" + allWidgetsIds + + ", validWidgetsIds=" + validWidgetsIds); + } + } finally { + holder.destroy(); } } @@ -1066,8 +1077,12 @@ public class LauncherProvider extends ContentProvider { return mMaxItemId; } - public AppWidgetHost newLauncherWidgetHost() { - return new LauncherAppWidgetHost(mContext); + /** + * @return A new {@link LauncherWidgetHolder} based on the current context + */ + @NonNull + public LauncherWidgetHolder newLauncherWidgetHolder() { + return new LauncherWidgetHolder(mContext); } @Override diff --git a/src/com/android/launcher3/LauncherWidgetHolder.java b/src/com/android/launcher3/LauncherWidgetHolder.java index 5fcd46fe4d..2612b9cb63 100644 --- a/src/com/android/launcher3/LauncherWidgetHolder.java +++ b/src/com/android/launcher3/LauncherWidgetHolder.java @@ -15,17 +15,39 @@ */ package com.android.launcher3; +import static android.app.Activity.RESULT_CANCELED; + +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; + +import android.app.PendingIntent; +import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetHostView; +import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; +import android.content.ActivityNotFoundException; import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.util.SparseArray; +import android.view.View; +import android.widget.RemoteViews; +import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.launcher3.config.FeatureFlags; +import com.android.launcher3.model.WidgetsModel; +import com.android.launcher3.model.data.ItemInfo; +import com.android.launcher3.testing.TestLogging; +import com.android.launcher3.testing.shared.TestProtocol; import com.android.launcher3.uioverrides.ApiWrapper; +import com.android.launcher3.widget.DeferredAppWidgetHostView; import com.android.launcher3.widget.LauncherAppWidgetHost; +import com.android.launcher3.widget.LauncherAppWidgetHostView; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; import com.android.launcher3.widget.PendingAppWidgetHostView; +import com.android.launcher3.widget.custom.CustomWidgetManager; import java.util.function.IntConsumer; @@ -34,8 +56,36 @@ import java.util.function.IntConsumer; * background. */ public class LauncherWidgetHolder { + public static final int APPWIDGET_HOST_ID = 1024; + + private static final int FLAG_LISTENING = 1; + private static final int FLAG_STATE_IS_NORMAL = 1 << 1; + private static final int FLAG_ACTIVITY_STARTED = 1 << 2; + private static final int FLAG_ACTIVITY_RESUMED = 1 << 3; + private static final int FLAGS_SHOULD_LISTEN = + FLAG_STATE_IS_NORMAL | FLAG_ACTIVITY_STARTED | FLAG_ACTIVITY_RESUMED; + @NonNull - private final LauncherAppWidgetHost mWidgetHost; + private final Context mContext; + + @NonNull + private final AppWidgetHost mWidgetHost; + + @NonNull + private final SparseArray mViews = new SparseArray<>(); + @NonNull + private final SparseArray mPendingViews = new SparseArray<>(); + @NonNull + private final SparseArray mDeferredViews = new SparseArray<>(); + @NonNull + private final SparseArray mCachedRemoteViews = new SparseArray<>(); + + private int mFlags = FLAG_STATE_IS_NORMAL; + + // TODO(b/191735836): Replace with ActivityOptions.KEY_SPLASH_SCREEN_STYLE when un-hidden + private static final String KEY_SPLASH_SCREEN_STYLE = "android.activity.splashScreenStyle"; + // TODO(b/191735836): Replace with SplashScreen.SPLASH_SCREEN_STYLE_EMPTY when un-hidden + private static final int SPLASH_SCREEN_STYLE_EMPTY = 0; public LauncherWidgetHolder(@NonNull Context context) { this(context, null); @@ -43,30 +93,70 @@ public class LauncherWidgetHolder { public LauncherWidgetHolder(@NonNull Context context, @Nullable IntConsumer appWidgetRemovedCallback) { - mWidgetHost = new LauncherAppWidgetHost(context, appWidgetRemovedCallback); + mContext = context; + mWidgetHost = createHost(context, appWidgetRemovedCallback); + } + + protected AppWidgetHost createHost( + Context context, @Nullable IntConsumer appWidgetRemovedCallback) { + return new LauncherAppWidgetHost(context, appWidgetRemovedCallback, this); } /** * Starts listening to the widget updates from the server side */ public void startListening() { - mWidgetHost.startListening(); + if (WidgetsModel.GO_DISABLE_WIDGETS) { + return; + } + setListeningFlag(true); + try { + mWidgetHost.startListening(); + } catch (Exception e) { + if (!Utilities.isBinderSizeError(e)) { + throw new RuntimeException(e); + } + // We're willing to let this slide. The exception is being caused by the list of + // RemoteViews which is being passed back. The startListening relationship will + // have been established by this point, and we will end up populating the + // widgets upon bind anyway. See issue 14255011 for more context. + } + + // We go in reverse order and inflate any deferred or cached widget + for (int i = mViews.size() - 1; i >= 0; i--) { + LauncherAppWidgetHostView view = mViews.valueAt(i); + if (view instanceof DeferredAppWidgetHostView) { + view.reInflate(); + } + if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) { + final int appWidgetId = mViews.keyAt(i); + if (view == mDeferredViews.get(appWidgetId)) { + // If the widget view was deferred, we'll need to call super.createView here + // to make the binder call to system process to fetch cumulative updates to this + // widget, as well as setting up this view for future updates. + mWidgetHost.createView(view.getLauncher(), appWidgetId, + view.getAppWidgetInfo()); + // At this point #onCreateView should have been called, which in turn returned + // the deferred view. There's no reason to keep the reference anymore, so we + // removed it here. + mDeferredViews.remove(appWidgetId); + } + } + } } /** - * Set the STARTED state of the widget host - * @param isStarted True if setting the host as started, false otherwise + * Registers an "activity started/stopped" event. */ public void setActivityStarted(boolean isStarted) { - mWidgetHost.setActivityStarted(isStarted); + setShouldListenFlag(FLAG_ACTIVITY_STARTED, isStarted); } /** - * Set the RESUMED state of the widget host - * @param isResumed True if setting the host as resumed, false otherwise + * Registers an "activity paused/resumed" event. */ public void setActivityResumed(boolean isResumed) { - mWidgetHost.setActivityResumed(isResumed); + setShouldListenFlag(FLAG_ACTIVITY_RESUMED, isResumed); } /** @@ -74,7 +164,7 @@ public class LauncherWidgetHolder { * @param isNormal True if setting the host to be in normal state, false otherwise */ public void setStateIsNormal(boolean isNormal) { - mWidgetHost.setStateIsNormal(isNormal); + setShouldListenFlag(FLAG_STATE_IS_NORMAL, isNormal); } /** @@ -83,6 +173,7 @@ public class LauncherWidgetHolder { */ public void deleteAppWidgetId(int appWidgetId) { mWidgetHost.deleteAppWidgetId(appWidgetId); + mViews.remove(appWidgetId); } /** @@ -91,20 +182,37 @@ public class LauncherWidgetHolder { * @param view The {@link PendingAppWidgetHostView} of the app widget */ public void addPendingView(int appWidgetId, @NonNull PendingAppWidgetHostView view) { - mWidgetHost.addPendingView(appWidgetId, view); + mPendingViews.put(appWidgetId, view); } /** - * @return True if the host is listening to the widget updates, false otherwise + * @param appWidgetId The app widget id of the specified widget + * @return The {@link PendingAppWidgetHostView} of the widget if it exists, null otherwise */ - public boolean isListening() { - return mWidgetHost.isListening(); + @Nullable + protected PendingAppWidgetHostView getPendingView(int appWidgetId) { + return mPendingViews.get(appWidgetId); + } + + protected void removePendingView(int appWidgetId) { + mPendingViews.remove(appWidgetId); + } + + /** + * Called when the launcher is destroyed + */ + public void destroy() { + // No-op } /** * @return The allocated app widget id if allocation is successful, returns -1 otherwise */ public int allocateAppWidgetId() { + if (WidgetsModel.GO_DISABLE_WIDGETS) { + return AppWidgetManager.INVALID_APPWIDGET_ID; + } + return mWidgetHost.allocateAppWidgetId(); } @@ -112,18 +220,18 @@ public class LauncherWidgetHolder { * Add a listener that is triggered when the providers of the widgets are changed * @param listener The listener that notifies when the providers changed */ - public void addProviderChangeListener( - @NonNull LauncherAppWidgetHost.ProviderChangedListener listener) { - mWidgetHost.addProviderChangeListener(listener); + public void addProviderChangeListener(@NonNull ProviderChangedListener listener) { + LauncherAppWidgetHost tempHost = (LauncherAppWidgetHost) mWidgetHost; + tempHost.addProviderChangeListener(listener); } /** * Remove the specified listener from the host * @param listener The listener that is to be removed from the host */ - public void removeProviderChangeListener( - LauncherAppWidgetHost.ProviderChangedListener listener) { - mWidgetHost.removeProviderChangeListener(listener); + public void removeProviderChangeListener(ProviderChangedListener listener) { + LauncherAppWidgetHost tempHost = (LauncherAppWidgetHost) mWidgetHost; + tempHost.removeProviderChangeListener(listener); } /** @@ -134,7 +242,40 @@ public class LauncherWidgetHolder { */ public void startConfigActivity(@NonNull BaseDraggingActivity activity, int widgetId, int requestCode) { - mWidgetHost.startConfigActivity(activity, widgetId, requestCode); + if (WidgetsModel.GO_DISABLE_WIDGETS) { + sendActionCancelled(activity, requestCode); + return; + } + + try { + TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "start: startConfigActivity"); + mWidgetHost.startAppWidgetConfigureActivityForResult(activity, widgetId, 0, requestCode, + getConfigurationActivityOptions(activity, widgetId)); + } catch (ActivityNotFoundException | SecurityException e) { + Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); + sendActionCancelled(activity, requestCode); + } + } + + private void sendActionCancelled(final BaseActivity activity, final int requestCode) { + MAIN_EXECUTOR.execute( + () -> activity.onActivityResult(requestCode, RESULT_CANCELED, null)); + } + + /** + * Returns an {@link android.app.ActivityOptions} bundle from the {code activity} for launching + * the configuration of the {@code widgetId} app widget, or null of options cannot be produced. + */ + @Nullable + protected Bundle getConfigurationActivityOptions(@NonNull BaseDraggingActivity activity, + int widgetId) { + LauncherAppWidgetHostView view = mViews.get(widgetId); + if (view == null) return null; + Object tag = view.getTag(); + if (!(tag instanceof ItemInfo)) return null; + Bundle bundle = activity.getActivityLaunchOptions(view, (ItemInfo) tag).toBundle(); + bundle.putInt(KEY_SPLASH_SCREEN_STYLE, SPLASH_SCREEN_STYLE_EMPTY); + return bundle; } /** @@ -146,27 +287,38 @@ public class LauncherWidgetHolder { */ public void startBindFlow(@NonNull BaseActivity activity, int appWidgetId, @NonNull AppWidgetProviderInfo info, int requestCode) { - mWidgetHost.startBindFlow(activity, appWidgetId, info, requestCode); + if (WidgetsModel.GO_DISABLE_WIDGETS) { + sendActionCancelled(activity, requestCode); + return; + } + + Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND) + .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) + .putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.provider) + .putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE, info.getProfile()); + // TODO: we need to make sure that this accounts for the options bundle. + // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options); + activity.startActivityForResult(intent, requestCode); } /** * Stop the host from listening to the widget updates */ public void stopListening() { + if (WidgetsModel.GO_DISABLE_WIDGETS) { + return; + } + mWidgetHost.stopListening(); + setListeningFlag(false); } - /** - * Create a view for the specified app widget - * @param context The activity context for which the view is created - * @param appWidgetId The ID of the widget - * @param info The {@link LauncherAppWidgetProviderInfo} of the widget - * @return A view for the widget - */ - @NonNull - public AppWidgetHostView createView(@NonNull Context context, int appWidgetId, - @NonNull LauncherAppWidgetProviderInfo info) { - return mWidgetHost.createView(context, appWidgetId, info); + protected void setListeningFlag(final boolean isListening) { + if (isListening) { + mFlags |= FLAG_LISTENING; + return; + } + mFlags &= ~FLAG_LISTENING; } /** @@ -174,14 +326,184 @@ public class LauncherWidgetHolder { * @param handler The interaction handler */ public void setInteractionHandler( - @Nullable LauncherAppWidgetHost.LauncherWidgetInteractionHandler handler) { + @Nullable LauncherWidgetInteractionHandler handler) { ApiWrapper.setHostInteractionHandler(mWidgetHost, handler); } + /** + * Delete the host + */ + public void deleteHost() { + mWidgetHost.deleteHost(); + } + + /** + * @return The app widget ids + */ + @NonNull + public int[] getAppWidgetIds() { + return mWidgetHost.getAppWidgetIds(); + } + + /** + * Create a view for the specified app widget + * @param context The activity context for which the view is created + * @param appWidgetId The ID of the widget + * @param appWidget The {@link LauncherAppWidgetProviderInfo} of the widget + * @return A view for the widget + */ + @NonNull + public AppWidgetHostView createView(@NonNull Context context, int appWidgetId, + @NonNull LauncherAppWidgetProviderInfo appWidget) { + if (appWidget.isCustomWidget()) { + LauncherAppWidgetHostView lahv = new LauncherAppWidgetHostView(context); + lahv.setAppWidget(0, appWidget); + CustomWidgetManager.INSTANCE.get(context).onViewCreated(lahv); + return lahv; + } else if ((mFlags & FLAG_LISTENING) == 0) { + // Since the launcher hasn't started listening to widget updates, we can't simply call + // super.createView here because the later will make a binder call to retrieve + // RemoteViews from system process. + // TODO: have launcher always listens to widget updates in background so that this + // check can be removed altogether. + if (FeatureFlags.ENABLE_CACHED_WIDGET.get() + && mCachedRemoteViews.get(appWidgetId) != null) { + // We've found RemoteViews from cache for this widget, so we will instantiate a + // widget host view and populate it with the cached RemoteViews. + final LauncherAppWidgetHostView view = new LauncherAppWidgetHostView(context); + view.setAppWidget(appWidgetId, appWidget); + view.updateAppWidget(mCachedRemoteViews.get(appWidgetId)); + mDeferredViews.put(appWidgetId, view); + mViews.put(appWidgetId, view); + return view; + } else { + // When cache misses, a placeholder for the widget will be returned instead. + DeferredAppWidgetHostView view = new DeferredAppWidgetHostView(context); + view.setAppWidget(appWidgetId, appWidget); + mViews.put(appWidgetId, view); + return view; + } + } else { + try { + return mWidgetHost.createView(context, appWidgetId, appWidget); + } catch (Exception e) { + if (!Utilities.isBinderSizeError(e)) { + throw new RuntimeException(e); + } + + // If the exception was thrown while fetching the remote views, let the view stay. + // This will ensure that if the widget posts a valid update later, the view + // will update. + LauncherAppWidgetHostView view = mViews.get(appWidgetId); + if (view == null) { + view = onCreateView(mContext, appWidgetId, appWidget); + } + view.setAppWidget(appWidgetId, appWidget); + view.switchToErrorView(); + return view; + } + } + } + + /** + * Listener for getting notifications on provider changes. + */ + public interface ProviderChangedListener { + /** + * Notify the listener that the providers have changed + */ + void notifyWidgetProvidersChanged(); + } + + /** + * Called to return a proper view when creating a view + * @param context The context for which the widget view is created + * @param appWidgetId The ID of the added widget + * @param appWidget The provider info of the added widget + * @return A view for the specified app widget + */ + @NonNull + public LauncherAppWidgetHostView onCreateView(Context context, int appWidgetId, + AppWidgetProviderInfo appWidget) { + final LauncherAppWidgetHostView view; + if (getPendingView(appWidgetId) != null) { + view = getPendingView(appWidgetId); + removePendingView(appWidgetId); + } else if (mDeferredViews.get(appWidgetId) != null) { + // In case the widget view is deferred, we will simply return the deferred view as + // opposed to instantiate a new instance of LauncherAppWidgetHostView since launcher + // already added the former to the workspace. + view = mDeferredViews.get(appWidgetId); + } else { + view = new LauncherAppWidgetHostView(context); + } + mViews.put(appWidgetId, view); + return view; + } + /** * Clears all the views from the host */ public void clearViews() { - mWidgetHost.clearViews(); + LauncherAppWidgetHost tempHost = (LauncherAppWidgetHost) mWidgetHost; + tempHost.clearViews(); + if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) { + // First, we clear any previously cached content from existing widgets + mCachedRemoteViews.clear(); + mDeferredViews.clear(); + // Then we proceed to cache the content from the widgets + for (int i = 0; i < mViews.size(); i++) { + final int appWidgetId = mViews.keyAt(i); + final LauncherAppWidgetHostView view = mViews.get(appWidgetId); + mCachedRemoteViews.put(appWidgetId, view.getLastRemoteViews()); + } + } + mViews.clear(); + } + + /** + * @return True if the host is listening to the updates, false otherwise + */ + public boolean isListening() { + return (mFlags & FLAG_LISTENING) != 0; + } + + /** + * Sets or unsets a flag the can change whether the widget host should be in the listening + * state. + */ + private void setShouldListenFlag(int flag, boolean on) { + if (on) { + mFlags |= flag; + } else { + mFlags &= ~flag; + } + + final boolean listening = isListening(); + if (!listening && (mFlags & FLAGS_SHOULD_LISTEN) == FLAGS_SHOULD_LISTEN) { + // Postpone starting listening until all flags are on. + startListening(); + } else if (listening && (mFlags & FLAG_ACTIVITY_STARTED) == 0) { + // Postpone stopping listening until the activity is stopped. + stopListening(); + } + } + + /** + * Set as a substitution for the hidden interaction handler in RemoteViews + */ + public interface LauncherWidgetInteractionHandler { + /** + * Invoked when the user performs an interaction on the View. + * + * @param view the View with which the user interacted + * @param pendingIntent the base PendingIntent associated with the view + * @param response the response to the interaction, which knows how to fill in the + * attached PendingIntent + */ + boolean onInteraction( + View view, + PendingIntent pendingIntent, + RemoteViews.RemoteResponse response); } } diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 27e1ba143b..39679a994a 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -63,6 +63,7 @@ import android.widget.Toast; import androidx.annotation.Nullable; +import com.android.launcher3.LauncherWidgetHolder.ProviderChangedListener; import com.android.launcher3.accessibility.AccessibleDragListenerAdapter; import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper; import com.android.launcher3.anim.Interpolators; @@ -107,7 +108,6 @@ import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.RunnableList; import com.android.launcher3.util.Thunk; import com.android.launcher3.util.WallpaperOffsetInterpolator; -import com.android.launcher3.widget.LauncherAppWidgetHost.ProviderChangedListener; import com.android.launcher3.widget.LauncherAppWidgetHostView; import com.android.launcher3.widget.NavigableAppWidgetHostView; import com.android.launcher3.widget.PendingAddShortcutInfo; diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java index 05b1984887..4fb5ff6638 100644 --- a/src/com/android/launcher3/dragndrop/AddItemActivity.java +++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java @@ -53,10 +53,13 @@ import android.view.accessibility.AccessibilityEvent; import android.view.accessibility.AccessibilityManager; import android.widget.TextView; +import androidx.annotation.Nullable; + import com.android.launcher3.BaseActivity; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherWidgetHolder; import com.android.launcher3.R; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.model.ItemInstallQueue; @@ -69,7 +72,6 @@ import com.android.launcher3.util.SystemUiController; import com.android.launcher3.views.AbstractSlideInView; import com.android.launcher3.views.BaseDragLayer; import com.android.launcher3.widget.AddItemWidgetsBottomSheet; -import com.android.launcher3.widget.LauncherAppWidgetHost; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; import com.android.launcher3.widget.NavigableAppWidgetHostView; import com.android.launcher3.widget.PendingAddShortcutInfo; @@ -105,7 +107,8 @@ public class AddItemActivity extends BaseActivity private WidgetCell mWidgetCell; // Widget request specific options. - private LauncherAppWidgetHost mAppWidgetHost; + @Nullable + private LauncherWidgetHolder mAppWidgetHolder = null; private WidgetManagerHelper mAppWidgetManager; private int mPendingBindWidgetId; private Bundle mWidgetOptions; @@ -284,7 +287,7 @@ public class AddItemActivity extends BaseActivity mWidgetCell.setRemoteViewsPreview(PinItemDragListener.getPreview(mRequest)); mAppWidgetManager = new WidgetManagerHelper(this); - mAppWidgetHost = new LauncherAppWidgetHost(this); + mAppWidgetHolder = new LauncherWidgetHolder(this); PendingAddWidgetInfo pendingInfo = new PendingAddWidgetInfo(widgetInfo, CONTAINER_PIN_WIDGETS); @@ -338,7 +341,7 @@ public class AddItemActivity extends BaseActivity return; } - mPendingBindWidgetId = mAppWidgetHost.allocateAppWidgetId(); + mPendingBindWidgetId = mAppWidgetHolder.allocateAppWidgetId(); AppWidgetProviderInfo widgetProviderInfo = mRequest.getAppWidgetProviderInfo(this); boolean success = mAppWidgetManager.bindAppWidgetIdIfAllowed( mPendingBindWidgetId, widgetProviderInfo, mWidgetOptions); @@ -349,7 +352,7 @@ public class AddItemActivity extends BaseActivity } // request bind widget - mAppWidgetHost.startBindFlow(this, mPendingBindWidgetId, + mAppWidgetHolder.startBindFlow(this, mPendingBindWidgetId, mRequest.getAppWidgetProviderInfo(this), REQUEST_BIND_APPWIDGET); } @@ -362,6 +365,15 @@ public class AddItemActivity extends BaseActivity mSlideInView.close(/* animate= */ true); } + @Override + public void onDestroy() { + super.onDestroy(); + if (mAppWidgetHolder != null) { + // Necessary to destroy the holder to free up possible activity context + mAppWidgetHolder.destroy(); + } + } + @Override public void onBackPressed() { logCommand(LAUNCHER_ADD_EXTERNAL_ITEM_BACK); @@ -378,7 +390,7 @@ public class AddItemActivity extends BaseActivity acceptWidget(widgetId); } else { // Simply wait it out. - mAppWidgetHost.deleteAppWidgetId(widgetId); + mAppWidgetHolder.deleteAppWidgetId(widgetId); mPendingBindWidgetId = -1; } return; diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index 482e923403..0646e7f802 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -68,6 +68,7 @@ import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings.Favorites; +import com.android.launcher3.LauncherWidgetHolder; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; @@ -99,7 +100,6 @@ import com.android.launcher3.util.window.WindowManagerProxy; import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.BaseDragLayer; import com.android.launcher3.widget.BaseLauncherAppWidgetHostView; -import com.android.launcher3.widget.LauncherAppWidgetHost; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; import com.android.launcher3.widget.LocalColorExtractor; import com.android.launcher3.widget.NavigableAppWidgetHostView; @@ -554,7 +554,7 @@ public class LauncherPreviewRenderer extends ContextWrapper private class LauncherPreviewAppWidgetHost extends AppWidgetHost { private LauncherPreviewAppWidgetHost(Context context) { - super(context, LauncherAppWidgetHost.APPWIDGET_HOST_ID); + super(context, LauncherWidgetHolder.APPWIDGET_HOST_ID); } @Override diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java index 48b3acfbf1..70dd98eef6 100644 --- a/src/com/android/launcher3/provider/RestoreDbTask.java +++ b/src/com/android/launcher3/provider/RestoreDbTask.java @@ -38,6 +38,7 @@ import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherProvider.DatabaseHelper; import com.android.launcher3.LauncherSettings.Favorites; +import com.android.launcher3.LauncherWidgetHolder; import com.android.launcher3.Utilities; import com.android.launcher3.logging.FileLog; import com.android.launcher3.model.DeviceGridState; @@ -353,9 +354,12 @@ public class RestoreDbTask { private void restoreAppWidgetIdsIfExists(Context context) { SharedPreferences prefs = Utilities.getPrefs(context); if (prefs.contains(APPWIDGET_OLD_IDS) && prefs.contains(APPWIDGET_IDS)) { + LauncherWidgetHolder holder = new LauncherWidgetHolder(context); AppWidgetsRestoredReceiver.restoreAppWidgetIds(context, IntArray.fromConcatString(prefs.getString(APPWIDGET_OLD_IDS, "")).toArray(), - IntArray.fromConcatString(prefs.getString(APPWIDGET_IDS, "")).toArray()); + IntArray.fromConcatString(prefs.getString(APPWIDGET_IDS, "")).toArray(), + holder); + holder.destroy(); } else { FileLog.d(TAG, "No app widget ids to restore."); } diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHost.java b/src/com/android/launcher3/widget/LauncherAppWidgetHost.java index fff8fbb12a..c57139d72c 100644 --- a/src/com/android/launcher3/widget/LauncherAppWidgetHost.java +++ b/src/com/android/launcher3/widget/LauncherAppWidgetHost.java @@ -16,301 +16,88 @@ package com.android.launcher3.widget; -import static android.app.Activity.RESULT_CANCELED; +import static com.android.launcher3.LauncherWidgetHolder.APPWIDGET_HOST_ID; -import android.app.PendingIntent; import android.appwidget.AppWidgetHost; -import android.appwidget.AppWidgetHostView; -import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; -import android.content.ActivityNotFoundException; import android.content.Context; -import android.content.Intent; -import android.os.Bundle; -import android.os.Handler; -import android.util.SparseArray; -import android.view.View; -import android.widget.RemoteViews; -import android.widget.Toast; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.launcher3.BaseActivity; -import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.LauncherAppState; -import com.android.launcher3.R; -import com.android.launcher3.Utilities; -import com.android.launcher3.config.FeatureFlags; -import com.android.launcher3.model.WidgetsModel; -import com.android.launcher3.model.data.ItemInfo; -import com.android.launcher3.testing.TestLogging; -import com.android.launcher3.testing.shared.TestProtocol; -import com.android.launcher3.widget.custom.CustomWidgetManager; +import com.android.launcher3.LauncherWidgetHolder; import java.util.ArrayList; import java.util.function.IntConsumer; - /** * Specific {@link AppWidgetHost} that creates our {@link LauncherAppWidgetHostView} * which correctly captures all long-press events. This ensures that users can * always pick up and move widgets. */ public class LauncherAppWidgetHost extends AppWidgetHost { + @NonNull + private final ArrayList + mProviderChangeListeners = new ArrayList<>(); - private static final int FLAG_LISTENING = 1; - private static final int FLAG_STATE_IS_NORMAL = 1 << 1; - private static final int FLAG_ACTIVITY_STARTED = 1 << 2; - private static final int FLAG_ACTIVITY_RESUMED = 1 << 3; - private static final int FLAGS_SHOULD_LISTEN = - FLAG_STATE_IS_NORMAL | FLAG_ACTIVITY_STARTED | FLAG_ACTIVITY_RESUMED; - // TODO(b/191735836): Replace with ActivityOptions.KEY_SPLASH_SCREEN_STYLE when un-hidden - private static final String KEY_SPLASH_SCREEN_STYLE = "android.activity.splashScreenStyle"; - // TODO(b/191735836): Replace with SplashScreen.SPLASH_SCREEN_STYLE_EMPTY when un-hidden - private static final int SPLASH_SCREEN_STYLE_EMPTY = 0; - - public static final int APPWIDGET_HOST_ID = 1024; - - private final ArrayList mProviderChangeListeners = new ArrayList<>(); - private final SparseArray mViews = new SparseArray<>(); - private final SparseArray mPendingViews = new SparseArray<>(); - private final SparseArray mDeferredViews = new SparseArray<>(); - private final SparseArray mCachedRemoteViews = new SparseArray<>(); - + @NonNull private final Context mContext; - private int mFlags = FLAG_STATE_IS_NORMAL; - private IntConsumer mAppWidgetRemovedCallback = null; + @Nullable + private final IntConsumer mAppWidgetRemovedCallback; - /** - * This serves for the purpose of getting rid of the hidden API calling of InteractionHandler - */ - public interface LauncherWidgetInteractionHandler { - /** - * Invoked when the user performs an interaction on the View. - * - * @param view the View with which the user interacted - * @param pendingIntent the base PendingIntent associated with the view - * @param response the response to the interaction, which knows how to fill in the - * attached PendingIntent - */ - boolean onInteraction( - View view, - PendingIntent pendingIntent, - RemoteViews.RemoteResponse response); - } + @NonNull + private final LauncherWidgetHolder mHolder; - public LauncherAppWidgetHost(Context context) { - this(context, null); - } - - public LauncherAppWidgetHost(Context context, - IntConsumer appWidgetRemovedCallback) { + public LauncherAppWidgetHost(@NonNull Context context, + @Nullable IntConsumer appWidgetRemovedCallback, @NonNull LauncherWidgetHolder holder) { super(context, APPWIDGET_HOST_ID); mContext = context; mAppWidgetRemovedCallback = appWidgetRemovedCallback; - } - - @Override - protected LauncherAppWidgetHostView onCreateView(Context context, int appWidgetId, - AppWidgetProviderInfo appWidget) { - final LauncherAppWidgetHostView view; - if (mPendingViews.get(appWidgetId) != null) { - view = mPendingViews.get(appWidgetId); - mPendingViews.remove(appWidgetId); - } else if (mDeferredViews.get(appWidgetId) != null) { - // In case the widget view is deferred, we will simply return the deferred view as - // opposed to instantiate a new instance of LauncherAppWidgetHostView since launcher - // already added the former to the workspace. - view = mDeferredViews.get(appWidgetId); - } else { - view = new LauncherAppWidgetHostView(context); - } - mViews.put(appWidgetId, view); - return view; - } - - @Override - public void startListening() { - if (WidgetsModel.GO_DISABLE_WIDGETS) { - return; - } - mFlags |= FLAG_LISTENING; - try { - super.startListening(); - } catch (Exception e) { - if (!Utilities.isBinderSizeError(e)) { - throw new RuntimeException(e); - } - // We're willing to let this slide. The exception is being caused by the list of - // RemoteViews which is being passed back. The startListening relationship will - // have been established by this point, and we will end up populating the - // widgets upon bind anyway. See issue 14255011 for more context. - } - - // We go in reverse order and inflate any deferred or cached widget - for (int i = mViews.size() - 1; i >= 0; i--) { - LauncherAppWidgetHostView view = mViews.valueAt(i); - if (view instanceof DeferredAppWidgetHostView) { - view.reInflate(); - } - if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) { - final int appWidgetId = mViews.keyAt(i); - if (view == mDeferredViews.get(appWidgetId)) { - // If the widget view was deferred, we'll need to call super.createView here - // to make the binder call to system process to fetch cumulative updates to this - // widget, as well as setting up this view for future updates. - super.createView(view.mLauncher, appWidgetId, view.getAppWidgetInfo()); - // At this point #onCreateView should have been called, which in turn returned - // the deferred view. There's no reason to keep the reference anymore, so we - // removed it here. - mDeferredViews.remove(appWidgetId); - } - } - } - } - - @Override - public void stopListening() { - if (WidgetsModel.GO_DISABLE_WIDGETS) { - return; - } - mFlags &= ~FLAG_LISTENING; - super.stopListening(); - } - - public boolean isListening() { - return (mFlags & FLAG_LISTENING) != 0; + mHolder = holder; } /** - * Sets or unsets a flag the can change whether the widget host should be in the listening - * state. + * Add a listener that is triggered when the providers of the widgets are changed + * @param listener The listener that notifies when the providers changed */ - private void setShouldListenFlag(int flag, boolean on) { - if (on) { - mFlags |= flag; - } else { - mFlags &= ~flag; - } - - final boolean listening = isListening(); - if (!listening && (mFlags & FLAGS_SHOULD_LISTEN) == FLAGS_SHOULD_LISTEN) { - // Postpone starting listening until all flags are on. - startListening(); - } else if (listening && (mFlags & FLAG_ACTIVITY_STARTED) == 0) { - // Postpone stopping listening until the activity is stopped. - stopListening(); - } + public void addProviderChangeListener( + @NonNull LauncherWidgetHolder.ProviderChangedListener listener) { + mProviderChangeListeners.add(listener); } /** - * Registers an "entering/leaving Normal state" event. + * Remove the specified listener from the host + * @param listener The listener that is to be removed from the host */ - public void setStateIsNormal(boolean isNormal) { - setShouldListenFlag(FLAG_STATE_IS_NORMAL, isNormal); - } - - /** - * Registers an "activity started/stopped" event. - */ - public void setActivityStarted(boolean isStarted) { - setShouldListenFlag(FLAG_ACTIVITY_STARTED, isStarted); - } - - /** - * Registers an "activity paused/resumed" event. - */ - public void setActivityResumed(boolean isResumed) { - setShouldListenFlag(FLAG_ACTIVITY_RESUMED, isResumed); + public void removeProviderChangeListener( + LauncherWidgetHolder.ProviderChangedListener listener) { + mProviderChangeListeners.remove(listener); } @Override - public int allocateAppWidgetId() { - if (WidgetsModel.GO_DISABLE_WIDGETS) { - return AppWidgetManager.INVALID_APPWIDGET_ID; - } - - return super.allocateAppWidgetId(); - } - - public void addProviderChangeListener(ProviderChangedListener callback) { - mProviderChangeListeners.add(callback); - } - - public void removeProviderChangeListener(ProviderChangedListener callback) { - mProviderChangeListeners.remove(callback); - } - protected void onProvidersChanged() { if (!mProviderChangeListeners.isEmpty()) { - for (ProviderChangedListener callback : new ArrayList<>(mProviderChangeListeners)) { + for (LauncherWidgetHolder.ProviderChangedListener callback : + new ArrayList<>(mProviderChangeListeners)) { callback.notifyWidgetProvidersChanged(); } } } - public void addPendingView(int appWidgetId, PendingAppWidgetHostView view) { - mPendingViews.put(appWidgetId, view); - } - - public AppWidgetHostView createView(Context context, int appWidgetId, - LauncherAppWidgetProviderInfo appWidget) { - if (appWidget.isCustomWidget()) { - LauncherAppWidgetHostView lahv = new LauncherAppWidgetHostView(context); - lahv.setAppWidget(0, appWidget); - CustomWidgetManager.INSTANCE.get(context).onViewCreated(lahv); - return lahv; - } else if ((mFlags & FLAG_LISTENING) == 0) { - // Since the launcher hasn't started listening to widget updates, we can't simply call - // super.createView here because the later will make a binder call to retrieve - // RemoteViews from system process. - // TODO: have launcher always listens to widget updates in background so that this - // check can be removed altogether. - if (FeatureFlags.ENABLE_CACHED_WIDGET.get() - && mCachedRemoteViews.get(appWidgetId) != null) { - // We've found RemoteViews from cache for this widget, so we will instantiate a - // widget host view and populate it with the cached RemoteViews. - final LauncherAppWidgetHostView view = new LauncherAppWidgetHostView(context); - view.setAppWidget(appWidgetId, appWidget); - view.updateAppWidget(mCachedRemoteViews.get(appWidgetId)); - mDeferredViews.put(appWidgetId, view); - mViews.put(appWidgetId, view); - return view; - } else { - // When cache misses, a placeholder for the widget will be returned instead. - DeferredAppWidgetHostView view = new DeferredAppWidgetHostView(context); - view.setAppWidget(appWidgetId, appWidget); - mViews.put(appWidgetId, view); - return view; - } - } else { - try { - return super.createView(context, appWidgetId, appWidget); - } catch (Exception e) { - if (!Utilities.isBinderSizeError(e)) { - throw new RuntimeException(e); - } - - // If the exception was thrown while fetching the remote views, let the view stay. - // This will ensure that if the widget posts a valid update later, the view - // will update. - LauncherAppWidgetHostView view = mViews.get(appWidgetId); - if (view == null) { - view = onCreateView(mContext, appWidgetId, appWidget); - } - view.setAppWidget(appWidgetId, appWidget); - view.switchToErrorView(); - return view; - } - } + @Override + @NonNull + public LauncherAppWidgetHostView onCreateView(Context context, int appWidgetId, + AppWidgetProviderInfo appWidget) { + return mHolder.onCreateView(context, appWidgetId, appWidget); } /** * Called when the AppWidget provider for a AppWidget has been upgraded to a new apk. */ @Override - protected void onProviderChanged(int appWidgetId, AppWidgetProviderInfo appWidget) { + protected void onProviderChanged(int appWidgetId, @NonNull AppWidgetProviderInfo appWidget) { LauncherAppWidgetProviderInfo info = LauncherAppWidgetProviderInfo.fromProviderInfo( mContext, appWidget); super.onProviderChanged(appWidgetId, info); @@ -324,6 +111,7 @@ public class LauncherAppWidgetHost extends AppWidgetHost { * * @param appWidgetId TODO: make this override when SDK is updated */ + @Override public void onAppWidgetRemoved(int appWidgetId) { if (mAppWidgetRemovedCallback == null) { return; @@ -331,92 +119,12 @@ public class LauncherAppWidgetHost extends AppWidgetHost { mAppWidgetRemovedCallback.accept(appWidgetId); } - @Override - public void deleteAppWidgetId(int appWidgetId) { - super.deleteAppWidgetId(appWidgetId); - mViews.remove(appWidgetId); - } - + /** + * The same as super.clearViews(), except with the scope exposed + */ @Override public void clearViews() { super.clearViews(); - if (FeatureFlags.ENABLE_CACHED_WIDGET.get()) { - // First, we clear any previously cached content from existing widgets - mCachedRemoteViews.clear(); - mDeferredViews.clear(); - // Then we proceed to cache the content from the widgets - for (int i = 0; i < mViews.size(); i++) { - final int appWidgetId = mViews.keyAt(i); - final LauncherAppWidgetHostView view = mViews.get(appWidgetId); - mCachedRemoteViews.put(appWidgetId, view.mLastRemoteViews); - } - } - mViews.clear(); } - public void startBindFlow(BaseActivity activity, - int appWidgetId, AppWidgetProviderInfo info, int requestCode) { - - if (WidgetsModel.GO_DISABLE_WIDGETS) { - sendActionCancelled(activity, requestCode); - return; - } - - Intent intent = new Intent(AppWidgetManager.ACTION_APPWIDGET_BIND) - .putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId) - .putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER, info.provider) - .putExtra(AppWidgetManager.EXTRA_APPWIDGET_PROVIDER_PROFILE, info.getProfile()); - // TODO: we need to make sure that this accounts for the options bundle. - // intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_OPTIONS, options); - activity.startActivityForResult(intent, requestCode); - } - - /** - * Launches an app widget's configuration activity. - * @param activity The activity from which to launch the configuration activity - * @param widgetId The id of the bound app widget to be configured - * @param requestCode An optional request code to be returned with the result - */ - public void startConfigActivity(BaseDraggingActivity activity, int widgetId, int requestCode) { - if (WidgetsModel.GO_DISABLE_WIDGETS) { - sendActionCancelled(activity, requestCode); - return; - } - - try { - TestLogging.recordEvent(TestProtocol.SEQUENCE_MAIN, "start: startConfigActivity"); - startAppWidgetConfigureActivityForResult(activity, widgetId, 0, requestCode, - getConfigurationActivityOptions(activity, widgetId)); - } catch (ActivityNotFoundException | SecurityException e) { - Toast.makeText(activity, R.string.activity_not_found, Toast.LENGTH_SHORT).show(); - sendActionCancelled(activity, requestCode); - } - } - - /** - * Returns an {@link android.app.ActivityOptions} bundle from the {code activity} for launching - * the configuration of the {@code widgetId} app widget, or null of options cannot be produced. - */ - @Nullable - private Bundle getConfigurationActivityOptions(BaseDraggingActivity activity, int widgetId) { - LauncherAppWidgetHostView view = mViews.get(widgetId); - if (view == null) return null; - Object tag = view.getTag(); - if (!(tag instanceof ItemInfo)) return null; - Bundle bundle = activity.getActivityLaunchOptions(view, (ItemInfo) tag).toBundle(); - bundle.putInt(KEY_SPLASH_SCREEN_STYLE, SPLASH_SCREEN_STYLE_EMPTY); - return bundle; - } - - private void sendActionCancelled(final BaseActivity activity, final int requestCode) { - new Handler().post(() -> activity.onActivityResult(requestCode, RESULT_CANCELED, null)); - } - - /** - * Listener for getting notifications on provider changes. - */ - public interface ProviderChangedListener { - - void notifyWidgetProvidersChanged(); - } } diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java index bc3889fd26..990282bdab 100644 --- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java +++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java @@ -37,6 +37,7 @@ import android.widget.AdapterView; import android.widget.Advanceable; import android.widget.RemoteViews; +import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.CheckLongPressHelper; @@ -172,6 +173,16 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView mReinflateOnConfigChange = !isSameOrientation(); } + @NonNull + public Launcher getLauncher() { + return mLauncher; + } + + @Nullable + public RemoteViews getLastRemoteViews() { + return mLastRemoteViews; + } + private boolean isSameOrientation() { return mLauncher.getResources().getConfiguration().orientation == mLauncher.getOrientation(); diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java index 21b2647d0c..ee8d8e85b3 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java +++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java @@ -52,6 +52,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherWidgetHolder.ProviderChangedListener; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.PendingAnimation; @@ -65,7 +66,6 @@ import com.android.launcher3.views.SpringRelativeLayout; import com.android.launcher3.views.StickyHeaderLayout; import com.android.launcher3.views.WidgetsEduView; import com.android.launcher3.widget.BaseWidgetSheet; -import com.android.launcher3.widget.LauncherAppWidgetHost.ProviderChangedListener; import com.android.launcher3.widget.model.WidgetsListBaseEntry; import com.android.launcher3.widget.picker.search.SearchModeListener; import com.android.launcher3.widget.picker.search.WidgetsSearchBar; diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java b/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java index ea0f5a3c5d..51bcca9f52 100644 --- a/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java +++ b/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java @@ -23,8 +23,8 @@ import android.content.pm.ShortcutInfo; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.launcher3.LauncherWidgetHolder; import com.android.launcher3.Utilities; -import com.android.launcher3.widget.LauncherAppWidgetHost; /** * A wrapper for the hidden API calls @@ -43,7 +43,7 @@ public class ApiWrapper { * @param handler InteractionHandler for the views in the host */ public static void setHostInteractionHandler(@NonNull AppWidgetHost host, - @Nullable LauncherAppWidgetHost.LauncherWidgetInteractionHandler handler) { + @Nullable LauncherWidgetHolder.LauncherWidgetInteractionHandler handler) { // No-op } } diff --git a/tests/src/com/android/launcher3/util/WidgetUtils.java b/tests/src/com/android/launcher3/util/WidgetUtils.java index 6fc84914f8..c8cec56c34 100644 --- a/tests/src/com/android/launcher3/util/WidgetUtils.java +++ b/tests/src/com/android/launcher3/util/WidgetUtils.java @@ -20,7 +20,6 @@ import static androidx.test.platform.app.InstrumentationRegistry.getInstrumentat import static com.android.launcher3.WorkspaceLayoutManager.FIRST_SCREEN_ID; -import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetManager; import android.appwidget.AppWidgetProviderInfo; import android.content.ComponentName; @@ -30,9 +29,9 @@ import android.os.Bundle; import android.os.Process; import com.android.launcher3.LauncherSettings; +import com.android.launcher3.LauncherWidgetHolder; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.LauncherAppWidgetInfo; -import com.android.launcher3.widget.LauncherAppWidgetHost; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; import com.android.launcher3.widget.PendingAddWidgetInfo; import com.android.launcher3.widget.WidgetManagerHelper; @@ -71,14 +70,19 @@ public class WidgetUtils { pendingInfo.minSpanY = item.minSpanY; Bundle options = pendingInfo.getDefaultSizeOptions(targetContext); - AppWidgetHost host = new LauncherAppWidgetHost(targetContext); - int widgetId = host.allocateAppWidgetId(); - if (!new WidgetManagerHelper(targetContext) - .bindAppWidgetIdIfAllowed(widgetId, info, options)) { - host.deleteAppWidgetId(widgetId); - throw new IllegalArgumentException("Unable to bind widget id"); + LauncherWidgetHolder holder = new LauncherWidgetHolder(targetContext); + try { + int widgetId = holder.allocateAppWidgetId(); + if (!new WidgetManagerHelper(targetContext) + .bindAppWidgetIdIfAllowed(widgetId, info, options)) { + holder.deleteAppWidgetId(widgetId); + throw new IllegalArgumentException("Unable to bind widget id"); + } + item.appWidgetId = widgetId; + } finally { + // Necessary to destroy the holder to free up possible activity context + holder.destroy(); } - item.appWidgetId = widgetId; } return item; } From 8bbfcb65815cb3d2d6f269d8d11e6d4a04980937 Mon Sep 17 00:00:00 2001 From: Sihua Ma Date: Tue, 8 Nov 2022 16:46:07 -0800 Subject: [PATCH 242/429] Move LauncherWidgetHolder to widget package Making LauncherAppWidgetHost package-private as well Bug: 235358918 Test: N/A Change-Id: If022ec8d429579a972991872b2dc11db76719341 --- .../android/launcher3/uioverrides/ApiWrapper.java | 2 +- .../uioverrides/QuickstepInteractionHandler.java | 2 +- .../launcher3/uioverrides/QuickstepLauncher.java | 2 +- .../launcher3/AppWidgetsRestoredReceiver.java | 1 + src/com/android/launcher3/AutoInstallsLayout.java | 1 + .../android/launcher3/DefaultLayoutParser.java | 1 + src/com/android/launcher3/Launcher.java | 1 + src/com/android/launcher3/LauncherProvider.java | 1 + src/com/android/launcher3/Workspace.java | 3 ++- .../launcher3/dragndrop/AddItemActivity.java | 2 +- .../graphics/LauncherPreviewRenderer.java | 2 +- src/com/android/launcher3/model/ModelWriter.java | 2 +- .../android/launcher3/provider/RestoreDbTask.java | 2 +- .../launcher3/widget/LauncherAppWidgetHost.java | 5 ++--- .../widget/LauncherAppWidgetHostView.java | 11 ----------- .../{ => widget}/LauncherWidgetHolder.java | 15 +++++++-------- .../launcher3/widget/picker/WidgetsFullSheet.java | 2 +- .../android/launcher3/uioverrides/ApiWrapper.java | 2 +- .../com/android/launcher3/util/WidgetUtils.java | 2 +- 19 files changed, 26 insertions(+), 33 deletions(-) rename src/com/android/launcher3/{ => widget}/LauncherWidgetHolder.java (97%) diff --git a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java index 8002c6d525..379a6cd2f4 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java +++ b/quickstep/src/com/android/launcher3/uioverrides/ApiWrapper.java @@ -23,8 +23,8 @@ import android.content.pm.ShortcutInfo; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.launcher3.LauncherWidgetHolder; import com.android.launcher3.Utilities; +import com.android.launcher3.widget.LauncherWidgetHolder; /** * A wrapper for the hidden API calls diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java index 6a6c824ed8..353d817242 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepInteractionHandler.java @@ -29,12 +29,12 @@ import android.view.View; import android.widget.RemoteViews; import android.window.SplashScreen; -import com.android.launcher3.LauncherWidgetHolder; import com.android.launcher3.Utilities; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.util.ActivityOptionsWrapper; import com.android.launcher3.widget.LauncherAppWidgetHostView; +import com.android.launcher3.widget.LauncherWidgetHolder; /** Provides a Quickstep specific animation when launching an activity from an app widget. */ class QuickstepInteractionHandler diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java index 9813c8a987..f90feb8ed7 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java +++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java @@ -78,7 +78,6 @@ import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.LauncherState; -import com.android.launcher3.LauncherWidgetHolder; import com.android.launcher3.QuickstepAccessibilityDelegate; import com.android.launcher3.QuickstepTransitionManager; import com.android.launcher3.R; @@ -125,6 +124,7 @@ import com.android.launcher3.util.PendingSplitSelectInfo; import com.android.launcher3.util.RunnableList; import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; import com.android.launcher3.util.TouchController; +import com.android.launcher3.widget.LauncherWidgetHolder; import com.android.quickstep.OverviewCommandHelper; import com.android.quickstep.RecentsModel; import com.android.quickstep.SystemUiProxy; diff --git a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java index 8604f1acd4..eb6d096602 100644 --- a/src/com/android/launcher3/AppWidgetsRestoredReceiver.java +++ b/src/com/android/launcher3/AppWidgetsRestoredReceiver.java @@ -21,6 +21,7 @@ import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.pm.UserCache; import com.android.launcher3.provider.RestoreDbTask; import com.android.launcher3.util.ContentWriter; +import com.android.launcher3.widget.LauncherWidgetHolder; public class AppWidgetsRestoredReceiver extends BroadcastReceiver { diff --git a/src/com/android/launcher3/AutoInstallsLayout.java b/src/com/android/launcher3/AutoInstallsLayout.java index 0003510ab1..efdd5e15e7 100644 --- a/src/com/android/launcher3/AutoInstallsLayout.java +++ b/src/com/android/launcher3/AutoInstallsLayout.java @@ -47,6 +47,7 @@ import com.android.launcher3.qsb.QsbContainerView; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.Thunk; +import com.android.launcher3.widget.LauncherWidgetHolder; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; diff --git a/src/com/android/launcher3/DefaultLayoutParser.java b/src/com/android/launcher3/DefaultLayoutParser.java index d8558f0ca6..af13beac1d 100644 --- a/src/com/android/launcher3/DefaultLayoutParser.java +++ b/src/com/android/launcher3/DefaultLayoutParser.java @@ -20,6 +20,7 @@ import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.shortcuts.ShortcutKey; import com.android.launcher3.util.Thunk; +import com.android.launcher3.widget.LauncherWidgetHolder; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParserException; diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index de2ef554ad..81f2c18503 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -210,6 +210,7 @@ import com.android.launcher3.views.OptionsPopupView; import com.android.launcher3.views.ScrimView; import com.android.launcher3.widget.LauncherAppWidgetHostView; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; +import com.android.launcher3.widget.LauncherWidgetHolder; import com.android.launcher3.widget.PendingAddShortcutInfo; import com.android.launcher3.widget.PendingAddWidgetInfo; import com.android.launcher3.widget.PendingAppWidgetHostView; diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java index a6731a5d77..457e12673b 100644 --- a/src/com/android/launcher3/LauncherProvider.java +++ b/src/com/android/launcher3/LauncherProvider.java @@ -71,6 +71,7 @@ import com.android.launcher3.util.IntSet; import com.android.launcher3.util.NoLocaleSQLiteHelper; import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.Thunk; +import com.android.launcher3.widget.LauncherWidgetHolder; import org.xmlpull.v1.XmlPullParser; diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 39679a994a..99045dc68a 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -63,7 +63,6 @@ import android.widget.Toast; import androidx.annotation.Nullable; -import com.android.launcher3.LauncherWidgetHolder.ProviderChangedListener; import com.android.launcher3.accessibility.AccessibleDragListenerAdapter; import com.android.launcher3.accessibility.WorkspaceAccessibilityHelper; import com.android.launcher3.anim.Interpolators; @@ -109,6 +108,8 @@ import com.android.launcher3.util.RunnableList; import com.android.launcher3.util.Thunk; import com.android.launcher3.util.WallpaperOffsetInterpolator; import com.android.launcher3.widget.LauncherAppWidgetHostView; +import com.android.launcher3.widget.LauncherWidgetHolder; +import com.android.launcher3.widget.LauncherWidgetHolder.ProviderChangedListener; import com.android.launcher3.widget.NavigableAppWidgetHostView; import com.android.launcher3.widget.PendingAddShortcutInfo; import com.android.launcher3.widget.PendingAddWidgetInfo; diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java index 4fb5ff6638..5a49f4ad41 100644 --- a/src/com/android/launcher3/dragndrop/AddItemActivity.java +++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java @@ -59,7 +59,6 @@ import com.android.launcher3.BaseActivity; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; -import com.android.launcher3.LauncherWidgetHolder; import com.android.launcher3.R; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.model.ItemInstallQueue; @@ -73,6 +72,7 @@ import com.android.launcher3.views.AbstractSlideInView; import com.android.launcher3.views.BaseDragLayer; import com.android.launcher3.widget.AddItemWidgetsBottomSheet; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; +import com.android.launcher3.widget.LauncherWidgetHolder; import com.android.launcher3.widget.NavigableAppWidgetHostView; import com.android.launcher3.widget.PendingAddShortcutInfo; import com.android.launcher3.widget.PendingAddWidgetInfo; diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index 0646e7f802..2361907ed4 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -68,7 +68,6 @@ import com.android.launcher3.InsettableFrameLayout; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherSettings.Favorites; -import com.android.launcher3.LauncherWidgetHolder; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.Workspace; @@ -101,6 +100,7 @@ import com.android.launcher3.views.ActivityContext; import com.android.launcher3.views.BaseDragLayer; import com.android.launcher3.widget.BaseLauncherAppWidgetHostView; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; +import com.android.launcher3.widget.LauncherWidgetHolder; import com.android.launcher3.widget.LocalColorExtractor; import com.android.launcher3.widget.NavigableAppWidgetHostView; import com.android.launcher3.widget.custom.CustomWidgetManager; diff --git a/src/com/android/launcher3/model/ModelWriter.java b/src/com/android/launcher3/model/ModelWriter.java index 514e7b22d8..f444bd5718 100644 --- a/src/com/android/launcher3/model/ModelWriter.java +++ b/src/com/android/launcher3/model/ModelWriter.java @@ -36,7 +36,6 @@ import com.android.launcher3.LauncherProvider; import com.android.launcher3.LauncherSettings; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.LauncherSettings.Settings; -import com.android.launcher3.LauncherWidgetHolder; import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.logging.FileLog; @@ -49,6 +48,7 @@ import com.android.launcher3.util.ContentWriter; import com.android.launcher3.util.Executors; import com.android.launcher3.util.ItemInfoMatcher; import com.android.launcher3.util.LooperExecutor; +import com.android.launcher3.widget.LauncherWidgetHolder; import java.util.ArrayList; import java.util.Arrays; diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java index 70dd98eef6..95ac7b0ca9 100644 --- a/src/com/android/launcher3/provider/RestoreDbTask.java +++ b/src/com/android/launcher3/provider/RestoreDbTask.java @@ -38,7 +38,6 @@ import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherProvider.DatabaseHelper; import com.android.launcher3.LauncherSettings.Favorites; -import com.android.launcher3.LauncherWidgetHolder; import com.android.launcher3.Utilities; import com.android.launcher3.logging.FileLog; import com.android.launcher3.model.DeviceGridState; @@ -48,6 +47,7 @@ import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.provider.LauncherDbUtils.SQLiteTransaction; import com.android.launcher3.util.IntArray; import com.android.launcher3.util.LogConfig; +import com.android.launcher3.widget.LauncherWidgetHolder; import java.io.InvalidObjectException; import java.util.Arrays; diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHost.java b/src/com/android/launcher3/widget/LauncherAppWidgetHost.java index c57139d72c..9c21ea2bb7 100644 --- a/src/com/android/launcher3/widget/LauncherAppWidgetHost.java +++ b/src/com/android/launcher3/widget/LauncherAppWidgetHost.java @@ -16,7 +16,7 @@ package com.android.launcher3.widget; -import static com.android.launcher3.LauncherWidgetHolder.APPWIDGET_HOST_ID; +import static com.android.launcher3.widget.LauncherWidgetHolder.APPWIDGET_HOST_ID; import android.appwidget.AppWidgetHost; import android.appwidget.AppWidgetProviderInfo; @@ -26,7 +26,6 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.LauncherAppState; -import com.android.launcher3.LauncherWidgetHolder; import java.util.ArrayList; import java.util.function.IntConsumer; @@ -36,7 +35,7 @@ import java.util.function.IntConsumer; * which correctly captures all long-press events. This ensures that users can * always pick up and move widgets. */ -public class LauncherAppWidgetHost extends AppWidgetHost { +class LauncherAppWidgetHost extends AppWidgetHost { @NonNull private final ArrayList mProviderChangeListeners = new ArrayList<>(); diff --git a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java index 990282bdab..bc3889fd26 100644 --- a/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java +++ b/src/com/android/launcher3/widget/LauncherAppWidgetHostView.java @@ -37,7 +37,6 @@ import android.widget.AdapterView; import android.widget.Advanceable; import android.widget.RemoteViews; -import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.CheckLongPressHelper; @@ -173,16 +172,6 @@ public class LauncherAppWidgetHostView extends BaseLauncherAppWidgetHostView mReinflateOnConfigChange = !isSameOrientation(); } - @NonNull - public Launcher getLauncher() { - return mLauncher; - } - - @Nullable - public RemoteViews getLastRemoteViews() { - return mLastRemoteViews; - } - private boolean isSameOrientation() { return mLauncher.getResources().getConfiguration().orientation == mLauncher.getOrientation(); diff --git a/src/com/android/launcher3/LauncherWidgetHolder.java b/src/com/android/launcher3/widget/LauncherWidgetHolder.java similarity index 97% rename from src/com/android/launcher3/LauncherWidgetHolder.java rename to src/com/android/launcher3/widget/LauncherWidgetHolder.java index 2612b9cb63..54977297b8 100644 --- a/src/com/android/launcher3/LauncherWidgetHolder.java +++ b/src/com/android/launcher3/widget/LauncherWidgetHolder.java @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package com.android.launcher3; +package com.android.launcher3.widget; import static android.app.Activity.RESULT_CANCELED; @@ -36,17 +36,16 @@ import android.widget.Toast; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.launcher3.BaseActivity; +import com.android.launcher3.BaseDraggingActivity; +import com.android.launcher3.R; +import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.model.WidgetsModel; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.shared.TestProtocol; import com.android.launcher3.uioverrides.ApiWrapper; -import com.android.launcher3.widget.DeferredAppWidgetHostView; -import com.android.launcher3.widget.LauncherAppWidgetHost; -import com.android.launcher3.widget.LauncherAppWidgetHostView; -import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; -import com.android.launcher3.widget.PendingAppWidgetHostView; import com.android.launcher3.widget.custom.CustomWidgetManager; import java.util.function.IntConsumer; @@ -134,7 +133,7 @@ public class LauncherWidgetHolder { // If the widget view was deferred, we'll need to call super.createView here // to make the binder call to system process to fetch cumulative updates to this // widget, as well as setting up this view for future updates. - mWidgetHost.createView(view.getLauncher(), appWidgetId, + mWidgetHost.createView(view.mLauncher, appWidgetId, view.getAppWidgetInfo()); // At this point #onCreateView should have been called, which in turn returned // the deferred view. There's no reason to keep the reference anymore, so we @@ -455,7 +454,7 @@ public class LauncherWidgetHolder { for (int i = 0; i < mViews.size(); i++) { final int appWidgetId = mViews.keyAt(i); final LauncherAppWidgetHostView view = mViews.get(appWidgetId); - mCachedRemoteViews.put(appWidgetId, view.getLastRemoteViews()); + mCachedRemoteViews.put(appWidgetId, view.mLastRemoteViews); } } mViews.clear(); diff --git a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java index ee8d8e85b3..72ec62979e 100644 --- a/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java +++ b/src/com/android/launcher3/widget/picker/WidgetsFullSheet.java @@ -52,7 +52,6 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; -import com.android.launcher3.LauncherWidgetHolder.ProviderChangedListener; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.PendingAnimation; @@ -66,6 +65,7 @@ import com.android.launcher3.views.SpringRelativeLayout; import com.android.launcher3.views.StickyHeaderLayout; import com.android.launcher3.views.WidgetsEduView; import com.android.launcher3.widget.BaseWidgetSheet; +import com.android.launcher3.widget.LauncherWidgetHolder.ProviderChangedListener; import com.android.launcher3.widget.model.WidgetsListBaseEntry; import com.android.launcher3.widget.picker.search.SearchModeListener; import com.android.launcher3.widget.picker.search.WidgetsSearchBar; diff --git a/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java b/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java index 51bcca9f52..02f4ecee3c 100644 --- a/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java +++ b/src_ui_overrides/com/android/launcher3/uioverrides/ApiWrapper.java @@ -23,8 +23,8 @@ import android.content.pm.ShortcutInfo; import androidx.annotation.NonNull; import androidx.annotation.Nullable; -import com.android.launcher3.LauncherWidgetHolder; import com.android.launcher3.Utilities; +import com.android.launcher3.widget.LauncherWidgetHolder; /** * A wrapper for the hidden API calls diff --git a/tests/src/com/android/launcher3/util/WidgetUtils.java b/tests/src/com/android/launcher3/util/WidgetUtils.java index c8cec56c34..e514142f7d 100644 --- a/tests/src/com/android/launcher3/util/WidgetUtils.java +++ b/tests/src/com/android/launcher3/util/WidgetUtils.java @@ -29,10 +29,10 @@ import android.os.Bundle; import android.os.Process; import com.android.launcher3.LauncherSettings; -import com.android.launcher3.LauncherWidgetHolder; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.LauncherAppWidgetInfo; import com.android.launcher3.widget.LauncherAppWidgetProviderInfo; +import com.android.launcher3.widget.LauncherWidgetHolder; import com.android.launcher3.widget.PendingAddWidgetInfo; import com.android.launcher3.widget.WidgetManagerHelper; From 6692f78229b42462ba90e2666e7dd42d0f6e8c1f Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Wed, 9 Nov 2022 18:26:06 -0800 Subject: [PATCH 243/429] Allow user to tap on stashed app to launch task in fullscreen This patch implements a new feature that allows the user to tap on the staged app rectangle in split staging mode. When the user does so, split selection will be canceled, and the staged app will animate out to fill the screen and launch in fullscreen. Done by creating a new onClick listener on mFirstFloatingTaskView that sets up the screen-filling animation, and then calls a new RecentsView function, launchStagedTask(), that launches mSplitHiddenTaskView and cleans up RecentsView afterwards (similar to what happens when a split pair is selected, but only one app is launched). Open issues: - After the staged task animates out to fill the screen, the task itself loads instantly without animating in. Ideally, it should fade in, similar to what happens when two split tasks are loaded in. Bug: 257513449 Test: Manual on tablet Change-Id: I2ae8e13e1c9848aae1978a536766c370949fd08b --- .../quickstep/util/SplitAnimationTimings.java | 2 +- .../android/quickstep/views/RecentsView.java | 50 +++++++++++++++++-- .../launcher3/config/FeatureFlags.java | 5 ++ 3 files changed, 51 insertions(+), 6 deletions(-) diff --git a/quickstep/src/com/android/quickstep/util/SplitAnimationTimings.java b/quickstep/src/com/android/quickstep/util/SplitAnimationTimings.java index 2966fbb5db..7dc1b32858 100644 --- a/quickstep/src/com/android/quickstep/util/SplitAnimationTimings.java +++ b/quickstep/src/com/android/quickstep/util/SplitAnimationTimings.java @@ -25,7 +25,7 @@ import android.view.animation.Interpolator; */ public interface SplitAnimationTimings { int TABLET_ENTER_DURATION = 866; - int TABLET_CONFIRM_DURATION = 383; + int TABLET_CONFIRM_DURATION = 500; int PHONE_ENTER_DURATION = 517; int PHONE_CONFIRM_DURATION = 333; diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index ff0c984b6d..2474b690a8 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -41,6 +41,7 @@ import static com.android.launcher3.anim.Interpolators.FINAL_FRAME; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.anim.Interpolators.OVERSHOOT_0_75; import static com.android.launcher3.anim.Interpolators.clampToProgress; +import static com.android.launcher3.config.FeatureFlags.ENABLE_LAUNCH_FROM_STAGED_APP; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_OVERVIEW_ACTIONS_SPLIT; 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; @@ -125,7 +126,6 @@ import androidx.annotation.Nullable; import androidx.annotation.UiThread; import androidx.core.graphics.ColorUtils; -import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseActivity; import com.android.launcher3.BaseActivity.MultiWindowModeChangedListener; import com.android.launcher3.DeviceProfile; @@ -2903,6 +2903,11 @@ public abstract class RecentsView launchStagedTask()); + + pendingAnimation.buildAnim().start(); + } + /** * Creates a {@link PendingAnimation} for dismissing the specified {@link TaskView}. * @param dismissedTaskView the {@link TaskView} to be dismissed @@ -4294,11 +4327,8 @@ public abstract class RecentsView resetFromSplitSelectionState()); + } else { + // Split staging was started from a new intent (from app menu in Home/AllApps) + mActivity.startActivity(mSplitSelectSource.intent); + } + } + protected void onTaskLaunchAnimationEnd(boolean success) { if (success) { resetTaskVisuals(); diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 33f3bfdbfe..e20489c3aa 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -342,6 +342,11 @@ public final class FeatureFlags { public static final BooleanFlag ENABLE_DEVICE_PROFILE_LOGGING = new DeviceFlag( "ENABLE_DEVICE_PROFILE_LOGGING", false, "Allows DeviceProfile logging"); + public static final BooleanFlag ENABLE_LAUNCH_FROM_STAGED_APP = getDebugFlag( + "ENABLE_LAUNCH_FROM_STAGED_APP", false, + "Enable the ability to tap a staged app during split select to launch it in full screen" + ); + public static void initialize(Context context) { synchronized (sDebugFlags) { for (DebugFlag flag : sDebugFlags) { From dc837863393d6a2b3d7b4dce306210a1ad4cf256 Mon Sep 17 00:00:00 2001 From: Hawkwood Glazier Date: Fri, 11 Nov 2022 22:28:19 +0000 Subject: [PATCH 244/429] Update PluginManager Import Bug: 258424862 Test: Rebuilt Launcher Change-Id: I7a8b343533e8d8eb8fddc3683c57ece664af8736 --- .../launcher3/uioverrides/plugins/PluginManagerWrapper.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java index fe0bca6646..e3d386cae6 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java +++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginManagerWrapper.java @@ -28,9 +28,9 @@ import com.android.launcher3.Utilities; import com.android.launcher3.util.MainThreadInitializedObject; import com.android.systemui.plugins.Plugin; import com.android.systemui.plugins.PluginListener; +import com.android.systemui.plugins.PluginManager; import com.android.systemui.shared.plugins.PluginActionManager; import com.android.systemui.shared.plugins.PluginInstance; -import com.android.systemui.shared.plugins.PluginManager; import com.android.systemui.shared.plugins.PluginManagerImpl; import com.android.systemui.shared.plugins.PluginPrefs; import com.android.systemui.shared.system.UncaughtExceptionPreHandlerManager; From 30cc32411771d1dcc1a98d370c94c60200b71207 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Wed, 16 Nov 2022 15:51:10 -0800 Subject: [PATCH 245/429] Check NPE and log error condition for enableBlockingTimeout in test harness. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Similar to enableTransientTaskbar changes in ag/Ifa929dca18437ae101cf3290feda4209790604d2 This method differs from enableManualTaskbarStashing in that we call it during setup/teardown and so in these cases TaskbarActivityContext being null may be valid. For instance, as part of the teardown, taskbar may have already been destroyed so enabling blocking timeout may be a moot point — adding logs can help verify that assumption. Bug: 259337908 Bug: 257549303 Test: TaplTestsTaskbar Change-Id: I2eeb02573670a503687ca7aa364d14f3124cd0ef --- .../quickstep/QuickstepTestInformationHandler.java | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java index 65614ba966..713b01654c 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -179,9 +179,15 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { private void enableBlockingTimeout( TouchInteractionService.TISBinder tisBinder, boolean enable) { - // Allow null-pointer to catch illegal states. - tisBinder.getTaskbarManager().getCurrentActivityContext().enableBlockingTimeoutDuringTests( - enable); + TaskbarActivityContext context = tisBinder.getTaskbarManager().getCurrentActivityContext(); + if (context == null) { + if (TestProtocol.sDebugTracing) { + Log.d(NPE_TRANSIENT_TASKBAR, "enableBlockingTimeout: enable=" + enable, + new Exception()); + } + } else { + context.enableBlockingTimeoutDuringTests(enable); + } } private void enableTransientTaskbar( From 47d4d81b4f4dcc604716306745756df4bee35a7b Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Fri, 4 Nov 2022 16:43:42 -0700 Subject: [PATCH 246/429] Cleaning Utilities.java > Removing some unused methods > Moving some specialized methods to corresponding classes > Removing GridProvider check as it is released Bug: 257555083 Test: Presubmit Change-Id: Ib0f8c673d018071d3f4b7d9247e0a35718ab009c Merged-In: Ib0f8c673d018071d3f4b7d9247e0a35718ab009c --- .../launcher3/model/WellbeingModel.java | 2 - .../RecentsAnimationDeviceState.java | 25 +- .../LauncherUnfoldAnimationController.java | 3 +- .../com/android/quickstep/views/TaskView.java | 3 +- src/com/android/launcher3/BubbleTextView.java | 9 +- .../launcher3/InvariantDeviceProfile.java | 7 +- src/com/android/launcher3/Utilities.java | 254 +++--------------- .../android/launcher3/folder/FolderIcon.java | 11 +- .../android/launcher3/model/ModelUtils.java | 10 +- .../launcher3/util/BgObjectWithLooper.java | 17 ++ .../util/SimpleBroadcastReceiver.java | 11 + .../launcher3/views/OptionsPopupView.java | 27 +- 12 files changed, 110 insertions(+), 269 deletions(-) diff --git a/quickstep/src/com/android/launcher3/model/WellbeingModel.java b/quickstep/src/com/android/launcher3/model/WellbeingModel.java index 68ed682792..fb2d0dcc3c 100644 --- a/quickstep/src/com/android/launcher3/model/WellbeingModel.java +++ b/quickstep/src/com/android/launcher3/model/WellbeingModel.java @@ -18,8 +18,6 @@ package com.android.launcher3.model; import static android.content.ContentResolver.SCHEME_CONTENT; -import static com.android.launcher3.Utilities.newContentObserver; - import android.annotation.TargetApi; import android.app.RemoteAction; import android.content.ContentProviderClient; diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java index e87fdad933..9e25555eec 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationDeviceState.java @@ -46,10 +46,7 @@ import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_S import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED; import android.app.ActivityTaskManager; -import android.content.BroadcastReceiver; import android.content.Context; -import android.content.Intent; -import android.content.IntentFilter; import android.graphics.Region; import android.inputmethodservice.InputMethodService; import android.net.Uri; @@ -63,12 +60,12 @@ import android.view.MotionEvent; import androidx.annotation.BinderThread; import androidx.annotation.NonNull; -import com.android.launcher3.Utilities; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.DisplayController.DisplayInfoChangeListener; import com.android.launcher3.util.DisplayController.Info; import com.android.launcher3.util.NavigationMode; import com.android.launcher3.util.SettingsCache; +import com.android.launcher3.util.SimpleBroadcastReceiver; import com.android.quickstep.TopTaskTracker.CachedTaskInfo; import com.android.quickstep.util.NavBarPosition; import com.android.systemui.shared.system.ActivityManagerWrapper; @@ -114,15 +111,12 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener { private boolean mIsUserUnlocked; private final ArrayList mUserUnlockedActions = new ArrayList<>(); - private final BroadcastReceiver mUserUnlockedReceiver = new BroadcastReceiver() { - @Override - public void onReceive(Context context, Intent intent) { - if (ACTION_USER_UNLOCKED.equals(intent.getAction())) { - mIsUserUnlocked = true; - notifyUserUnlocked(); - } + private final SimpleBroadcastReceiver mUserUnlockedReceiver = new SimpleBroadcastReceiver(i -> { + if (ACTION_USER_UNLOCKED.equals(i.getAction())) { + mIsUserUnlocked = true; + notifyUserUnlocked(); } - }; + }); private int mGestureBlockingTaskId = -1; private @NonNull Region mExclusionRegion = new Region(); @@ -153,10 +147,9 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener { mIsUserUnlocked = context.getSystemService(UserManager.class) .isUserUnlocked(Process.myUserHandle()); if (!mIsUserUnlocked) { - mContext.registerReceiver(mUserUnlockedReceiver, - new IntentFilter(ACTION_USER_UNLOCKED)); + mUserUnlockedReceiver.register(mContext, ACTION_USER_UNLOCKED); } - runOnDestroy(() -> Utilities.unregisterReceiverSafely(mContext, mUserUnlockedReceiver)); + runOnDestroy(() -> mUserUnlockedReceiver.unregisterReceiverSafely(mContext)); // Register for exclusion updates mExclusionListener = new SystemGestureExclusionListenerCompat(mDisplayId) { @@ -347,7 +340,7 @@ public class RecentsAnimationDeviceState implements DisplayInfoChangeListener { action.run(); } mUserUnlockedActions.clear(); - Utilities.unregisterReceiverSafely(mContext, mUserUnlockedReceiver); + mUserUnlockedReceiver.unregisterReceiverSafely(mContext); } /** diff --git a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java index f12074b538..170c622035 100644 --- a/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java +++ b/quickstep/src/com/android/quickstep/util/LauncherUnfoldAnimationController.java @@ -18,7 +18,6 @@ package com.android.quickstep.util; import static com.android.launcher3.LauncherAnimUtils.HOTSEAT_SCALE_PROPERTY_FACTORY; import static com.android.launcher3.LauncherAnimUtils.SCALE_INDEX_UNFOLD_ANIMATION; import static com.android.launcher3.LauncherAnimUtils.WORKSPACE_SCALE_PROPERTY_FACTORY; -import static com.android.launcher3.Utilities.comp; import android.annotation.Nullable; import android.util.FloatProperty; @@ -135,7 +134,7 @@ public class LauncherUnfoldAnimationController { @Override public void onTransitionProgress(float progress) { if (mQsbInsettable != null) { - float insetPercentage = comp(progress) * MAX_WIDTH_INSET_FRACTION; + float insetPercentage = (1 - progress) * MAX_WIDTH_INSET_FRACTION; mQsbInsettable.setHorizontalInsets(insetPercentage); } } diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index 583771e15e..180e13b371 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -20,7 +20,6 @@ import static android.view.Display.DEFAULT_DISPLAY; import static android.widget.Toast.LENGTH_SHORT; import static com.android.launcher3.LauncherState.BACKGROUND_APP; -import static com.android.launcher3.Utilities.comp; import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor; import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; @@ -501,7 +500,7 @@ public class TaskView extends FrameLayout implements Reusable { return; } mModalness = modalness; - mIconView.setAlpha(comp(modalness)); + mIconView.setAlpha(1 - modalness); mDigitalWellBeingToast.updateBannerOffset(modalness, mCurrentFullscreenParams.mCurrentDrawnInsets.top + mCurrentFullscreenParams.mCurrentDrawnInsets.bottom); diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index c0a00c2784..9f54f09bb6 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -607,15 +607,16 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, * Get the icon bounds on the view depending on the layout type. */ public void getIconBounds(int iconSize, Rect outBounds) { - Utilities.setRectToViewCenter(this, iconSize, outBounds); + outBounds.set(0, 0, iconSize, iconSize); if (mLayoutHorizontal) { + int top = (getHeight() - iconSize) / 2; if (mIsRtl) { - outBounds.offsetTo(getWidth() - iconSize - getPaddingRight(), outBounds.top); + outBounds.offsetTo(getWidth() - iconSize - getPaddingRight(), top); } else { - outBounds.offsetTo(getPaddingLeft(), outBounds.top); + outBounds.offsetTo(getPaddingLeft(), top); } } else { - outBounds.offsetTo(outBounds.left, getPaddingTop()); + outBounds.offset((getWidth() - iconSize) / 2, getPaddingTop()); } } diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index ca92aa48f6..4bb9f0682d 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -307,8 +307,7 @@ public class InvariantDeviceProfile { } public static String getCurrentGridName(Context context) { - return Utilities.isGridOptionsEnabled(context) - ? Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null) : null; + return Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null); } private String initGrid(Context context, String gridName) { @@ -383,10 +382,6 @@ public class InvariantDeviceProfile { allAppsBorderSpaces = displayOption.allAppsBorderSpaces; allAppsIconSize = displayOption.allAppsIconSizes; allAppsIconTextSize = displayOption.allAppsIconTextSizes; - if (!Utilities.isGridOptionsEnabled(context)) { - allAppsIconSize = iconSize; - allAppsIconTextSize = iconTextSize; - } if (devicePaddingId != 0) { devicePaddings = new DevicePaddings(context, devicePaddingId); diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index a5075327d0..743e3aed52 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -26,20 +26,13 @@ import android.annotation.TargetApi; import android.app.ActivityManager; import android.app.Person; import android.app.WallpaperManager; -import android.content.BroadcastReceiver; -import android.content.ComponentName; import android.content.Context; -import android.content.Intent; import android.content.SharedPreferences; import android.content.pm.LauncherActivityInfo; import android.content.pm.LauncherApps; -import android.content.pm.PackageInfo; -import android.content.pm.PackageManager; -import android.content.pm.ResolveInfo; import android.content.pm.ShortcutInfo; import android.content.res.Configuration; import android.content.res.Resources; -import android.database.ContentObserver; import android.graphics.Color; import android.graphics.ColorFilter; import android.graphics.LightingColorFilter; @@ -51,7 +44,6 @@ import android.graphics.RectF; import android.graphics.drawable.AdaptiveIconDrawable; import android.graphics.drawable.ColorDrawable; import android.graphics.drawable.Drawable; -import android.net.Uri; import android.os.Build; import android.os.Build.VERSION_CODES; import android.os.DeadObjectException; @@ -71,15 +63,12 @@ import android.view.MotionEvent; import android.view.View; import android.view.ViewConfiguration; import android.view.animation.Interpolator; -import android.widget.LinearLayout; import androidx.annotation.ChecksSdkIntAtLeast; import androidx.annotation.NonNull; -import androidx.annotation.Nullable; import androidx.core.graphics.ColorUtils; import com.android.launcher3.dragndrop.FolderAdaptiveIcon; -import com.android.launcher3.graphics.GridCustomizationsProvider; import com.android.launcher3.graphics.TintedDrawableSpan; import com.android.launcher3.icons.ShortcutCachingLogic; import com.android.launcher3.icons.ThemedIconDrawable; @@ -91,7 +80,6 @@ import com.android.launcher3.shortcuts.ShortcutKey; import com.android.launcher3.shortcuts.ShortcutRequest; import com.android.launcher3.testing.shared.ResourceUtils; import com.android.launcher3.util.IntArray; -import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.util.SplitConfigurationOptions.SplitPositionOption; import com.android.launcher3.util.Themes; import com.android.launcher3.views.ActivityContext; @@ -100,10 +88,8 @@ import com.android.launcher3.widget.PendingAddShortcutInfo; import java.lang.reflect.Method; import java.util.ArrayList; -import java.util.Arrays; import java.util.List; import java.util.Locale; -import java.util.function.Consumer; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -117,8 +103,6 @@ public final class Utilities { private static final Pattern sTrimPattern = Pattern.compile("^[\\s|\\p{javaSpaceChar}]*(.*)[\\s|\\p{javaSpaceChar}]*$"); - private static final int[] sLoc0 = new int[2]; - private static final int[] sLoc1 = new int[2]; private static final Matrix sMatrix = new Matrix(); private static final Matrix sInverseMatrix = new Matrix(); @@ -167,14 +151,6 @@ public final class Utilities { Settings.Global.DEVELOPMENT_SETTINGS_ENABLED, 0) != 0; } - // An intent extra to indicate the horizontal scroll of the wallpaper. - public static final String EXTRA_WALLPAPER_OFFSET = "com.android.launcher3.WALLPAPER_OFFSET"; - public static final String EXTRA_WALLPAPER_FLAVOR = "com.android.launcher3.WALLPAPER_FLAVOR"; - - // An intent extra to indicate the launch source by launcher. - public static final String EXTRA_WALLPAPER_LAUNCH_SOURCE = - "com.android.wallpaper.LAUNCH_SOURCE"; - public static boolean IS_RUNNING_IN_TEST_HARNESS = ActivityManager.isRunningInTestHarness(); @@ -186,12 +162,6 @@ public final class Utilities { return Log.isLoggable(propertyName, Log.VERBOSE); } - public static boolean existsStyleWallpapers(Context context) { - ResolveInfo ri = context.getPackageManager().resolveActivity( - PackageManagerHelper.getStyleWallpapersIntent(context), 0); - return ri != null; - } - /** * Given a coordinate relative to the descendant, find the coordinate in a parent view's * coordinates. @@ -305,9 +275,9 @@ public final class Utilities { * Sets {@param out} to be same as {@param in} by rounding individual values */ public static void roundArray(float[] in, int[] out) { - for (int i = 0; i < in.length; i++) { - out[i] = Math.round(in[i]); - } + for (int i = 0; i < in.length; i++) { + out[i] = Math.round(in[i]); + } } public static void offsetPoints(float[] points, float offsetX, float offsetY) { @@ -328,80 +298,8 @@ public final class Utilities { localY < (v.getHeight() + slop); } - public static int[] getCenterDeltaInScreenSpace(View v0, View v1) { - v0.getLocationInWindow(sLoc0); - v1.getLocationInWindow(sLoc1); - - sLoc0[0] += (v0.getMeasuredWidth() * v0.getScaleX()) / 2; - sLoc0[1] += (v0.getMeasuredHeight() * v0.getScaleY()) / 2; - sLoc1[0] += (v1.getMeasuredWidth() * v1.getScaleX()) / 2; - sLoc1[1] += (v1.getMeasuredHeight() * v1.getScaleY()) / 2; - return new int[] {sLoc1[0] - sLoc0[0], sLoc1[1] - sLoc0[1]}; - } - - /** - * Helper method to set rectOut with rectFSrc. - */ - public static void setRect(RectF rectFSrc, Rect rectOut) { - rectOut.left = (int) rectFSrc.left; - rectOut.top = (int) rectFSrc.top; - rectOut.right = (int) rectFSrc.right; - rectOut.bottom = (int) rectFSrc.bottom; - } - public static void scaleRectFAboutCenter(RectF r, float scale) { - scaleRectFAboutPivot(r, scale, r.centerX(), r.centerY()); - } - - public static void scaleRectFAboutPivot(RectF r, float scale, float px, float py) { - if (scale != 1.0f) { - r.offset(-px, -py); - r.left = r.left * scale; - r.top = r.top * scale ; - r.right = r.right * scale; - r.bottom = r.bottom * scale; - r.offset(px, py); - } - } - - public static void scaleRectAboutCenter(Rect r, float scale) { - if (scale != 1.0f) { - int cx = r.centerX(); - int cy = r.centerY(); - r.offset(-cx, -cy); - scaleRect(r, scale); - r.offset(cx, cy); - } - } - - public static void scaleRect(Rect r, float scale) { - if (scale != 1.0f) { - r.left = (int) (r.left * scale + 0.5f); - r.top = (int) (r.top * scale + 0.5f); - r.right = (int) (r.right * scale + 0.5f); - r.bottom = (int) (r.bottom * scale + 0.5f); - } - } - - public static void insetRect(Rect r, Rect insets) { - r.left = Math.min(r.right, r.left + insets.left); - r.top = Math.min(r.bottom, r.top + insets.top); - r.right = Math.max(r.left, r.right - insets.right); - r.bottom = Math.max(r.top, r.bottom - insets.bottom); - } - - public static float shrinkRect(Rect r, float scaleX, float scaleY) { - float scale = Math.min(Math.min(scaleX, scaleY), 1.0f); - if (scale < 1.0f) { - int deltaX = (int) (r.width() * (scaleX - scale) * 0.5f); - r.left += deltaX; - r.right -= deltaX; - - int deltaY = (int) (r.height() * (scaleY - scale) * 0.5f); - r.top += deltaY; - r.bottom -= deltaY; - } - return scale; + scaleRectFAboutCenter(r, scale, scale); } /** @@ -419,6 +317,33 @@ public final class Utilities { r.offset(px, py); } + public static void scaleRectAboutCenter(Rect r, float scale) { + if (scale != 1.0f) { + int cx = r.centerX(); + int cy = r.centerY(); + r.offset(-cx, -cy); + r.left = (int) (r.left * scale + 0.5f); + r.top = (int) (r.top * scale + 0.5f); + r.right = (int) (r.right * scale + 0.5f); + r.bottom = (int) (r.bottom * scale + 0.5f); + r.offset(cx, cy); + } + } + + public static float shrinkRect(Rect r, float scaleX, float scaleY) { + float scale = Math.min(Math.min(scaleX, scaleY), 1.0f); + if (scale < 1.0f) { + int deltaX = (int) (r.width() * (scaleX - scale) * 0.5f); + r.left += deltaX; + r.right -= deltaX; + + int deltaY = (int) (r.height() * (scaleY - scale) * 0.5f); + r.top += deltaY; + r.bottom -= deltaY; + } + return scale; + } + /** * Maps t from one range to another range. * @param t The value to map. @@ -453,30 +378,6 @@ public final class Utilities { return min + (value * (max - min)); } - /** - * Bounds parameter to the range [0, 1] - */ - public static float saturate(float a) { - return boundToRange(a, 0, 1.0f); - } - - /** - * Returns the compliment (1 - a) of the parameter. - */ - public static float comp(float a) { - return 1 - a; - } - - /** - * Returns the "probabilistic or" of a and b. (a + b - ab). - * Useful beyond probability, can be used to combine two unit progresses for example. - */ - public static float or(float a, float b) { - float satA = saturate(a); - float satB = saturate(b); - return satA + satB - (satA * satB); - } - /** * Trims the string, removing all whitespace at the beginning and end of the string. * Non-breaking whitespaces are also removed. @@ -536,7 +437,6 @@ public final class Utilities { return ResourceUtils.roundPxValueFromFloat(value); } - public static String createDbSelectionQuery(String columnName, IntArray values) { return String.format(Locale.ENGLISH, "%s IN (%s)", columnName, values.toConcatString()); } @@ -559,18 +459,6 @@ public final class Utilities { return defaultValue; } - /** - * Using the view's bounds and icon size, calculate where the icon bounds will - * be if it was positioned at the center of the view. - */ - public static void setRectToViewCenter(View iconView, int iconSize, Rect outBounds) { - int top = (iconView.getHeight() - iconSize) / 2; - int left = (iconView.getWidth() - iconSize) / 2; - int right = left + iconSize; - int bottom = top + iconSize; - outBounds.set(left, top, right, bottom); - } - /** * Ensures that a value is within given bounds. Specifically: * If value is less than lowerBound, return lowerBound; else if value is greater than upperBound, @@ -646,42 +534,6 @@ public final class Utilities { || e.getCause() instanceof DeadObjectException; } - public static boolean isGridOptionsEnabled(Context context) { - return isComponentEnabled(context.getPackageManager(), - context.getPackageName(), - GridCustomizationsProvider.class.getName()); - } - - private static boolean isComponentEnabled(PackageManager pm, String pkgName, String clsName) { - ComponentName componentName = new ComponentName(pkgName, clsName); - int componentEnabledSetting = pm.getComponentEnabledSetting(componentName); - - switch (componentEnabledSetting) { - case PackageManager.COMPONENT_ENABLED_STATE_DISABLED: - return false; - case PackageManager.COMPONENT_ENABLED_STATE_ENABLED: - return true; - case PackageManager.COMPONENT_ENABLED_STATE_DEFAULT: - default: - // We need to get the application info to get the component's default state - try { - PackageInfo packageInfo = pm.getPackageInfo(pkgName, - PackageManager.GET_PROVIDERS | PackageManager.GET_DISABLED_COMPONENTS); - - if (packageInfo.providers != null) { - return Arrays.stream(packageInfo.providers).anyMatch( - pi -> pi.name.equals(clsName) && pi.isEnabled()); - } - - // the component is not declared in the AndroidManifest - return false; - } catch (PackageManager.NameNotFoundException e) { - // the package isn't installed on the device - return false; - } - } - } - /** * Utility method to post a runnable on the handler, skipping the synchronization barriers. */ @@ -691,12 +543,6 @@ public final class Utilities { handler.sendMessage(msg); } - public static void unregisterReceiverSafely(Context context, BroadcastReceiver receiver) { - try { - context.unregisterReceiver(receiver); - } catch (IllegalArgumentException e) {} - } - /** * Returns the full drawable for info without any flattening or pre-processing. * @@ -794,14 +640,6 @@ public final class Utilities { } } - /** - * @return true is the extra is either null or is of type {@param type} - */ - public static boolean isValidExtraType(Intent intent, String key, Class type) { - Object extra = intent.getParcelableExtra(key); - return extra == null || type.isInstance(extra); - } - public static float squaredHypot(float x, float y) { return x * x + y * y; } @@ -811,18 +649,6 @@ public final class Utilities { return slop * slop; } - /** - * Helper method to create a content provider - */ - public static ContentObserver newContentObserver(Handler handler, Consumer command) { - return new ContentObserver(handler) { - @Override - public void onChange(boolean selfChange, Uri uri) { - command.accept(uri); - } - }; - } - /** * Rotates `inOutBounds` by `delta` 90-degree increments. Rotation is visually CCW. Parent * sizes represent the "space" that will rotate carrying inOutBounds along with it to determine @@ -871,16 +697,6 @@ public final class Utilities { ColorUtils.blendARGB(0, color, tintAmount)); } - /** - * Sets start margin on the provided {@param view} to be {@param margin}. - * Assumes {@param view} is a child of {@link LinearLayout} - */ - public static void setStartMarginForView(View view, int margin) { - LinearLayout.LayoutParams lp = (LinearLayout.LayoutParams) view.getLayoutParams(); - lp.setMarginStart(margin); - view.setLayoutParams(lp); - } - public static Rect getViewBounds(@NonNull View v) { int[] pos = new int[2]; v.getLocationOnScreen(pos); @@ -921,12 +737,4 @@ public final class Utilities { } return options; } - - public static boolean bothNull(@Nullable Object a, @Nullable Object b) { - return a == null && b == null; - } - - public static boolean bothNonNull(@Nullable Object a, @Nullable Object b) { - return a != null && b != null; - } } diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java index e8759da0d0..dd00f07807 100644 --- a/src/com/android/launcher3/folder/FolderIcon.java +++ b/src/com/android/launcher3/folder/FolderIcon.java @@ -616,11 +616,14 @@ public class FolderIcon extends FrameLayout implements FolderListener, IconLabel public void drawDot(Canvas canvas) { if (!mForceHideDot && ((mDotInfo != null && mDotInfo.hasDot()) || mDotScale > 0)) { Rect iconBounds = mDotParams.iconBounds; + // FolderIcon draws the icon to be top-aligned (with padding) & horizontally-centered + int iconSize = mActivity.getDeviceProfile().iconSizePx; + iconBounds.left = (getWidth() - iconSize) / 2; + iconBounds.right = iconBounds.left + iconSize; + iconBounds.top = getPaddingTop(); + iconBounds.bottom = iconBounds.top + iconSize; - Utilities.setRectToViewCenter(this, mActivity.getDeviceProfile().iconSizePx, - iconBounds); - iconBounds.offsetTo(iconBounds.left, getPaddingTop()); - float iconScale = (float) mBackground.previewSize / iconBounds.width(); + float iconScale = (float) mBackground.previewSize / iconSize; Utilities.scaleRectAboutCenter(iconBounds, iconScale); // If we are animating to the accepting state, animate the dot out. diff --git a/src/com/android/launcher3/model/ModelUtils.java b/src/com/android/launcher3/model/ModelUtils.java index 1ced0b16f4..c21fc38cfb 100644 --- a/src/com/android/launcher3/model/ModelUtils.java +++ b/src/com/android/launcher3/model/ModelUtils.java @@ -15,8 +15,6 @@ */ package com.android.launcher3.model; -import static com.android.launcher3.Utilities.isValidExtraType; - import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; @@ -149,4 +147,12 @@ public class ModelUtils { info.intent = launchIntent; return info; } + + /** + * @return true if the extra is either null or is of type {@param type} + */ + private static boolean isValidExtraType(Intent intent, String key, Class type) { + Object extra = intent.getParcelableExtra(key); + return extra == null || type.isInstance(extra); + } } diff --git a/src/com/android/launcher3/util/BgObjectWithLooper.java b/src/com/android/launcher3/util/BgObjectWithLooper.java index 1483c43a11..adc3c7d885 100644 --- a/src/com/android/launcher3/util/BgObjectWithLooper.java +++ b/src/com/android/launcher3/util/BgObjectWithLooper.java @@ -15,10 +15,15 @@ */ package com.android.launcher3.util; +import android.database.ContentObserver; +import android.net.Uri; +import android.os.Handler; import android.os.Looper; import androidx.annotation.WorkerThread; +import java.util.function.Consumer; + /** * Utility class to define an object which does most of it's processing on a * dedicated background thread. @@ -43,4 +48,16 @@ public abstract class BgObjectWithLooper { */ @WorkerThread protected abstract void onInitialized(Looper looper); + + /** + * Helper method to create a content provider + */ + protected static ContentObserver newContentObserver(Handler handler, Consumer command) { + return new ContentObserver(handler) { + @Override + public void onChange(boolean selfChange, Uri uri) { + command.accept(uri); + } + }; + } } diff --git a/src/com/android/launcher3/util/SimpleBroadcastReceiver.java b/src/com/android/launcher3/util/SimpleBroadcastReceiver.java index 4dfa5ccdeb..0a23506692 100644 --- a/src/com/android/launcher3/util/SimpleBroadcastReceiver.java +++ b/src/com/android/launcher3/util/SimpleBroadcastReceiver.java @@ -52,4 +52,15 @@ public class SimpleBroadcastReceiver extends BroadcastReceiver { } context.registerReceiver(this, filter, flags); } + + /** + * Unregisters the receiver ignoring any errors + */ + public void unregisterReceiverSafely(Context context) { + try { + context.unregisterReceiver(this); + } catch (IllegalArgumentException e) { + // It was probably never registered or already unregistered. Ignore. + } + } } diff --git a/src/com/android/launcher3/views/OptionsPopupView.java b/src/com/android/launcher3/views/OptionsPopupView.java index d30192542f..b3c376fb0d 100644 --- a/src/com/android/launcher3/views/OptionsPopupView.java +++ b/src/com/android/launcher3/views/OptionsPopupView.java @@ -15,9 +15,6 @@ */ package com.android.launcher3.views; -import static com.android.launcher3.Utilities.EXTRA_WALLPAPER_FLAVOR; -import static com.android.launcher3.Utilities.EXTRA_WALLPAPER_LAUNCH_SOURCE; -import static com.android.launcher3.Utilities.EXTRA_WALLPAPER_OFFSET; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.IGNORE; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_SETTINGS_BUTTON_TAP_OR_LONGPRESS; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_WIDGETSTRAY_BUTTON_TAP_OR_LONGPRESS; @@ -51,6 +48,7 @@ import com.android.launcher3.popup.ArrowPopup; import com.android.launcher3.shortcuts.DeepShortcutView; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.shared.TestProtocol; +import com.android.launcher3.util.PackageManagerHelper; import com.android.launcher3.widget.picker.WidgetsFullSheet; import java.util.ArrayList; @@ -62,6 +60,13 @@ import java.util.List; public class OptionsPopupView extends ArrowPopup implements OnClickListener, OnLongClickListener { + // An intent extra to indicate the horizontal scroll of the wallpaper. + private static final String EXTRA_WALLPAPER_OFFSET = "com.android.launcher3.WALLPAPER_OFFSET"; + private static final String EXTRA_WALLPAPER_FLAVOR = "com.android.launcher3.WALLPAPER_FLAVOR"; + // An intent extra to indicate the launch source by launcher. + private static final String EXTRA_WALLPAPER_LAUNCH_SOURCE = + "com.android.wallpaper.LAUNCH_SOURCE"; + private final ArrayMap mItemMap = new ArrayMap<>(); private RectF mTargetRect; private boolean mShouldAddArrow; @@ -180,10 +185,11 @@ public class OptionsPopupView extends ArrowPopup */ public static ArrayList getOptions(Launcher launcher) { ArrayList options = new ArrayList<>(); - int resString = Utilities.existsStyleWallpapers(launcher) ? - R.string.styles_wallpaper_button_text : R.string.wallpaper_button_text; - int resDrawable = Utilities.existsStyleWallpapers(launcher) ? - R.drawable.ic_palette : R.drawable.ic_wallpaper; + boolean styleWallpaperExists = styleWallpapersExists(launcher); + int resString = styleWallpaperExists + ? R.string.styles_wallpaper_button_text : R.string.wallpaper_button_text; + int resDrawable = styleWallpaperExists + ? R.drawable.ic_palette : R.drawable.ic_wallpaper; options.add(new OptionItem(launcher, resString, resDrawable, @@ -251,7 +257,7 @@ public class OptionsPopupView extends ArrowPopup .putExtra(EXTRA_WALLPAPER_OFFSET, launcher.getWorkspace().getWallpaperOffsetForCenterPage()) .putExtra(EXTRA_WALLPAPER_LAUNCH_SOURCE, "app_launched_launcher"); - if (!Utilities.existsStyleWallpapers(launcher)) { + if (!styleWallpapersExists(launcher)) { intent.putExtra(EXTRA_WALLPAPER_FLAVOR, "wallpaper_only"); } else { intent.putExtra(EXTRA_WALLPAPER_FLAVOR, "focus_wallpaper"); @@ -299,4 +305,9 @@ public class OptionsPopupView extends ArrowPopup this.clickListener = clickListener; } } + + private static boolean styleWallpapersExists(Context context) { + return context.getPackageManager().resolveActivity( + PackageManagerHelper.getStyleWallpapersIntent(context), 0) != null; + } } From 50b335fbba7eb70c5a9c594a040490bf41da7c93 Mon Sep 17 00:00:00 2001 From: Pat Manning Date: Thu, 17 Nov 2022 10:54:19 +0000 Subject: [PATCH 247/429] Set grid progress even when task count is 0. Fix: 256090552 Test: manual Change-Id: I2a0ccaf007af71bbe3338453553a7dff59a7d6d2 --- quickstep/src/com/android/quickstep/views/RecentsView.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index ff0c984b6d..940e254502 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -125,7 +125,6 @@ import androidx.annotation.Nullable; import androidx.annotation.UiThread; import androidx.core.graphics.ColorUtils; -import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.BaseActivity; import com.android.launcher3.BaseActivity.MultiWindowModeChangedListener; import com.android.launcher3.DeviceProfile; @@ -2764,13 +2763,9 @@ public abstract class RecentsView Date: Tue, 8 Nov 2022 11:57:59 +0000 Subject: [PATCH 248/429] Fix janky close animation when taskbar is unstashed - Updated startRect for close animation when taskbar is unstashed Fix: 258167450 Test: Use back gesture to close app when taskbarw is stashed or unstashed Change-Id: I56913c2770024bcb47a74c28941bc59f60b4666b --- .../com/android/launcher3/QuickstepTransitionManager.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 1b47939d04..7f72580dba 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -1677,9 +1677,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener mLauncher.getStateManager().moveToRestState(); } + RectF windowTargetBounds = + new RectF(getWindowTargetBounds(appTargets, getRotationChange(appTargets))); Pair pair = createWallpaperOpenAnimations( - appTargets, wallpaperTargets, mFromUnlock, - new RectF(0, 0, mDeviceProfile.widthPx, mDeviceProfile.heightPx), + appTargets, wallpaperTargets, mFromUnlock, windowTargetBounds, QuickStepContract.getWindowCornerRadius(mLauncher)); mLauncher.clearForceInvisibleFlag(INVISIBLE_ALL); From 0a3d67f34fc7632943c741cb28f85888fa7b7132 Mon Sep 17 00:00:00 2001 From: Luca Zuccarini Date: Thu, 17 Nov 2022 13:04:59 +0000 Subject: [PATCH 249/429] Add support for multiple focus listeners to ExtendedEditText. Bug: 249952937 Test: manual, see other bug in the topic Change-Id: I8cc6f525d1a895cc9ee6c6087b51af330d4f25a6 --- .../android/launcher3/ExtendedEditText.java | 30 +++++++++++++++++++ .../search/AllAppsSearchBarController.java | 3 +- src/com/android/launcher3/folder/Folder.java | 8 ++++- 3 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/ExtendedEditText.java b/src/com/android/launcher3/ExtendedEditText.java index 11f2020054..c59f25d85a 100644 --- a/src/com/android/launcher3/ExtendedEditText.java +++ b/src/com/android/launcher3/ExtendedEditText.java @@ -18,6 +18,7 @@ package com.android.launcher3; import static com.android.launcher3.logging.KeyboardStateManager.KeyboardState.SHOW; import android.content.Context; +import android.graphics.Rect; import android.text.TextUtils; import android.util.AttributeSet; import android.view.DragEvent; @@ -27,12 +28,17 @@ import android.widget.EditText; import com.android.launcher3.views.ActivityContext; +import java.util.HashSet; +import java.util.Set; + /** * The edit text that reports back when the back key has been pressed. * Note: AppCompatEditText doesn't fully support #displayCompletions and #onCommitCompletion */ public class ExtendedEditText extends EditText { + private final Set mOnFocusChangeListeners = new HashSet<>(); + private boolean mForceDisableSuggestions = false; /** @@ -129,4 +135,28 @@ public class ExtendedEditText extends EditText { setText(""); } } + + /** + * This method should be preferred to {@link #setOnFocusChangeListener(OnFocusChangeListener)}, + * as it allows for multiple listeners from different sources. + */ + public void addOnFocusChangeListener(OnFocusChangeListener listener) { + mOnFocusChangeListeners.add(listener); + } + + /** + * Removes the given listener from the set of registered focus listeners, or does nothing if it + * wasn't registered in the first place. + */ + public void removeOnFocusChangeListener(OnFocusChangeListener listener) { + mOnFocusChangeListeners.remove(listener); + } + + @Override + protected void onFocusChanged(boolean focused, int direction, Rect previouslyFocusedRect) { + super.onFocusChanged(focused, direction, previouslyFocusedRect); + for (OnFocusChangeListener listener : mOnFocusChangeListeners) { + listener.onFocusChange(this, focused); + } + } } diff --git a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java index 4c461aa5d4..9d085d1c4f 100644 --- a/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java +++ b/src/com/android/launcher3/allapps/search/AllAppsSearchBarController.java @@ -70,7 +70,7 @@ public class AllAppsSearchBarController mInput.addTextChangedListener(this); mInput.setOnEditorActionListener(this); mInput.setOnBackKeyListener(this); - mInput.setOnFocusChangeListener(this); + mInput.addOnFocusChangeListener(this); mSearchAlgorithm = searchAlgorithm; } @@ -160,6 +160,7 @@ public class AllAppsSearchBarController mCallback.clearSearchResult(); mInput.reset(); mQuery = null; + mInput.removeOnFocusChangeListener(this); } /** diff --git a/src/com/android/launcher3/folder/Folder.java b/src/com/android/launcher3/folder/Folder.java index 99822da4a4..94eea3598e 100644 --- a/src/com/android/launcher3/folder/Folder.java +++ b/src/com/android/launcher3/folder/Folder.java @@ -282,7 +282,6 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo mFolderName = findViewById(R.id.folder_name); mFolderName.setTextSize(TypedValue.COMPLEX_UNIT_PX, dp.folderLabelTextSizePx); mFolderName.setOnBackKeyListener(this); - mFolderName.setOnFocusChangeListener(this); mFolderName.setOnEditorActionListener(this); mFolderName.setSelectAllOnFocus(true); mFolderName.setInputType(mFolderName.getInputType() @@ -457,6 +456,13 @@ public class Folder extends AbstractFloatingView implements ClipPathView, DragSo // the folder itself. requestFocus(); super.onAttachedToWindow(); + mFolderName.addOnFocusChangeListener(this); + } + + @Override + protected void onDetachedFromWindow() { + super.onDetachedFromWindow(); + mFolderName.removeOnFocusChangeListener(this); } @Override From 33fa3ffeec5cc6845eebd93cb692345a54a0813c Mon Sep 17 00:00:00 2001 From: Pat Manning Date: Thu, 17 Nov 2022 14:35:51 +0000 Subject: [PATCH 250/429] End live tile when quick settings expands, not just notification shade. This is needed for split-shade and for two-finger pull down of shade which goes directly to quick settings. Fix: 256090552 Fix: 259417195 Test: manual Change-Id: Ief28ae69d4142ddabb4d4b1a9f821abecd81be1e --- .../com/android/quickstep/TouchInteractionService.java | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 450774bee7..def7caad80 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -31,6 +31,7 @@ import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYS import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_UNLOCK_ANIMATION_CONTROLLER; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_TRACING_ENABLED; import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_BACK_ANIMATION; import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_DESKTOP_MODE; @@ -533,9 +534,10 @@ public class TouchInteractionService extends Service } } - boolean wasExpanded = (lastSysUIFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0; - boolean isExpanded = - (systemUiStateFlags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0; + int isShadeExpandedFlag = + SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED | SYSUI_STATE_QUICK_SETTINGS_EXPANDED; + boolean wasExpanded = (lastSysUIFlags & isShadeExpandedFlag) != 0; + boolean isExpanded = (systemUiStateFlags & isShadeExpandedFlag) != 0; if (wasExpanded != isExpanded && isExpanded) { // End live tile when expanding the notification panel for the first time from // overview. From 146701ca3eefa854df4e95b5af8cc140b5433613 Mon Sep 17 00:00:00 2001 From: Stefan Andonian Date: Thu, 10 Nov 2022 23:07:40 +0000 Subject: [PATCH 251/429] Move SharedPreferences code to its own class. Bug: 251502424 Test: Code compiled correctly. Change-Id: Iea0d6ab2999504117546ee0f7adc0c7b8b45c065 --- .../quickstep/TaskOverlayFactoryGo.java | 6 +++--- .../launcher3/model/PredictionUpdateTask.java | 4 ++-- .../model/QuickstepModelDelegate.java | 2 +- .../taskbar/StashedHandleViewController.java | 4 ++-- .../taskbar/TaskbarStashController.java | 3 ++- .../overlay/TaskbarOverlayContext.java | 4 ++-- .../plugins/PluginEnablerImpl.java | 8 ++++---- .../quickstep/TouchInteractionService.java | 3 ++- .../interaction/GestureSandboxActivity.java | 4 ++-- .../logging/SettingsChangeLogger.java | 4 ++-- .../quickstep/util/RecentsOrientedState.java | 4 ++-- .../launcher3/InvariantDeviceProfile.java | 7 ++++--- src/com/android/launcher3/Launcher.java | 4 ++-- .../android/launcher3/LauncherAppState.java | 4 ++-- src/com/android/launcher3/LauncherPrefs.kt | 20 +++++++++++++++++++ .../android/launcher3/LauncherProvider.java | 8 ++++---- .../launcher3/SessionCommitReceiver.java | 2 +- src/com/android/launcher3/Utilities.java | 13 ------------ .../allapps/BaseAllAppsContainerView.java | 3 ++- .../launcher3/allapps/WorkEduCard.java | 4 ++-- .../graphics/GridCustomizationsProvider.java | 2 +- .../launcher3/model/DeviceGridState.java | 6 +++--- .../launcher3/pm/InstallSessionHelper.java | 2 +- .../launcher3/provider/RestoreDbTask.java | 13 ++++++------ .../launcher3/qsb/QsbContainerView.java | 6 +++--- .../SecondaryDisplayLauncher.java | 4 ++-- .../settings/DeveloperOptionsFragment.java | 5 +++-- .../launcher3/settings/SettingsActivity.java | 4 +++- .../launcher3/states/RotationHelper.java | 4 ++-- src/com/android/launcher3/util/Themes.java | 3 ++- 30 files changed, 88 insertions(+), 72 deletions(-) create mode 100644 src/com/android/launcher3/LauncherPrefs.kt diff --git a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java index c997e52dbd..253147d96b 100644 --- a/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java +++ b/go/quickstep/src/com/android/quickstep/TaskOverlayFactoryGo.java @@ -50,8 +50,8 @@ import androidx.annotation.IntDef; import androidx.annotation.VisibleForTesting; import com.android.launcher3.BaseActivity; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; -import com.android.launcher3.Utilities; import com.android.launcher3.views.ArrowTipView; import com.android.quickstep.util.AssistContentRequester; import com.android.quickstep.util.RecentsOrientedState; @@ -124,7 +124,7 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory { AssistContentRequester assistContentRequester) { super(taskThumbnailView); mFactoryContentRequester = assistContentRequester; - mSharedPreferences = Utilities.getPrefs(mApplicationContext); + mSharedPreferences = LauncherPrefs.getPrefs(mApplicationContext); } /** @@ -151,7 +151,7 @@ public final class TaskOverlayFactoryGo extends TaskOverlayFactory { boolean isAllowedByPolicy = mThumbnailView.isRealSnapshot() && !isManagedProfileTask; getActionsView().setCallbacks(new OverlayUICallbacksGoImpl(isAllowedByPolicy, task)); mTaskPackageName = task.key.getPackageName(); - mSharedPreferences = Utilities.getPrefs(mApplicationContext); + mSharedPreferences = LauncherPrefs.getPrefs(mApplicationContext); checkSettings(); if (!mAssistStructurePermitted || !mAssistScreenshotPermitted diff --git a/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java b/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java index bc3253fcfb..e6edeb4dbb 100644 --- a/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java +++ b/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java @@ -30,7 +30,7 @@ import android.os.UserHandle; import androidx.annotation.NonNull; import com.android.launcher3.LauncherAppState; -import com.android.launcher3.Utilities; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.model.BgDataModel.FixedContainerItems; import com.android.launcher3.model.QuickstepModelDelegate.PredictorState; import com.android.launcher3.model.data.AppInfo; @@ -59,7 +59,7 @@ public class PredictionUpdateTask extends BaseModelUpdateTask { Context context = app.getContext(); // TODO: remove this - Utilities.getDevicePrefs(context).edit() + LauncherPrefs.getDevicePrefs(context).edit() .putBoolean(LAST_PREDICTION_ENABLED_STATE, !mTargets.isEmpty()).apply(); Set usersForChangedShortcuts = diff --git a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java index de0b14d4fa..3615c52a7a 100644 --- a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java +++ b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java @@ -18,12 +18,12 @@ package com.android.launcher3.model; import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.text.format.DateUtils.formatElapsedTime; +import static com.android.launcher3.LauncherPrefs.getDevicePrefs; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_PREDICTION; import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_WIDGETS_PREDICTION; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APPLICATION; import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_DEEP_SHORTCUT; -import static com.android.launcher3.Utilities.getDevicePrefs; import static com.android.launcher3.hybridhotseat.HotseatPredictionModel.convertDataModelToAppTargetBundle; import static com.android.launcher3.model.PredictionHelper.getAppTargetFromItemInfo; import static com.android.launcher3.model.PredictionHelper.wrapAppTargetWithItemLocation; diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java index 45d573994d..af46df4225 100644 --- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java @@ -26,8 +26,8 @@ import android.view.View; import android.view.ViewOutlineProvider; import com.android.launcher3.DeviceProfile; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; -import com.android.launcher3.Utilities; import com.android.launcher3.anim.RevealOutlineAnimation; import com.android.launcher3.anim.RoundedRectRevealOutlineProvider; import com.android.launcher3.util.DisplayController; @@ -81,7 +81,7 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT public StashedHandleViewController(TaskbarActivityContext activity, StashedHandleView stashedHandleView) { mActivity = activity; - mPrefs = Utilities.getPrefs(mActivity); + mPrefs = LauncherPrefs.getPrefs(mActivity); mStashedHandleView = stashedHandleView; mTaskbarStashedHandleAlpha = new MultiValueAlpha(mStashedHandleView, NUM_ALPHA_CHANNELS); mTaskbarStashedHandleAlpha.setUpdateVisibility(true); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 06348e2119..6274ec0f0f 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -42,6 +42,7 @@ import androidx.annotation.VisibleForTesting; import com.android.internal.jank.InteractionJankMonitor; import com.android.launcher3.Alarm; import com.android.launcher3.DeviceProfile; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimatorListeners; @@ -187,7 +188,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba public TaskbarStashController(TaskbarActivityContext activity) { mActivity = activity; - mPrefs = Utilities.getPrefs(mActivity); + mPrefs = LauncherPrefs.getPrefs(mActivity); mSystemUiProxy = SystemUiProxy.INSTANCE.get(activity); if (isPhoneMode()) { // DeviceProfile's taskbar vars aren't initialized w/ the flag off diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java index 7e3163ddc5..ebaf60a10f 100644 --- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayContext.java @@ -19,8 +19,8 @@ import android.content.Context; import android.view.View; import com.android.launcher3.DeviceProfile; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; -import com.android.launcher3.Utilities; import com.android.launcher3.allapps.ActivityAllAppsContainerView; import com.android.launcher3.allapps.search.DefaultSearchAdapterProvider; import com.android.launcher3.allapps.search.SearchAdapterProvider; @@ -62,7 +62,7 @@ public class TaskbarOverlayContext extends BaseTaskbarContext { mOverlayController = controllers.taskbarOverlayController; mDragController = new TaskbarDragController(this); mDragController.init(controllers); - mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this)); + mOnboardingPrefs = new OnboardingPrefs<>(this, LauncherPrefs.getPrefs(this)); mDragLayer = new TaskbarOverlayDragLayer(this); TaskbarStashController taskbarStashController = controllers.taskbarStashController; diff --git a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java index 5afeca7e3b..faa900b714 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java +++ b/quickstep/src/com/android/launcher3/uioverrides/plugins/PluginEnablerImpl.java @@ -18,11 +18,11 @@ import android.content.ComponentName; import android.content.Context; import android.content.SharedPreferences; -import com.android.launcher3.Utilities; -import com.android.systemui.shared.plugins.PluginEnabler; - import androidx.preference.PreferenceDataStore; +import com.android.launcher3.LauncherPrefs; +import com.android.systemui.shared.plugins.PluginEnabler; + public class PluginEnablerImpl extends PreferenceDataStore implements PluginEnabler { private static final String PREFIX_PLUGIN_ENABLED = "PLUGIN_ENABLED_"; @@ -30,7 +30,7 @@ public class PluginEnablerImpl extends PreferenceDataStore implements PluginEnab final private SharedPreferences mSharedPrefs; public PluginEnablerImpl(Context context) { - mSharedPrefs = Utilities.getDevicePrefs(context); + mSharedPrefs = LauncherPrefs.getDevicePrefs(context); } @Override diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 450774bee7..f51c9fb119 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -69,6 +69,7 @@ import androidx.annotation.UiThread; import com.android.app.viewcapture.ViewCapture; import com.android.launcher3.BaseDraggingActivity; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; @@ -479,7 +480,7 @@ public class TouchInteractionService extends Service } // Reset home bounce seen on quick step enabled for first time - SharedPreferences sharedPrefs = Utilities.getPrefs(this); + SharedPreferences sharedPrefs = LauncherPrefs.getPrefs(this); if (!sharedPrefs.getBoolean(HAS_ENABLED_QUICKSTEP_ONCE, true)) { sharedPrefs.edit() .putBoolean(HAS_ENABLED_QUICKSTEP_ONCE, true) diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java index bf7023c217..4a701202db 100644 --- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java +++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java @@ -28,8 +28,8 @@ import android.view.Window; import androidx.annotation.NonNull; import androidx.fragment.app.FragmentActivity; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; -import com.android.launcher3.Utilities; import com.android.launcher3.logging.StatsLogManager; import com.android.quickstep.TouchInteractionService.TISBinder; import com.android.quickstep.interaction.TutorialController.TutorialType; @@ -63,7 +63,7 @@ public class GestureSandboxActivity extends FragmentActivity { requestWindowFeature(Window.FEATURE_NO_TITLE); setContentView(R.layout.gesture_tutorial_activity); - mSharedPrefs = Utilities.getPrefs(this); + mSharedPrefs = LauncherPrefs.getPrefs(this); mStatsLogManager = StatsLogManager.newInstance(getApplicationContext()); Bundle args = savedInstanceState == null ? getIntent().getExtras() : savedInstanceState; diff --git a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java index 2ccdfa3b36..5efc45e385 100644 --- a/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java +++ b/quickstep/src/com/android/quickstep/logging/SettingsChangeLogger.java @@ -16,8 +16,8 @@ package com.android.quickstep.logging; -import static com.android.launcher3.Utilities.getDevicePrefs; -import static com.android.launcher3.Utilities.getPrefs; +import static com.android.launcher3.LauncherPrefs.getDevicePrefs; +import static com.android.launcher3.LauncherPrefs.getPrefs; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_SCREEN_SUGGESTIONS_DISABLED; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_HOME_SCREEN_SUGGESTIONS_ENABLED; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_NOTIFICATION_DOT_DISABLED; diff --git a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java index c459f303d1..db8c7f23b9 100644 --- a/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java +++ b/quickstep/src/com/android/quickstep/util/RecentsOrientedState.java @@ -45,7 +45,7 @@ import androidx.annotation.NonNull; import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; -import com.android.launcher3.Utilities; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.testing.shared.TestProtocol; import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.DisplayController; @@ -139,7 +139,7 @@ public class RecentsOrientedState implements public RecentsOrientedState(Context context, BaseActivityInterface sizeStrategy, IntConsumer rotationChangeListener) { mContext = context; - mSharedPrefs = Utilities.getPrefs(context); + mSharedPrefs = LauncherPrefs.getPrefs(context); mOrientationListener = new OrientationEventListener(context) { @Override public void onOrientationChanged(int degrees) { diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 9c5ec38866..87f52106e0 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -200,7 +200,8 @@ public class InvariantDeviceProfile { String gridName = getCurrentGridName(context); String newGridName = initGrid(context, gridName); if (!newGridName.equals(gridName)) { - Utilities.getPrefs(context).edit().putString(KEY_IDP_GRID_NAME, newGridName).apply(); + LauncherPrefs.getPrefs(context).edit().putString(KEY_IDP_GRID_NAME, newGridName) + .apply(); } new DeviceGridState(this).writeToPrefs(context); @@ -308,7 +309,7 @@ public class InvariantDeviceProfile { } public static String getCurrentGridName(Context context) { - return Utilities.getPrefs(context).getString(KEY_IDP_GRID_NAME, null); + return LauncherPrefs.getPrefs(context).getString(KEY_IDP_GRID_NAME, null); } private String initGrid(Context context, String gridName) { @@ -436,7 +437,7 @@ public class InvariantDeviceProfile { public void setCurrentGrid(Context context, String gridName) { Context appContext = context.getApplicationContext(); - Utilities.getPrefs(appContext).edit().putString(KEY_IDP_GRID_NAME, gridName).apply(); + LauncherPrefs.getPrefs(appContext).edit().putString(KEY_IDP_GRID_NAME, gridName).apply(); MAIN_EXECUTOR.execute(() -> onConfigChanged(appContext)); } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 578efdf5db..5cce407d0b 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -473,7 +473,7 @@ public class Launcher extends StatefulActivity InvariantDeviceProfile idp = app.getInvariantDeviceProfile(); initDeviceProfile(idp); idp.addOnChangeListener(this); - mSharedPrefs = Utilities.getPrefs(this); + mSharedPrefs = LauncherPrefs.getPrefs(this); mIconCache = app.getIconCache(); mAccessibilityDelegate = createAccessibilityDelegate(); @@ -1563,7 +1563,7 @@ public class Launcher extends StatefulActivity @Override public SharedPreferences getDevicePrefs() { - return Utilities.getDevicePrefs(this); + return LauncherPrefs.getDevicePrefs(this); } public int getOrientation() { diff --git a/src/com/android/launcher3/LauncherAppState.java b/src/com/android/launcher3/LauncherAppState.java index ea3f723e29..49659364b9 100644 --- a/src/com/android/launcher3/LauncherAppState.java +++ b/src/com/android/launcher3/LauncherAppState.java @@ -18,7 +18,7 @@ package com.android.launcher3; import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED; -import static com.android.launcher3.Utilities.getDevicePrefs; +import static com.android.launcher3.LauncherPrefs.getDevicePrefs; import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; import static com.android.launcher3.util.SettingsCache.NOTIFICATION_BADGING_URI; @@ -117,7 +117,7 @@ public class LauncherAppState implements SafeCloseable { observer, MODEL_EXECUTOR.getHandler()); mOnTerminateCallback.add(iconChangeTracker::close); MODEL_EXECUTOR.execute(observer::verifyIconChanged); - SharedPreferences prefs = Utilities.getPrefs(mContext); + SharedPreferences prefs = LauncherPrefs.getPrefs(mContext); prefs.registerOnSharedPreferenceChangeListener(observer); mOnTerminateCallback.add( () -> prefs.unregisterOnSharedPreferenceChangeListener(observer)); diff --git a/src/com/android/launcher3/LauncherPrefs.kt b/src/com/android/launcher3/LauncherPrefs.kt new file mode 100644 index 0000000000..23ff10ad41 --- /dev/null +++ b/src/com/android/launcher3/LauncherPrefs.kt @@ -0,0 +1,20 @@ +package com.android.launcher3 + +import android.content.Context +import android.content.SharedPreferences + +object LauncherPrefs { + + @JvmStatic + fun getPrefs(context: Context): SharedPreferences { + // Use application context for shared preferences, so that we use a single cached instance + return context.applicationContext.getSharedPreferences( + LauncherFiles.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE) + } + + @JvmStatic + fun getDevicePrefs(context: Context): SharedPreferences { + // Use application context for shared preferences, so that we use a single cached instance + return context.applicationContext.getSharedPreferences( + LauncherFiles.DEVICE_PREFERENCES_KEY, Context.MODE_PRIVATE) + }} \ No newline at end of file diff --git a/src/com/android/launcher3/LauncherProvider.java b/src/com/android/launcher3/LauncherProvider.java index 457e12673b..d002c2b901 100644 --- a/src/com/android/launcher3/LauncherProvider.java +++ b/src/com/android/launcher3/LauncherProvider.java @@ -374,7 +374,7 @@ public class LauncherProvider extends ContentProvider { case LauncherSettings.Settings.METHOD_WAS_EMPTY_DB_CREATED : { Bundle result = new Bundle(); result.putBoolean(LauncherSettings.Settings.EXTRA_VALUE, - Utilities.getPrefs(getContext()).getBoolean( + LauncherPrefs.getPrefs(getContext()).getBoolean( mOpenHelper.getKey(EMPTY_DATABASE_CREATED), false)); return result; } @@ -520,7 +520,7 @@ public class LauncherProvider extends ContentProvider { } private void clearFlagEmptyDbCreated() { - Utilities.getPrefs(getContext()).edit() + LauncherPrefs.getPrefs(getContext()).edit() .remove(mOpenHelper.getKey(EMPTY_DATABASE_CREATED)).commit(); } @@ -532,7 +532,7 @@ public class LauncherProvider extends ContentProvider { * 4) The default configuration for the particular device */ synchronized private void loadDefaultFavoritesIfNecessary() { - SharedPreferences sp = Utilities.getPrefs(getContext()); + SharedPreferences sp = LauncherPrefs.getPrefs(getContext()); if (sp.getBoolean(mOpenHelper.getKey(EMPTY_DATABASE_CREATED), false)) { Log.d(TAG, "loading default workspace"); @@ -738,7 +738,7 @@ public class LauncherProvider extends ContentProvider { */ protected void onEmptyDbCreated() { // Set the flag for empty DB - Utilities.getPrefs(mContext).edit().putBoolean(getKey(EMPTY_DATABASE_CREATED), true) + LauncherPrefs.getPrefs(mContext).edit().putBoolean(getKey(EMPTY_DATABASE_CREATED), true) .commit(); } diff --git a/src/com/android/launcher3/SessionCommitReceiver.java b/src/com/android/launcher3/SessionCommitReceiver.java index bcd4c3f361..50ad2be505 100644 --- a/src/com/android/launcher3/SessionCommitReceiver.java +++ b/src/com/android/launcher3/SessionCommitReceiver.java @@ -98,6 +98,6 @@ public class SessionCommitReceiver extends BroadcastReceiver { } public static boolean isEnabled(Context context) { - return Utilities.getPrefs(context).getBoolean(ADD_ICON_PREFERENCE_KEY, true); + return LauncherPrefs.getPrefs(context).getBoolean(ADD_ICON_PREFERENCE_KEY, true); } } diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index 743e3aed52..ce009a1375 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -27,7 +27,6 @@ import android.app.ActivityManager; import android.app.Person; import android.app.WallpaperManager; import android.content.Context; -import android.content.SharedPreferences; import android.content.pm.LauncherActivityInfo; import android.content.pm.LauncherApps; import android.content.pm.ShortcutInfo; @@ -509,18 +508,6 @@ public final class Utilities { return spanned; } - public static SharedPreferences getPrefs(Context context) { - // Use application context for shared preferences, so that we use a single cached instance - return context.getApplicationContext().getSharedPreferences( - LauncherFiles.SHARED_PREFERENCES_KEY, Context.MODE_PRIVATE); - } - - public static SharedPreferences getDevicePrefs(Context context) { - // Use application context for shared preferences, so that we use a single cached instance - return context.getApplicationContext().getSharedPreferences( - LauncherFiles.DEVICE_PREFERENCES_KEY, Context.MODE_PRIVATE); - } - public static boolean isWallpaperSupported(Context context) { return context.getSystemService(WallpaperManager.class).isWallpaperSupported(); } diff --git a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java index da86d98b5e..8e519c1241 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsContainerView.java @@ -54,6 +54,7 @@ import com.android.launcher3.DragSource; import com.android.launcher3.DropTarget.DragObject; import com.android.launcher3.Insettable; import com.android.launcher3.InsettableFrameLayout; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.allapps.search.SearchAdapterProvider; @@ -148,7 +149,7 @@ public abstract class BaseAllAppsContainerView { } public DeviceGridState(Context context) { - SharedPreferences prefs = Utilities.getPrefs(context); + SharedPreferences prefs = LauncherPrefs.getPrefs(context); mGridSizeString = prefs.getString(KEY_WORKSPACE_SIZE, ""); mNumHotseat = prefs.getInt(KEY_HOTSEAT_COUNT, -1); mDeviceType = prefs.getInt(KEY_DEVICE_TYPE, TYPE_PHONE); @@ -90,7 +90,7 @@ public class DeviceGridState implements Comparable { * Stores the device state to shared preferences */ public void writeToPrefs(Context context) { - Utilities.getPrefs(context).edit() + LauncherPrefs.getPrefs(context).edit() .putString(KEY_WORKSPACE_SIZE, mGridSizeString) .putInt(KEY_HOTSEAT_COUNT, mNumHotseat) .putInt(KEY_DEVICE_TYPE, mDeviceType) diff --git a/src/com/android/launcher3/pm/InstallSessionHelper.java b/src/com/android/launcher3/pm/InstallSessionHelper.java index 16bb868f65..150bca4058 100644 --- a/src/com/android/launcher3/pm/InstallSessionHelper.java +++ b/src/com/android/launcher3/pm/InstallSessionHelper.java @@ -16,7 +16,7 @@ package com.android.launcher3.pm; -import static com.android.launcher3.Utilities.getPrefs; +import static com.android.launcher3.LauncherPrefs.getPrefs; import android.content.Context; import android.content.pm.ApplicationInfo; diff --git a/src/com/android/launcher3/provider/RestoreDbTask.java b/src/com/android/launcher3/provider/RestoreDbTask.java index 95ac7b0ca9..a45e8354b5 100644 --- a/src/com/android/launcher3/provider/RestoreDbTask.java +++ b/src/com/android/launcher3/provider/RestoreDbTask.java @@ -36,6 +36,7 @@ import androidx.annotation.NonNull; import com.android.launcher3.AppWidgetsRestoredReceiver; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.LauncherProvider.DatabaseHelper; import com.android.launcher3.LauncherSettings.Favorites; import com.android.launcher3.Utilities; @@ -86,7 +87,7 @@ public class RestoreDbTask { // Set is pending to false irrespective of the result, so that it doesn't get // executed again. - Utilities.getPrefs(context).edit().remove(RESTORED_DEVICE_TYPE).commit(); + LauncherPrefs.getPrefs(context).edit().remove(RESTORED_DEVICE_TYPE).commit(); idp.reinitializeAfterRestore(context); } @@ -239,7 +240,7 @@ public class RestoreDbTask { } // If restored from a single display backup, remove gaps between screenIds - if (Utilities.getPrefs(context).getInt(RESTORED_DEVICE_TYPE, TYPE_PHONE) + if (LauncherPrefs.getPrefs(context).getInt(RESTORED_DEVICE_TYPE, TYPE_PHONE) != TYPE_MULTI_DISPLAY) { removeScreenIdGaps(db); } @@ -338,7 +339,7 @@ public class RestoreDbTask { } public static boolean isPending(Context context) { - return Utilities.getPrefs(context).contains(RESTORED_DEVICE_TYPE); + return LauncherPrefs.getPrefs(context).contains(RESTORED_DEVICE_TYPE); } /** @@ -346,13 +347,13 @@ public class RestoreDbTask { */ public static void setPending(Context context) { FileLog.d(TAG, "Restore data received through full backup "); - Utilities.getPrefs(context).edit() + LauncherPrefs.getPrefs(context).edit() .putInt(RESTORED_DEVICE_TYPE, new DeviceGridState(context).getDeviceType()) .commit(); } private void restoreAppWidgetIdsIfExists(Context context) { - SharedPreferences prefs = Utilities.getPrefs(context); + SharedPreferences prefs = LauncherPrefs.getPrefs(context); if (prefs.contains(APPWIDGET_OLD_IDS) && prefs.contains(APPWIDGET_IDS)) { LauncherWidgetHolder holder = new LauncherWidgetHolder(context); AppWidgetsRestoredReceiver.restoreAppWidgetIds(context, @@ -370,7 +371,7 @@ public class RestoreDbTask { public static void setRestoredAppWidgetIds(Context context, @NonNull int[] oldIds, @NonNull int[] newIds) { - Utilities.getPrefs(context).edit() + LauncherPrefs.getPrefs(context).edit() .putString(APPWIDGET_OLD_IDS, IntArray.wrap(oldIds).toConcatString()) .putString(APPWIDGET_IDS, IntArray.wrap(newIds).toConcatString()) .commit(); diff --git a/src/com/android/launcher3/qsb/QsbContainerView.java b/src/com/android/launcher3/qsb/QsbContainerView.java index 23ee251772..f2952041f7 100644 --- a/src/com/android/launcher3/qsb/QsbContainerView.java +++ b/src/com/android/launcher3/qsb/QsbContainerView.java @@ -43,8 +43,8 @@ import androidx.annotation.Nullable; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; -import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.graphics.FragmentWithPreview; import com.android.launcher3.widget.util.WidgetSizes; @@ -200,7 +200,7 @@ public class QsbContainerView extends FrameLayout { Context context = getContext(); AppWidgetManager widgetManager = AppWidgetManager.getInstance(context); - int widgetId = Utilities.getPrefs(context).getInt(mKeyWidgetId, -1); + int widgetId = LauncherPrefs.getPrefs(context).getInt(mKeyWidgetId, -1); AppWidgetProviderInfo widgetInfo = widgetManager.getAppWidgetInfo(widgetId); boolean isWidgetBound = (widgetInfo != null) && widgetInfo.provider.equals(mWidgetInfo.provider); @@ -244,7 +244,7 @@ public class QsbContainerView extends FrameLayout { } private void saveWidgetId(int widgetId) { - Utilities.getPrefs(getContext()).edit().putInt(mKeyWidgetId, widgetId).apply(); + LauncherPrefs.getPrefs(getContext()).edit().putInt(mKeyWidgetId, widgetId).apply(); } @Override diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java index 7b32d8b749..dbab700a87 100644 --- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java +++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java @@ -35,9 +35,9 @@ import com.android.launcher3.DropTarget; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherAppState; import com.android.launcher3.LauncherModel; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.LauncherSettings; import com.android.launcher3.R; -import com.android.launcher3.Utilities; import com.android.launcher3.allapps.ActivityAllAppsContainerView; import com.android.launcher3.dragndrop.DragController; import com.android.launcher3.dragndrop.DragOptions; @@ -87,7 +87,7 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity super.onCreate(savedInstanceState); mModel = LauncherAppState.getInstance(this).getModel(); mDragController = new SecondaryDragController(this); - mOnboardingPrefs = new OnboardingPrefs<>(this, Utilities.getPrefs(this)); + mOnboardingPrefs = new OnboardingPrefs<>(this, LauncherPrefs.getPrefs(this)); mSecondaryDisplayPredictions = SecondaryDisplayPredictions.newInstance(this); if (getWindow().getDecorView().isAttachedToWindow()) { initUi(); diff --git a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java index 6057586fca..c81214e67b 100644 --- a/src/com/android/launcher3/settings/DeveloperOptionsFragment.java +++ b/src/com/android/launcher3/settings/DeveloperOptionsFragment.java @@ -59,8 +59,8 @@ import androidx.preference.PreferenceScreen; import androidx.preference.PreferenceViewHolder; import androidx.preference.SwitchPreference; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; -import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.config.FlagTogglerPrefUi; import com.android.launcher3.secondarydisplay.SecondaryDisplayLauncher; @@ -392,7 +392,8 @@ public class DeveloperOptionsFragment extends PreferenceFragmentCompat { onboardingPref.setTitle(title); onboardingPref.setSummary("Tap to reset"); onboardingPref.setOnPreferenceClickListener(preference -> { - SharedPreferences.Editor sharedPrefsEdit = Utilities.getPrefs(getContext()).edit(); + SharedPreferences.Editor sharedPrefsEdit = LauncherPrefs.getPrefs(getContext()) + .edit(); for (String key : keys) { sharedPrefsEdit.remove(key); } diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java index 70956a35ac..4cb4348a5e 100644 --- a/src/com/android/launcher3/settings/SettingsActivity.java +++ b/src/com/android/launcher3/settings/SettingsActivity.java @@ -46,6 +46,7 @@ import androidx.recyclerview.widget.RecyclerView; import com.android.launcher3.DeviceProfile; import com.android.launcher3.InvariantDeviceProfile; import com.android.launcher3.LauncherFiles; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.config.FeatureFlags; @@ -113,7 +114,8 @@ public class SettingsActivity extends FragmentActivity // Display the fragment as the main content. fm.beginTransaction().replace(R.id.content_frame, f).commit(); } - Utilities.getPrefs(getApplicationContext()).registerOnSharedPreferenceChangeListener(this); + LauncherPrefs.getPrefs(getApplicationContext()) + .registerOnSharedPreferenceChangeListener(this); } /** diff --git a/src/com/android/launcher3/states/RotationHelper.java b/src/com/android/launcher3/states/RotationHelper.java index b94ea0707b..642bdcdbb8 100644 --- a/src/com/android/launcher3/states/RotationHelper.java +++ b/src/com/android/launcher3/states/RotationHelper.java @@ -36,7 +36,7 @@ import androidx.annotation.WorkerThread; import com.android.launcher3.BaseActivity; import com.android.launcher3.DeviceProfile; -import com.android.launcher3.Utilities; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.util.DisplayController; /** @@ -104,7 +104,7 @@ public class RotationHelper implements OnSharedPreferenceChangeListener, mIgnoreAutoRotateSettings = ignoreAutoRotateSettings; if (!mIgnoreAutoRotateSettings) { if (mSharedPrefs == null) { - mSharedPrefs = Utilities.getPrefs(mActivity); + mSharedPrefs = LauncherPrefs.getPrefs(mActivity); mSharedPrefs.registerOnSharedPreferenceChangeListener(this); } mHomeRotationEnabled = mSharedPrefs.getBoolean(ALLOW_ROTATION_PREFERENCE_KEY, diff --git a/src/com/android/launcher3/util/Themes.java b/src/com/android/launcher3/util/Themes.java index 1728f4d0d2..585bea93ad 100644 --- a/src/com/android/launcher3/util/Themes.java +++ b/src/com/android/launcher3/util/Themes.java @@ -30,6 +30,7 @@ import android.util.AttributeSet; import android.util.SparseArray; import android.util.TypedValue; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.icons.GraphicsUtils; @@ -73,7 +74,7 @@ public class Themes { * Returns true if workspace icon theming is enabled */ public static boolean isThemedIconEnabled(Context context) { - return Utilities.getPrefs(context).getBoolean(KEY_THEMED_ICONS, false); + return LauncherPrefs.getPrefs(context).getBoolean(KEY_THEMED_ICONS, false); } public static String getDefaultBodyFont(Context context) { From 6386d4b55ba8bab561233bd25c70a3088ef78187 Mon Sep 17 00:00:00 2001 From: Schneider Victor-tulias Date: Tue, 15 Nov 2022 11:57:24 -0800 Subject: [PATCH 252/429] Update All set page subtitle to use the same device name used acrss the SUW Fixes: 252972556 Test: launched the all set page on a large screen, foldable and phone Change-Id: Id6cb86ff85aeb1453f96e707dc4921d23513c406 --- quickstep/res/values/strings.xml | 8 ++++---- .../quickstep/interaction/AllSetActivity.java | 14 ++++++++++---- 2 files changed, 14 insertions(+), 8 deletions(-) diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml index 1a801b5ade..45b8e3f323 100644 --- a/quickstep/res/values/strings.xml +++ b/quickstep/res/values/strings.xml @@ -189,10 +189,10 @@ Swipe up to go Home Tap the home button to go to your home screen - - You\u2019re ready to start using your phone - - You\u2019re ready to start using your tablet + + You\u2019re ready to start using your %1$s + + device System navigation settings diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java index 897b55949c..52f1867c76 100644 --- a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java +++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java @@ -42,6 +42,7 @@ import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.VibrationEffect; import android.os.Vibrator; +import android.text.TextUtils; import android.util.Log; import android.view.View; import android.view.View.AccessibilityDelegate; @@ -79,6 +80,7 @@ public class AllSetActivity extends Activity { "#Intent;action=com.android.settings.SEARCH_RESULT_TRAMPOLINE;S.:settings:fragment_args_key=gesture_system_navigation_input_summary;S.:settings:show_fragment=com.android.settings.gestures.SystemNavigationGestureSettings;end"; private static final String EXTRA_ACCENT_COLOR_DARK_MODE = "suwColorAccentDark"; private static final String EXTRA_ACCENT_COLOR_LIGHT_MODE = "suwColorAccentLight"; + private static final String EXTRA_DEVICE_NAME = "suwDeviceName"; private static final float HINT_BOTTOM_FACTOR = 1 - .94f; @@ -110,7 +112,8 @@ public class AllSetActivity extends Activity { int mode = getResources().getConfiguration().uiMode & Configuration.UI_MODE_NIGHT_MASK; boolean isDarkTheme = mode == Configuration.UI_MODE_NIGHT_YES; - int accentColor = getIntent().getIntExtra( + Intent intent = getIntent(); + int accentColor = intent.getIntExtra( isDarkTheme ? EXTRA_ACCENT_COLOR_DARK_MODE : EXTRA_ACCENT_COLOR_LIGHT_MODE, isDarkTheme ? Color.WHITE : Color.BLACK); @@ -121,10 +124,12 @@ public class AllSetActivity extends Activity { mContentView = findViewById(R.id.content_view); mSwipeUpShift = getResources().getDimension(R.dimen.allset_swipe_up_shift); - DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this); TextView subtitle = findViewById(R.id.subtitle); - subtitle.setText(dp.isTablet - ? R.string.allset_description_tablet : R.string.allset_description); + String suwDeviceName = intent.getStringExtra(EXTRA_DEVICE_NAME); + subtitle.setText(getString( + R.string.allset_description_generic, + !TextUtils.isEmpty(suwDeviceName) + ? suwDeviceName : getString(R.string.default_device_name))); TextView tv = findViewById(R.id.navigation_settings); tv.setTextColor(accentColor); @@ -138,6 +143,7 @@ public class AllSetActivity extends Activity { }); TextView hintTextView = findViewById(R.id.hint); + DeviceProfile dp = InvariantDeviceProfile.INSTANCE.get(this).getDeviceProfile(this); if (!dp.isGestureMode) { hintTextView.setText(R.string.allset_button_hint); } From 589c8d3e2949b7cb7194a0b855255a294b1cbba7 Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Thu, 17 Nov 2022 20:08:05 +0000 Subject: [PATCH 253/429] Add overlay proxy type to ALL and REBIND_SAFE. Test: Manual Fix: 259575422 Change-Id: I121fa0471f96df90e5ff88bbd0aba04556293dc7 --- src/com/android/launcher3/AbstractFloatingView.java | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/AbstractFloatingView.java b/src/com/android/launcher3/AbstractFloatingView.java index 73acd878c7..28d4a9f7a8 100644 --- a/src/com/android/launcher3/AbstractFloatingView.java +++ b/src/com/android/launcher3/AbstractFloatingView.java @@ -102,13 +102,15 @@ public abstract class AbstractFloatingView extends LinearLayout implements Touch | TYPE_OPTIONS_POPUP | TYPE_SNACKBAR | TYPE_LISTENER | TYPE_ALL_APPS_EDU | TYPE_ICON_SURFACE | TYPE_DRAG_DROP_POPUP | TYPE_PIN_WIDGET_FROM_EXTERNAL_POPUP | TYPE_WIDGETS_EDUCATION_DIALOG | TYPE_TASKBAR_EDUCATION_DIALOG | TYPE_TASKBAR_ALL_APPS - | TYPE_OPTIONS_POPUP_DIALOG | TYPE_ADD_TO_HOME_CONFIRMATION; + | TYPE_OPTIONS_POPUP_DIALOG | TYPE_ADD_TO_HOME_CONFIRMATION + | TYPE_TASKBAR_OVERLAY_PROXY; // Type of popups which should be kept open during launcher rebind public static final int TYPE_REBIND_SAFE = TYPE_WIDGETS_FULL_SHEET | TYPE_WIDGETS_BOTTOM_SHEET | TYPE_ON_BOARD_POPUP | TYPE_DISCOVERY_BOUNCE | TYPE_ALL_APPS_EDU | TYPE_ICON_SURFACE | TYPE_WIDGETS_EDUCATION_DIALOG - | TYPE_TASKBAR_EDUCATION_DIALOG | TYPE_TASKBAR_ALL_APPS | TYPE_OPTIONS_POPUP_DIALOG; + | TYPE_TASKBAR_EDUCATION_DIALOG | TYPE_TASKBAR_ALL_APPS | TYPE_OPTIONS_POPUP_DIALOG + | TYPE_TASKBAR_OVERLAY_PROXY; public static final int TYPE_ACCESSIBLE = TYPE_ALL & ~TYPE_DISCOVERY_BOUNCE & ~TYPE_LISTENER & ~TYPE_ALL_APPS_EDU; From a04de842d1ca5aa7d270ef074f8f423da0517797 Mon Sep 17 00:00:00 2001 From: Stefan Andonian Date: Thu, 17 Nov 2022 18:56:09 +0000 Subject: [PATCH 254/429] Fix ConcurrentModificationExceptions during binding. The same lists of extra items stored in BgModelData are also stored in UI components. This is causing ConcurrentModificationExceptions. The solution is to clone these lists or mark them as immutable before storing them in their respective components. Bug: 206918543 Test: Verified that crash no longer occurs after fix. Change-Id: I571a2c451af58137aa7513b372b6a8ecf9bd3ff6 --- .../HotseatPredictionController.java | 2 +- .../launcher3/model/PredictionUpdateTask.java | 9 ++++++--- .../model/QuickstepModelDelegate.java | 3 ++- .../model/WidgetsPredictionUpdateTask.java | 9 ++++++--- .../launcher3/model/BaseModelUpdateTask.java | 3 +-- .../android/launcher3/model/BgDataModel.java | 19 +------------------ 6 files changed, 17 insertions(+), 28 deletions(-) diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java index 05b81671c3..0a2a9b37ba 100644 --- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java +++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java @@ -305,7 +305,7 @@ public class HotseatPredictionController implements DragController.DragListener, * Sets or updates the predicted items only once the hotseat becomes hidden to the user */ private void applyPredictedItems(FixedContainerItems items) { - mPredictedItems = items.items; + mPredictedItems = new ArrayList(items.items); if (mPredictedItems.isEmpty()) { HotseatRestoreHelper.restoreBackup(mLauncher); } diff --git a/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java b/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java index bc3253fcfb..f3748ce281 100644 --- a/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java +++ b/quickstep/src/com/android/launcher3/model/PredictionUpdateTask.java @@ -34,8 +34,10 @@ import com.android.launcher3.Utilities; import com.android.launcher3.model.BgDataModel.FixedContainerItems; import com.android.launcher3.model.QuickstepModelDelegate.PredictorState; import com.android.launcher3.model.data.AppInfo; +import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; +import java.util.ArrayList; import java.util.List; import java.util.Set; import java.util.stream.Collectors; @@ -68,7 +70,7 @@ public class PredictionUpdateTask extends BaseModelUpdateTask { .map(info -> info.user) .collect(Collectors.toSet()); - FixedContainerItems fci = new FixedContainerItems(mPredictorState.containerId); + List items = new ArrayList<>(mTargets.size()); for (AppTarget target : mTargets) { WorkspaceItemInfo itemInfo; ShortcutInfo si = target.getShortcutInfo(); @@ -107,10 +109,11 @@ public class PredictionUpdateTask extends BaseModelUpdateTask { } } - itemInfo.container = fci.containerId; - fci.items.add(itemInfo); + itemInfo.container = mPredictorState.containerId; + items.add(itemInfo); } + FixedContainerItems fci = new FixedContainerItems(mPredictorState.containerId, items); dataModel.extraItems.put(fci.containerId, fci); bindExtraContainerItems(fci); usersForChangedShortcuts.forEach( diff --git a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java index de0b14d4fa..555be95384 100644 --- a/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java +++ b/quickstep/src/com/android/launcher3/model/QuickstepModelDelegate.java @@ -132,7 +132,8 @@ public class QuickstepModelDelegate extends ModelDelegate { // Widgets prediction isn't used frequently. And thus, it is not persisted on disk. mDataModel.extraItems.put(mWidgetsRecommendationState.containerId, - new FixedContainerItems(mWidgetsRecommendationState.containerId)); + new FixedContainerItems(mWidgetsRecommendationState.containerId, + new ArrayList<>())); mActive = true; } diff --git a/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java b/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java index 1beabf1255..6160378767 100644 --- a/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java +++ b/quickstep/src/com/android/launcher3/model/WidgetsPredictionUpdateTask.java @@ -25,6 +25,7 @@ import androidx.annotation.NonNull; import com.android.launcher3.LauncherAppState; import com.android.launcher3.model.BgDataModel.FixedContainerItems; import com.android.launcher3.model.QuickstepModelDelegate.PredictorState; +import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.widget.PendingAddWidgetInfo; @@ -91,10 +92,12 @@ public final class WidgetsPredictionUpdateTask extends BaseModelUpdateTask { if (servicePredictedItems.isEmpty()) { servicePredictedItems.addAll(localFilteredWidgets); } + + List items = servicePredictedItems.stream() + .map(it -> new PendingAddWidgetInfo(it.widgetInfo, CONTAINER_WIDGETS_PREDICTION)) + .collect(Collectors.toList()); FixedContainerItems fixedContainerItems = - new FixedContainerItems(mPredictorState.containerId); - servicePredictedItems.forEach(w -> fixedContainerItems.items.add( - new PendingAddWidgetInfo(w.widgetInfo, CONTAINER_WIDGETS_PREDICTION))); + new FixedContainerItems(mPredictorState.containerId, items); dataModel.extraItems.put(mPredictorState.containerId, fixedContainerItems); bindExtraContainerItems(fixedContainerItems); diff --git a/src/com/android/launcher3/model/BaseModelUpdateTask.java b/src/com/android/launcher3/model/BaseModelUpdateTask.java index 5b6f9f62a5..74a2c5d4b5 100644 --- a/src/com/android/launcher3/model/BaseModelUpdateTask.java +++ b/src/com/android/launcher3/model/BaseModelUpdateTask.java @@ -118,8 +118,7 @@ public abstract class BaseModelUpdateTask implements ModelUpdateTask { } public void bindExtraContainerItems(@NonNull final FixedContainerItems item) { - FixedContainerItems copy = item.clone(); - scheduleCallbackTask(c -> c.bindExtraContainerItems(copy)); + scheduleCallbackTask(c -> c.bindExtraContainerItems(item)); } public void bindDeepShortcuts(@NonNull final BgDataModel dataModel) { diff --git a/src/com/android/launcher3/model/BgDataModel.java b/src/com/android/launcher3/model/BgDataModel.java index de23c4b31f..b0f6e13ae3 100644 --- a/src/com/android/launcher3/model/BgDataModel.java +++ b/src/com/android/launcher3/model/BgDataModel.java @@ -433,26 +433,9 @@ public class BgDataModel { public final int containerId; public final List items; - public FixedContainerItems(int containerId) { - this(containerId, new ArrayList<>()); - } - public FixedContainerItems(int containerId, List items) { this.containerId = containerId; - this.items = items; - } - - @Override - public FixedContainerItems clone() { - return new FixedContainerItems(containerId, new ArrayList<>(items)); - } - - public void setItems(List newItems) { - items.clear(); - newItems.forEach(item -> { - item.container = containerId; - items.add(item); - }); + this.items = Collections.unmodifiableList(items); } } From 61b01e2c2a182fb1658c281c1c02282daf4d7e9f Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Wed, 19 Oct 2022 22:23:56 +0000 Subject: [PATCH 255/429] Add a11y titles for taskbar windows. Test: Manual with Talkback. Fix: 228389333 Change-Id: If30311166fde155d04cf1c9a6865c98d380a93ea --- quickstep/res/layout/all_apps_edu_view.xml | 3 ++- quickstep/res/layout/taskbar_all_apps.xml | 3 ++- quickstep/res/values/strings.xml | 6 ++++++ .../android/launcher3/taskbar/TaskbarActivityContext.java | 4 ++++ 4 files changed, 14 insertions(+), 2 deletions(-) diff --git a/quickstep/res/layout/all_apps_edu_view.xml b/quickstep/res/layout/all_apps_edu_view.xml index e7ef6e699a..0dd4df14e0 100644 --- a/quickstep/res/layout/all_apps_edu_view.xml +++ b/quickstep/res/layout/all_apps_edu_view.xml @@ -3,4 +3,5 @@ xmlns:android="http://schemas.android.com/apk/res/android" android:orientation="vertical" android:layout_width="@dimen/swipe_edu_width" - android:layout_height="@dimen/swipe_edu_max_height"/> + android:layout_height="@dimen/swipe_edu_max_height" + android:accessibilityPaneTitle="@string/taskbar_edu_a11y_title"/> diff --git a/quickstep/res/layout/taskbar_all_apps.xml b/quickstep/res/layout/taskbar_all_apps.xml index 34d4b231b1..a0dce65a45 100644 --- a/quickstep/res/layout/taskbar_all_apps.xml +++ b/quickstep/res/layout/taskbar_all_apps.xml @@ -17,7 +17,8 @@ + android:layout_height="match_parent" + android:accessibilityPaneTitle="@string/all_apps_label"> Rotate screen + + Taskbar education Taskbar education appeared @@ -259,6 +261,10 @@ Notifications Quick Settings + + Taskbar + + Navigation bar Move to top/left diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 27159d36c9..9b4015eb8a 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -332,6 +332,10 @@ public class TaskbarActivityContext extends BaseTaskbarContext { windowLayoutParams.layoutInDisplayCutoutMode = LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS; windowLayoutParams.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION; + windowLayoutParams.accessibilityTitle = getString( + TaskbarManager.isPhoneMode(mDeviceProfile) + ? R.string.taskbar_phone_a11y_title + : R.string.taskbar_a11y_title); return windowLayoutParams; } From 4b4e4a39df9a65226b79c8b9993a34909ececee3 Mon Sep 17 00:00:00 2001 From: Ats Jenk Date: Tue, 15 Nov 2022 10:35:35 -0800 Subject: [PATCH 256/429] Add onTaskMovedToFront to close floating views Fixes a bug with allapps not being closed if the launching activity does not trigger a onTaskStackChange callback. For example this is the case when allapps launches a task in freeform mode. In this case the previous task is still visible and won't be paused. The onTaskStackChange callback is not triggered. Leaving the allapps view visible. Bug: 259264346 Test: enable destop mode, open gmail, open allapps and open chrome, observe allapps view is closed Change-Id: I5e60baa15ebc04b5094a84ed977eb9f3bc73d4a6 --- .../launcher3/taskbar/overlay/TaskbarOverlayController.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java index 6c7bdbfd21..019e5a608f 100644 --- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java +++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java @@ -61,6 +61,11 @@ public final class TaskbarOverlayController { public void onTaskStackChanged() { mProxyView.close(false); } + + @Override + public void onTaskMovedToFront(int taskId) { + mProxyView.close(false); + } }; private DeviceProfile mLauncherDeviceProfile; From ff0f98dd03cc72de55ef27774795e7aac3613027 Mon Sep 17 00:00:00 2001 From: Sihua Ma Date: Thu, 10 Nov 2022 15:12:44 -0800 Subject: [PATCH 257/429] Clear drag views during swipe up animation progress This is to avoid clearing it too lately, at a point where the user starts to see a flicker on the screen. There was already a report of this bug. Filing a bug report on my own because the original one is hard to find. I will mark that as fixed once I find it again. Test: Manual Fix: 259157574 Change-Id: Idc9bb67ebf6fc3ff6d78880f28c46d916a02ab77 --- quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index b09e531fab..a413daa510 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -95,6 +95,7 @@ import com.android.launcher3.R; import com.android.launcher3.Utilities; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.anim.AnimatorPlaybackController; +import com.android.launcher3.dragndrop.DragView; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.logging.StatsLogManager.StatsLogger; import com.android.launcher3.statemanager.BaseState; @@ -1363,6 +1364,10 @@ public abstract class AbsSwipeUpHandler, // If we are transitioning to launcher, then listen for the activity to be restarted while // the transition is in progress if (mGestureState.getEndTarget().isLauncher) { + // This is also called when the launcher is resumed, in order to clear the pending + // widgets that have yet to be configured. + DragView.removeAllViews(mActivity); + TaskStackChangeListeners.getInstance().registerTaskStackListener( mActivityRestartListener); From c06426164f5eec115d8c3ab651c2346f381cd755 Mon Sep 17 00:00:00 2001 From: Ikram Gabiyev Date: Wed, 16 Nov 2022 05:14:22 +0000 Subject: [PATCH 258/429] Stash transient taskbar upon icon drag Transient taskbar needs to be stashed upon dragging the icon from it to create a splitscreen. Bug: 258850827 Test: manually reproduced the steps in the bug Change-Id: I88f2b4b25cb4c12fbe7e646a8ed668921ef24ab9 --- .../android/launcher3/taskbar/TaskbarDragController.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java index 3045eca052..dfff7eed78 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragController.java @@ -305,6 +305,9 @@ public class TaskbarDragController extends DragController im if (mDisallowGlobalDrag) { AbstractFloatingView.closeAllOpenViewsExcept(mActivity, TYPE_TASKBAR_ALL_APPS); } else { + // stash the transient taskbar + mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true); + AbstractFloatingView.closeAllOpenViews(mActivity); } @@ -413,6 +416,9 @@ public class TaskbarDragController extends DragController im if (dragEvent.getResult()) { maybeOnDragEnd(); } else { + // un-stash the transient taskbar in case drag and drop was canceled + mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(false); + // This will take care of calling maybeOnDragEnd() after the animation animateGlobalDragViewToOriginalPosition(btv, dragEvent); } From 2049f3990aea02437ae0fe02bee0447d191dabfd Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Thu, 17 Nov 2022 13:50:56 -0800 Subject: [PATCH 259/429] Use mContext instead of TaskbarActivityContex to enable transient taskbar. Bug: 259586791 Bug: 259337908 Bug: 257549303 Test: TaplTestsTaskbar Change-Id: Ibb0a8e8539946f3a496318a6a9cf4b553693d790 --- .../QuickstepTestInformationHandler.java | 21 ++++--------------- 1 file changed, 4 insertions(+), 17 deletions(-) diff --git a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java index 713b01654c..54e4a0d3f1 100644 --- a/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java +++ b/quickstep/src/com/android/quickstep/QuickstepTestInformationHandler.java @@ -138,15 +138,11 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { return response; case TestProtocol.REQUEST_ENABLE_TRANSIENT_TASKBAR: - runOnTISBinder(tisBinder -> { - enableTransientTaskbar(tisBinder, true); - }); + enableTransientTaskbar(true); return response; case TestProtocol.REQUEST_DISABLE_TRANSIENT_TASKBAR: - runOnTISBinder(tisBinder -> { - enableTransientTaskbar(tisBinder, false); - }); + enableTransientTaskbar(false); return response; } @@ -190,17 +186,8 @@ public class QuickstepTestInformationHandler extends TestInformationHandler { } } - private void enableTransientTaskbar( - TouchInteractionService.TISBinder tisBinder, boolean enable) { - TaskbarActivityContext context = tisBinder.getTaskbarManager().getCurrentActivityContext(); - if (context == null) { - if (TestProtocol.sDebugTracing) { - Log.d(NPE_TRANSIENT_TASKBAR, "enableTransientTaskbar: enable=" + enable, - new Exception()); - } - } else { - DisplayController.INSTANCE.get(context).enableTransientTaskbarForTests(enable); - } + private void enableTransientTaskbar(boolean enable) { + DisplayController.INSTANCE.get(mContext).enableTransientTaskbarForTests(enable); } /** From 02b4711e74d0d328f4fedb747cfd1541f86bdae7 Mon Sep 17 00:00:00 2001 From: Sebastian Franco Date: Thu, 17 Nov 2022 14:23:09 -0800 Subject: [PATCH 260/429] Fix issue where the solution is not updated when the grid is empty Test: Manually move widgets and shortcuts around and the position should match the animation Fix: 259502044 Change-Id: I20a98f9366394c840bb3cd0577de26a181a229ac --- src/com/android/launcher3/Workspace.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/com/android/launcher3/Workspace.java b/src/com/android/launcher3/Workspace.java index 517bbf835a..191d063f34 100644 --- a/src/com/android/launcher3/Workspace.java +++ b/src/com/android/launcher3/Workspace.java @@ -2385,6 +2385,9 @@ public class Workspace extends PagedView ItemInfo item = d.dragInfo; final View child = (mDragInfo == null) ? null : mDragInfo.cell; if (!nearestDropOccupied) { + mDragTargetLayout.performReorder((int) mDragViewVisualCenter[0], + (int) mDragViewVisualCenter[1], minSpanX, minSpanY, item.spanX, item.spanY, + child, mTargetCell, new int[2], CellLayout.MODE_SHOW_REORDER_HINT); mDragTargetLayout.visualizeDropLocation(mTargetCell[0], mTargetCell[1], item.spanX, item.spanY, d); } else if ((mDragMode == DRAG_MODE_NONE || mDragMode == DRAG_MODE_REORDER) From bcd65e85f4720292ba3e30169b9814875fd0a1ab Mon Sep 17 00:00:00 2001 From: Brandon Dayauon Date: Thu, 17 Nov 2022 14:37:40 -0800 Subject: [PATCH 261/429] Fix pause work apps button being higher than normal This issue can be repro'd by typing something in toast box, hightlighting text, share, then back gesturing back to allApps work tab. To fix, we can simply reset the translation when updating the visibility of the button by calling onApplyWindowInsets() in updateVisibility() bug: 259004115 test: Photos Before: https://screenshot.googleplex.com/6JbHbK3rfdXiXM4 after: https://screenshot.googleplex.com/B99SLsFcPYf6jrG Change-Id: I2d44de37666d5342457c6ae14c691eb1804043cd --- src/com/android/launcher3/allapps/WorkModeSwitch.java | 1 + 1 file changed, 1 insertion(+) diff --git a/src/com/android/launcher3/allapps/WorkModeSwitch.java b/src/com/android/launcher3/allapps/WorkModeSwitch.java index 0a938b219f..2272cdc3ef 100644 --- a/src/com/android/launcher3/allapps/WorkModeSwitch.java +++ b/src/com/android/launcher3/allapps/WorkModeSwitch.java @@ -154,6 +154,7 @@ public class WorkModeSwitch extends Button implements Insettable, View.OnClickLi private void updateVisibility() { clearAnimation(); + onApplyWindowInsets(getRootWindowInsets()); if (mWorkEnabled && mOnWorkTab) { setFlag(FLAG_FADE_ONGOING); setVisibility(VISIBLE); From 9390b500a9b4d8021416763b28289b71b7292f26 Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Tue, 27 Sep 2022 18:49:33 +0000 Subject: [PATCH 262/429] Only allow one TaskbarRecentsAnimationsListener at a time. If another animation is created while one is occurring, we should clean up the previous one. Test: Manual Fix: 233868461 Change-Id: Idf0e33ae95cbf19741ee943e450d478b1e18716b --- .../launcher3/taskbar/TaskbarLauncherStateController.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index ea5df87d35..d790b4b663 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -186,6 +186,10 @@ import java.util.StringJoiner; animatorSet.play(stashController.applyStateWithoutStart(duration)); animatorSet.play(applyState(duration, false)); + if (mTaskBarRecentsAnimationListener != null) { + mTaskBarRecentsAnimationListener.endGestureStateOverride( + !mLauncher.isInState(LauncherState.OVERVIEW)); + } mTaskBarRecentsAnimationListener = new TaskBarRecentsAnimationListener(callbacks); callbacks.addListener(mTaskBarRecentsAnimationListener); ((RecentsView) mLauncher.getOverviewPanel()).setTaskLaunchListener(() -> From 825ede3e92a7517bf8a6553ffca3a03c71bb0668 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Fri, 11 Nov 2022 18:43:56 -0800 Subject: [PATCH 263/429] Update test for vertical split * Takes into account taskbar insets, not sure what expected val should be so copied the same logic from code Bug: 219411750 Test: Ran test, passes Change-Id: I6230a3d043e41446c35c9b393abf4a2e0ea891af --- .../src/com/android/quickstep/FullscreenDrawParamsTest.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt index 6d47281f6c..0c96539762 100644 --- a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt +++ b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt @@ -94,8 +94,13 @@ class FullscreenDrawParamsTest : DeviceProfileBaseTest() { params.setProgress(/* fullscreenProgress= */ 1.0f, /* parentScale= */ 1.0f, /* taskViewScale= */ 1.0f, /* previewWidth= */ 0, dp, mPreviewPositionHelper) + // Probably unhelpful, but also unclear how to test otherwise ¯\_(ツ)_/¯ + val fullscreenTaskHeight = (dp.heightPx - dp.taskbarSize) * + (1 - (splitBounds.topTaskPercent + splitBounds.dividerHeightPercent)) + val canvasScreenRatio = canvasHeight / fullscreenTaskHeight + val expectedBottomHint = dp.taskbarSize * canvasScreenRatio assertThat(params.mCurrentDrawnInsets.bottom) - .isWithin(1f).of((dp.taskbarSize * TASK_SCALE)) + .isWithin(1f).of(expectedBottomHint) } @Test From 424c7f43930220aa26a524fddb27d3e5be9e8de1 Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Fri, 18 Nov 2022 01:09:18 +0000 Subject: [PATCH 264/429] Still launch disabled item if we can't handle its click. See where ItemClickHandler#handleDisabledItemClick returns false for context. If we do not honor this return value, the framework will not show a dialog in response to attempting launch the item. Fix: 258232619 Test: Manual Change-Id: Ie3b112eea17caf0a84defb331133bda9f3add5b6 --- .../com/android/launcher3/taskbar/TaskbarActivityContext.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 27159d36c9..3ee9051e32 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -758,9 +758,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { }); } else if (tag instanceof WorkspaceItemInfo) { WorkspaceItemInfo info = (WorkspaceItemInfo) tag; - if (info.isDisabled()) { - ItemClickHandler.handleDisabledItemClicked(info, this); - } else { + if (!info.isDisabled() || !ItemClickHandler.handleDisabledItemClicked(info, this)) { TaskbarUIController taskbarUIController = mControllers.uiController; RecentsView recents = taskbarUIController.getRecentsView(); if (recents != null From 21d4253c01366187e184c2b867ae5882d0168d17 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Thu, 17 Nov 2022 18:09:31 -0800 Subject: [PATCH 265/429] Fix home/overview threshold. Fixes: 258836670 Test: Enable I06e16d78c179b7c3281f423ed8c7dd6cfc42229a to visually show thresholds on screen Swipe up to overview where taskbar not showing and also with taskbar already showing Change-Id: Ie7487a5f869c0718d9ee08209dee8331a01d5989 --- .../android/quickstep/AbsSwipeUpHandler.java | 34 ++++++++++++++----- .../OtherActivityInputConsumer.java | 18 ++++------ 2 files changed, 33 insertions(+), 19 deletions(-) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index b09e531fab..28e783f327 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -317,6 +317,9 @@ public abstract class AbsSwipeUpHandler, private final int mTaskbarAppWindowThreshold; private final int mTaskbarCatchUpThreshold; private boolean mTaskbarAlreadyOpen; + private final boolean mIsTransientTaskbar; + // Only used when mIsTransientTaskbar is true. + private boolean mHasReachedHomeOverviewThreshold; public AbsSwipeUpHandler(Context context, RecentsAnimationDeviceState deviceState, TaskAnimationManager taskAnimationManager, GestureState gestureState, @@ -343,6 +346,7 @@ public abstract class AbsSwipeUpHandler, mTaskbarAppWindowThreshold = res .getDimensionPixelSize(R.dimen.taskbar_app_window_threshold); mTaskbarCatchUpThreshold = res.getDimensionPixelSize(R.dimen.taskbar_catch_up_threshold); + mIsTransientTaskbar = DisplayController.isTransientTaskbar(mActivity); mQuickSwitchScaleScrollThreshold = res .getDimension(R.dimen.quick_switch_scaling_scroll_threshold); @@ -819,7 +823,7 @@ public abstract class AbsSwipeUpHandler, @UiThread @Override public void updateFinalShift() { - final boolean passed = mCurrentShift.value >= MIN_PROGRESS_FOR_OVERVIEW; + final boolean passed = hasReachedHomeOverviewThreshold(); if (passed != mPassedOverviewThreshold) { mPassedOverviewThreshold = passed; if (mDeviceState.isTwoButtonNavMode() && !mGestureState.isHandlingAtomicEvent()) { @@ -1145,16 +1149,16 @@ public abstract class AbsSwipeUpHandler, } if (!mDeviceState.isFullyGesturalNavMode()) { - return (!hasReachedOverviewThreshold() && willGoToNewTask) ? NEW_TASK : RECENTS; + return (!hasReachedHomeOverviewThreshold() && willGoToNewTask) ? NEW_TASK : RECENTS; } return willGoToNewTask ? NEW_TASK : HOME; } private GestureEndTarget calculateEndTargetForNonFling(PointF velocity) { final boolean isScrollingToNewTask = isScrollingToNewTask(); - final boolean reachedOverviewThreshold = hasReachedOverviewThreshold(); + final boolean reachedHomeOverviewThreshold = hasReachedHomeOverviewThreshold(); if (!mDeviceState.isFullyGesturalNavMode()) { - return reachedOverviewThreshold && mGestureStarted + return reachedHomeOverviewThreshold && mGestureStarted ? RECENTS : (isScrollingToNewTask ? NEW_TASK : LAST_TASK); } @@ -1170,7 +1174,7 @@ public abstract class AbsSwipeUpHandler, return RECENTS; } else if (isScrollingToNewTask) { return NEW_TASK; - } else if (reachedOverviewThreshold) { + } else if (reachedHomeOverviewThreshold) { return HOME; } return LAST_TASK; @@ -1189,8 +1193,22 @@ public abstract class AbsSwipeUpHandler, return runningTaskIndex >= 0 && mRecentsView.getNextPage() != runningTaskIndex; } - private boolean hasReachedOverviewThreshold() { - return getTaskbarProgress() > MIN_PROGRESS_FOR_OVERVIEW; + /** + * Sets whether the current swipe has reached the threshold where if user lets go they would + * go to either the home state or overview state. + */ + public void setHasReachedHomeOverviewThreshold(boolean hasReachedHomeOverviewThreshold) { + mHasReachedHomeOverviewThreshold = hasReachedHomeOverviewThreshold; + } + + /** + * Returns true iff swipe has reached the overview threshold. + */ + public boolean hasReachedHomeOverviewThreshold() { + if (mIsTransientTaskbar) { + return mHasReachedHomeOverviewThreshold; + } + return mCurrentShift.value > MIN_PROGRESS_FOR_OVERVIEW; } @UiThread @@ -2267,7 +2285,7 @@ public abstract class AbsSwipeUpHandler, * There is also a catch up period so that the window can start moving 1:1 with the swipe. */ private float getTaskbarProgress() { - if (!DisplayController.isTransientTaskbar(mContext)) { + if (!mIsTransientTaskbar) { return mCurrentShift.value; } diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index b3d3c3dbf6..503644a606 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -36,7 +36,6 @@ import android.annotation.TargetApi; import android.content.Context; import android.content.ContextWrapper; import android.content.Intent; -import android.content.res.Resources; import android.graphics.PointF; import android.os.Build; import android.util.Log; @@ -151,10 +150,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mHandlerFactory = handlerFactory; mActivityInterface = mGestureState.getActivityInterface(); - Resources res = base.getResources(); - mTaskbarHomeOverviewThreshold = res - .getDimensionPixelSize(R.dimen.taskbar_home_overview_threshold); - mMotionPauseDetector = new MotionPauseDetector(base, false, mNavBarPosition.isLeftEdge() || mNavBarPosition.isRightEdge() ? MotionEvent.AXIS_X : MotionEvent.AXIS_Y); @@ -168,6 +163,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC TaskbarUIController controller = mActivityInterface.getTaskbarController(); mTaskbarAlreadyOpen = controller != null && !controller.isTaskbarStashed(); mIsTransientTaskbar = DisplayController.isTransientTaskbar(base); + mTaskbarHomeOverviewThreshold = base.getResources() + .getDimensionPixelSize(R.dimen.taskbar_home_overview_threshold); boolean continuingPreviousGesture = mTaskAnimationManager.isRecentsAnimationRunning(); mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget; @@ -340,13 +337,12 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } if (mDeviceState.isFullyGesturalNavMode()) { - float minDisplacement = mMotionPauseMinDisplacement; - - if (mIsTransientTaskbar && !mTaskbarAlreadyOpen) { - minDisplacement += mTaskbarHomeOverviewThreshold; + boolean minSwipeMet = upDist >= mMotionPauseMinDisplacement; + if (mIsTransientTaskbar) { + minSwipeMet = upDist >= mTaskbarHomeOverviewThreshold; + mInteractionHandler.setHasReachedHomeOverviewThreshold(minSwipeMet); } - - mMotionPauseDetector.setDisallowPause(upDist < minDisplacement + mMotionPauseDetector.setDisallowPause(!minSwipeMet || isLikelyToStartNewTask); mMotionPauseDetector.addPosition(ev); mInteractionHandler.setIsLikelyToStartNewTask(isLikelyToStartNewTask); From ae0d7ef78210dc0428153c12b2a6a36c993d20cc Mon Sep 17 00:00:00 2001 From: Thales Lima Date: Wed, 16 Nov 2022 15:53:43 +0000 Subject: [PATCH 266/429] Increase icon size to be closer to spec Also change paddings because spaces changed Bug: 258463609 Test: DeviceProfileDumpTest Change-Id: Iaee433ea3fb5ef633ad428699ce230317021b170 --- res/xml/paddings_handhelds.xml | 33 +++++++++++++++++++ src/com/android/launcher3/DeviceProfile.java | 10 +++--- .../launcher3/InvariantDeviceProfile.java | 14 +++----- .../launcher3/DeviceProfileBaseTest.kt | 32 ++---------------- 4 files changed, 46 insertions(+), 43 deletions(-) create mode 100644 res/xml/paddings_handhelds.xml diff --git a/res/xml/paddings_handhelds.xml b/res/xml/paddings_handhelds.xml new file mode 100644 index 0000000000..b9549a6133 --- /dev/null +++ b/res/xml/paddings_handhelds.xml @@ -0,0 +1,33 @@ + + + + + + + + + + + + \ No newline at end of file diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 3cb3461f8f..92530eaae6 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -498,10 +498,11 @@ public class DeviceProfile { extraSpace = updateAvailableDimensions(res); // Now that we have all of the variables calculated, we can tune certain sizes. - if (isScalableGrid && inv.devicePaddings != null) { + if (isScalableGrid && inv.devicePaddingId != INVALID_RESOURCE_HANDLE) { // Paddings were created assuming no scaling, so we first unscale the extra space. int unscaledExtraSpace = (int) (extraSpace / cellScaleToFit); - DevicePadding padding = inv.devicePaddings.getDevicePadding(unscaledExtraSpace); + DevicePaddings devicePaddings = new DevicePaddings(context, inv.devicePaddingId); + DevicePadding padding = devicePaddings.getDevicePadding(unscaledExtraSpace); int paddingWorkspaceTop = padding.getWorkspaceTopPadding(unscaledExtraSpace); int paddingWorkspaceBottom = padding.getWorkspaceBottomPadding(unscaledExtraSpace); @@ -1565,10 +1566,11 @@ public class DeviceProfile { writer.println(prefix + pxToDpStr("extraSpace", extraSpace)); writer.println(prefix + pxToDpStr("unscaled extraSpace", extraSpace / iconScale)); - if (inv.devicePaddings != null) { + if (inv.devicePaddingId != INVALID_RESOURCE_HANDLE) { int unscaledExtraSpace = (int) (extraSpace / iconScale); + DevicePaddings devicePaddings = new DevicePaddings(context, inv.devicePaddingId); writer.println(prefix + pxToDpStr("maxEmptySpace", - inv.devicePaddings.getDevicePadding(unscaledExtraSpace).getMaxEmptySpacePx())); + devicePaddings.getDevicePadding(unscaledExtraSpace).getMaxEmptySpacePx())); } writer.println(prefix + pxToDpStr("workspaceTopPadding", workspaceTopPadding)); writer.println(prefix + pxToDpStr("workspaceBottomPadding", workspaceBottomPadding)); diff --git a/src/com/android/launcher3/InvariantDeviceProfile.java b/src/com/android/launcher3/InvariantDeviceProfile.java index 9c5ec38866..ef06ff12e3 100644 --- a/src/com/android/launcher3/InvariantDeviceProfile.java +++ b/src/com/android/launcher3/InvariantDeviceProfile.java @@ -47,9 +47,9 @@ import android.view.Display; import androidx.annotation.DimenRes; import androidx.annotation.IntDef; -import androidx.annotation.Nullable; import androidx.annotation.StyleRes; import androidx.annotation.VisibleForTesting; +import androidx.annotation.XmlRes; import androidx.core.content.res.ResourcesCompat; import com.android.launcher3.icons.DotRenderer; @@ -172,7 +172,8 @@ public class InvariantDeviceProfile { * Do not query directly. see {@link DeviceProfile#isScalableGrid}. */ protected boolean isScalable; - public int devicePaddingId; + @XmlRes + public int devicePaddingId = INVALID_RESOURCE_HANDLE; public String dbFile; public int defaultLayoutId; @@ -184,9 +185,6 @@ public class InvariantDeviceProfile { */ public List supportedProfiles = Collections.EMPTY_LIST; - @Nullable - public DevicePaddings devicePaddings; - public Point defaultWallpaperSize; public Rect defaultWidgetPadding; @@ -384,10 +382,6 @@ public class InvariantDeviceProfile { allAppsIconSize = displayOption.allAppsIconSizes; allAppsIconTextSize = displayOption.allAppsIconTextSizes; - if (devicePaddingId != 0) { - devicePaddings = new DevicePaddings(context, devicePaddingId); - } - inlineQsb = closestProfile.inlineQsb; // If the partner customization apk contains any grid overrides, apply them @@ -825,7 +819,7 @@ public class InvariantDeviceProfile { isScalable = a.getBoolean( R.styleable.GridDisplayOption_isScalable, false); devicePaddingId = a.getResourceId( - R.styleable.GridDisplayOption_devicePaddingId, 0); + R.styleable.GridDisplayOption_devicePaddingId, INVALID_RESOURCE_HANDLE); int deviceCategory = a.getInt(R.styleable.GridDisplayOption_deviceCategory, DEVICE_CATEGORY_ALL); diff --git a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt index fe30fdc81d..4e166ce418 100644 --- a/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt +++ b/tests/src/com/android/launcher3/DeviceProfileBaseTest.kt @@ -16,7 +16,6 @@ package com.android.launcher3 import android.content.Context -import android.graphics.Point import android.graphics.PointF import android.graphics.Rect import android.util.SparseArray @@ -26,7 +25,6 @@ import com.android.launcher3.util.DisplayController.Info import com.android.launcher3.util.WindowBounds import org.junit.Before import org.mockito.ArgumentMatchers.any -import org.mockito.ArgumentMatchers.anyInt import org.mockito.Mockito.mock import java.io.PrintWriter import java.io.StringWriter @@ -42,9 +40,6 @@ abstract class DeviceProfileBaseTest { protected var transposeLayoutWithOrientation: Boolean = false protected var useTwoPanels: Boolean = false protected var isGestureMode: Boolean = true - protected var devicePaddingsMock: DevicePaddings = mock(DevicePaddings::class.java) - protected var staticdevicePaddingsMock: DevicePaddings.DevicePadding = - mock(DevicePaddings.DevicePadding::class.java) @Before fun setUp() { @@ -83,11 +78,6 @@ abstract class DeviceProfileBaseTest { whenever(info.isTablet(any())).thenReturn(false) whenever(info.getDensityDpi()).thenReturn(420) whenever(info.smallestSizeDp(any())).thenReturn(411f) - whenever(devicePaddingsMock.getDevicePadding(anyInt())).thenReturn(staticdevicePaddingsMock) - whenever(staticdevicePaddingsMock.getWorkspaceTopPadding(anyInt())).thenReturn(95) - whenever(staticdevicePaddingsMock.getWorkspaceBottomPadding(anyInt())).thenReturn(116) - whenever(staticdevicePaddingsMock.maxEmptySpacePx) - .thenReturn(if (isVerticalBar) if (isGestureMode) 131 else 184 else 315) this.isGestureMode = isGestureMode transposeLayoutWithOrientation = true @@ -152,7 +142,7 @@ abstract class DeviceProfileBaseTest { inlineQsb = BooleanArray(4) { false } - devicePaddings = devicePaddingsMock + devicePaddingId = R.xml.paddings_handhelds } } @@ -169,13 +159,6 @@ abstract class DeviceProfileBaseTest { whenever(info.isTablet(any())).thenReturn(true) whenever(info.getDensityDpi()).thenReturn(320) whenever(info.smallestSizeDp(any())).thenReturn(800f) - whenever(devicePaddingsMock.getDevicePadding(anyInt())).thenReturn(staticdevicePaddingsMock) - whenever(staticdevicePaddingsMock.getWorkspaceTopPadding(anyInt())) - .thenReturn(if (isLandscape) 32 else 159) - whenever(staticdevicePaddingsMock.getWorkspaceBottomPadding(anyInt())) - .thenReturn(if (isLandscape) 72 else 203) - whenever(staticdevicePaddingsMock.maxEmptySpacePx).thenReturn(if (isLandscape) 200 else 19998) - this.isGestureMode = isGestureMode useTwoPanels = false @@ -246,7 +229,7 @@ abstract class DeviceProfileBaseTest { false ) - devicePaddings = devicePaddingsMock + devicePaddingId = R.xml.paddings_handhelds } } @@ -263,15 +246,6 @@ abstract class DeviceProfileBaseTest { whenever(info.isTablet(any())).thenReturn(true) whenever(info.getDensityDpi()).thenReturn(420) whenever(info.smallestSizeDp(any())).thenReturn(700f) - whenever(devicePaddingsMock.getDevicePadding(anyInt())).thenReturn(staticdevicePaddingsMock) - - val topPadding = if (isLandscape) 18 else 89 - val bottomPadding = if (isLandscape) 39 else 146 - val maxEmptySpace = if (isLandscape) 131 else 236 - whenever(staticdevicePaddingsMock.getWorkspaceTopPadding(anyInt())).thenReturn(topPadding) - whenever(staticdevicePaddingsMock.getWorkspaceBottomPadding(anyInt())) - .thenReturn(bottomPadding) - whenever(staticdevicePaddingsMock.maxEmptySpacePx).thenReturn(maxEmptySpace) this.isGestureMode = isGestureMode useTwoPanels = true @@ -342,7 +316,7 @@ abstract class DeviceProfileBaseTest { false ) - devicePaddings = devicePaddingsMock + devicePaddingId = R.xml.paddings_handhelds } } From e04a87870953f6572386cb0409735f2262d37db7 Mon Sep 17 00:00:00 2001 From: Schneider Victor-tulias Date: Fri, 18 Nov 2022 18:43:37 +0000 Subject: [PATCH 267/429] Revert "Add debug logs to help identify when setRecentsAttachedToAppWindow will not animate properly." This reverts commit a0be92c830bff7303c5fa3cdb460d01d10ec03e4. Reason for revert: Bug fixed and logs are too verbose Test: ran launcher and checked logs Fixes: 244593270 Change-Id: Ia67ba96b0b2146308f9cad1df884144edf2ab186 --- .../android/quickstep/AbsSwipeUpHandler.java | 75 +++++-------------- .../quickstep/BaseActivityInterface.java | 35 ++------- 2 files changed, 25 insertions(+), 85 deletions(-) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index b09e531fab..3a646b8ffe 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -287,7 +287,7 @@ public abstract class AbsSwipeUpHandler, private AnimatorControllerWithResistance mLauncherTransitionController; private boolean mHasEndedLauncherTransition; - private AnimationFactory mAnimationFactory = (t, s) -> { }; + private AnimationFactory mAnimationFactory = (t) -> { }; private boolean mWasLauncherAlreadyVisible; @@ -531,9 +531,7 @@ public abstract class AbsSwipeUpHandler, Runnable initAnimFactory = () -> { mAnimationFactory = mActivityInterface.prepareRecentsUI(mDeviceState, mWasLauncherAlreadyVisible, this::onAnimatorPlaybackControllerCreated); - maybeUpdateRecentsAttachedState( - false /* animate */, - new ActiveGestureLog.CompoundString("on Launcher start (animate=false)")); + maybeUpdateRecentsAttachedState(false /* animate */); if (mGestureState.getEndTarget() != null) { // Update the end target in case the gesture ended before we init. mAnimationFactory.setEndTarget(mGestureState.getEndTarget()); @@ -638,8 +636,7 @@ public abstract class AbsSwipeUpHandler, } private void initializeLauncherAnimationController() { - buildAnimationController(new ActiveGestureLog.CompoundString( - "initializing launcher animation controller")); + buildAnimationController(); Object traceToken = TraceHelper.INSTANCE.beginSection("logToggleRecents", TraceHelper.FLAG_IGNORE_BINDERS); @@ -658,11 +655,7 @@ public abstract class AbsSwipeUpHandler, @Override public void onMotionPauseDetected() { mHasMotionEverBeenPaused = true; - maybeUpdateRecentsAttachedState( - true/* animate */, - true/* moveFocusedTask */, - new ActiveGestureLog.CompoundString( - "motion pause detected (animate=true)")); + maybeUpdateRecentsAttachedState(true/* animate */, true/* moveFocusedTask */); Optional.ofNullable(mActivityInterface.getTaskbarController()) .ifPresent(TaskbarUIController::startTranslationSpring); performHapticFeedback(); @@ -675,13 +668,12 @@ public abstract class AbsSwipeUpHandler, }; } - private void maybeUpdateRecentsAttachedState(ActiveGestureLog.CompoundString reason) { - maybeUpdateRecentsAttachedState(true /* animate */, reason.append(" (animate=true)")); + private void maybeUpdateRecentsAttachedState() { + maybeUpdateRecentsAttachedState(true /* animate */); } - private void maybeUpdateRecentsAttachedState( - boolean animate, ActiveGestureLog.CompoundString reason) { - maybeUpdateRecentsAttachedState(animate, false /* moveFocusedTask */, reason); + private void maybeUpdateRecentsAttachedState(boolean animate) { + maybeUpdateRecentsAttachedState(animate, false /* moveFocusedTask */); } /** @@ -693,8 +685,7 @@ public abstract class AbsSwipeUpHandler, * @param animate whether to animate when attaching RecentsView * @param moveFocusedTask whether to move focused task to front when attaching */ - private void maybeUpdateRecentsAttachedState( - boolean animate, boolean moveFocusedTask, ActiveGestureLog.CompoundString reason) { + private void maybeUpdateRecentsAttachedState(boolean animate, boolean moveFocusedTask) { if (!mDeviceState.isFullyGesturalNavMode() || mRecentsView == null) { return; } @@ -704,25 +695,14 @@ public abstract class AbsSwipeUpHandler, final boolean recentsAttachedToAppWindow; if (mGestureState.getEndTarget() != null) { recentsAttachedToAppWindow = mGestureState.getEndTarget().recentsAttachedToAppWindow; - reason.append("; gesture state end target != null (attached=") - .append(Boolean.toString(recentsAttachedToAppWindow)) - .append(")"); } else if (mContinuingLastGesture && mRecentsView.getRunningTaskIndex() != mRecentsView.getNextPage()) { recentsAttachedToAppWindow = true; - reason.append("; continuing last gesture (attached=true)"); } else if (runningTaskTarget != null && isNotInRecents(runningTaskTarget)) { // The window is going away so make sure recents is always visible in this case. recentsAttachedToAppWindow = true; - reason.append("; make sure recents is always visible (attached=true)"); } else { recentsAttachedToAppWindow = mHasMotionEverBeenPaused || mIsLikelyToStartNewTask; - reason.append(mHasMotionEverBeenPaused - ? "; motion has been paused" - : "; gesture is likely to start a new task") - .append(" (attached=") - .append(Boolean.toString(recentsAttachedToAppWindow)) - .append(")"); } if (moveFocusedTask && !mAnimationFactory.hasRecentsEverAttachedToAppWindow() && recentsAttachedToAppWindow) { @@ -730,8 +710,7 @@ public abstract class AbsSwipeUpHandler, // TaskView jumping to new position as we move the tasks. mRecentsView.moveFocusedTaskToFront(); } - mAnimationFactory.setRecentsAttachedToAppWindow( - recentsAttachedToAppWindow, animate, reason); + mAnimationFactory.setRecentsAttachedToAppWindow(recentsAttachedToAppWindow, animate); // Reapply window transform throughout the attach animation, as the animation affects how // much the window is bound by overscroll (vs moving freely). @@ -751,29 +730,22 @@ public abstract class AbsSwipeUpHandler, } public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { - setIsLikelyToStartNewTask( - isLikelyToStartNewTask, - true /* animate */, - new ActiveGestureLog.CompoundString( - "setting gesture likely to start (animate=true)")); + setIsLikelyToStartNewTask(isLikelyToStartNewTask, true /* animate */); } - private void setIsLikelyToStartNewTask( - boolean isLikelyToStartNewTask, - boolean animate, - ActiveGestureLog.CompoundString reason) { + private void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask, boolean animate) { if (mIsLikelyToStartNewTask != isLikelyToStartNewTask) { mIsLikelyToStartNewTask = isLikelyToStartNewTask; - maybeUpdateRecentsAttachedState(animate, reason); + maybeUpdateRecentsAttachedState(animate); } } - private void buildAnimationController(ActiveGestureLog.CompoundString reason) { + private void buildAnimationController() { if (!canCreateNewOrUpdateExistingLauncherTransitionController()) { return; } initTransitionEndpoints(mActivity.getDeviceProfile()); - mAnimationFactory.createActivityInterface(mTransitionDragLength, reason); + mAnimationFactory.createActivityInterface(mTransitionDragLength); } /** @@ -788,7 +760,7 @@ public abstract class AbsSwipeUpHandler, @Override public WindowInsets onApplyWindowInsets(View view, WindowInsets windowInsets) { WindowInsets result = view.onApplyWindowInsets(windowInsets); - buildAnimationController(new ActiveGestureLog.CompoundString("applying window insets")); + buildAnimationController(); // Reapply the current shift to ensure it takes new insets into account, e.g. when long // pressing to stash taskbar without moving the finger. updateFinalShift(); @@ -962,10 +934,7 @@ public abstract class AbsSwipeUpHandler, }); } notifyGestureStartedAsync(); - setIsLikelyToStartNewTask( - isLikelyToStartNewTask, - false /* animate */, - new ActiveGestureLog.CompoundString("on gesture started (animate=false)")); + setIsLikelyToStartNewTask(isLikelyToStartNewTask, false /* animate */); mStateCallback.setStateOnUiThread(STATE_GESTURE_STARTED); mGestureStarted = true; } @@ -1046,8 +1015,7 @@ public abstract class AbsSwipeUpHandler, private void onSettledOnEndTarget() { // Fast-finish the attaching animation if it's still running. - maybeUpdateRecentsAttachedState(false, new ActiveGestureLog.CompoundString( - "on settled on end target (animate=false)")); + maybeUpdateRecentsAttachedState(false); final GestureEndTarget endTarget = mGestureState.getEndTarget(); // Wait until the given View (if supplied) draws before resuming the last task. View postResumeLastTask = mActivityInterface.onSettledOnEndTarget(endTarget); @@ -1357,8 +1325,7 @@ public abstract class AbsSwipeUpHandler, @UiThread private void animateToProgressInternal(float start, float end, long duration, Interpolator interpolator, GestureEndTarget target, PointF velocityPxPerMs) { - maybeUpdateRecentsAttachedState(new ActiveGestureLog.CompoundString( - "animate to progress internal")); + maybeUpdateRecentsAttachedState(); // If we are transitioning to launcher, then listen for the activity to be restarted while // the transition is in progress @@ -1677,9 +1644,7 @@ public abstract class AbsSwipeUpHandler, mRecentsView.post(mRecentsView::resetTaskVisuals); } // Make sure recents is in its final state - maybeUpdateRecentsAttachedState( - false, new ActiveGestureLog.CompoundString( - "setting up window animation (animate=false)")); + maybeUpdateRecentsAttachedState(false); mActivityInterface.onSwipeUpToHomeComplete(mDeviceState); } }); diff --git a/quickstep/src/com/android/quickstep/BaseActivityInterface.java b/quickstep/src/com/android/quickstep/BaseActivityInterface.java index a62232620d..fc8f02e6b6 100644 --- a/quickstep/src/com/android/quickstep/BaseActivityInterface.java +++ b/quickstep/src/com/android/quickstep/BaseActivityInterface.java @@ -60,7 +60,6 @@ import com.android.launcher3.touch.PagedOrientationHandler; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.NavigationMode; import com.android.launcher3.views.ScrimView; -import com.android.quickstep.util.ActiveGestureLog; import com.android.quickstep.util.ActivityInitListener; import com.android.quickstep.util.AnimatorControllerWithResistance; import com.android.quickstep.views.RecentsView; @@ -402,16 +401,14 @@ public abstract class BaseActivityInterface diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml index bc4209ee0f..6064af5373 100644 --- a/quickstep/res/values-am/strings.xml +++ b/quickstep/res/values-am/strings.xml @@ -79,8 +79,10 @@ "ወደ መነሻ ለመሄድ በጣት ወደ ላይ ማንሸራተት" - "ስልክዎን መጠቀም ለመጀመር ዝግጁ ነዎት" - "ጡባዊዎን መጠቀም ለመጀመር ዝግጁ ነዎት" + + + + "የስርዓት አሰሳ ቅንብሮች" "አጋራ" "ቅጽበታዊ ገጽ እይታ" @@ -94,6 +96,8 @@ "ይቅር" "ዝለል" "ማያ ገጹን አዙር" + + "የተግባር አሞሌ ትምህርት ይታያል" "የተግባር አሞሌ ትምህርት ተዘግቷል" "መተግበሪያዎችን ለመቀየር የተግባር አሞሌውን ይጠቀሙ" @@ -110,6 +114,10 @@ "የቅርብ ጊዜዎቹ" "ማሳወቂያዎች" "ፈጣን ቅንብሮች" + + + + "ወደ ላይ/ግራ ይውሰዱ" "ወደ ታች/ቀኝ ይውሰዱ" diff --git a/quickstep/res/values-ar/strings.xml b/quickstep/res/values-ar/strings.xml index b461230676..fe7645300d 100644 --- a/quickstep/res/values-ar/strings.xml +++ b/quickstep/res/values-ar/strings.xml @@ -77,23 +77,25 @@ "الدليل التوجيهي %1$d من إجمالي %2$d" "اكتملت عملية الإعداد" "مرِّر سريعًا للأعلى للانتقال إلى الشاشة الرئيسية." - + "انقر على زر الشاشة الرئيسية للانتقال إلى الشاشة الرئيسية." + + + - "يمكنك الآن بدء استخدام هاتفك." - "يمكنك الآن بدء استخدام جهازك اللوحي." "إعدادات التنقّل داخل النظام" "مشاركة" "لقطة شاشة" "تقسيم" "انقر على تطبيق آخر لاستخدام وضع تقسيم الشاشة." - - + "اختَر تطبيقًا آخر لاستخدام وضع تقسيم الشاشة." "لا يسمح التطبيق أو لا تسمح مؤسستك بهذا الإجراء." "هل تريد تخطي الدليل التوجيهي؟" "يمكنك العثور على هذا الدليل التوجيهي لاحقًا في التطبيق \"%1$s\"" "إلغاء" "التخطي" "تدوير الشاشة" + + "ظهرت لوحة تعليم استخدام شريط المهام." "تم إغلاق لوحة تعليم استخدام شريط المهام." "يمكنك استخدام شريط المهام للتبديل بين التطبيقات." @@ -110,6 +112,10 @@ "الأحدث" "الإشعارات" "إعدادات سريعة" + + + + "الانتقال إلى يمين الشاشة أو أعلاها" "الانتقال إلى يسار الشاشة أو أسفلها" diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml index 3bae94e157..51c3eefe1c 100644 --- a/quickstep/res/values-as/strings.xml +++ b/quickstep/res/values-as/strings.xml @@ -79,8 +79,10 @@ "গৃহ স্ক্ৰীনলৈ যাবলৈ ওপৰলৈ ছোৱাইপ কৰক" - "আপুনি আপোনাৰ ফ’নটো ব্যৱহাৰ কৰিবলৈ সাজু" - "আপুনি আপোনাৰ টেবলেটটো ব্যৱহাৰ কৰিবলৈ সাজু" + + + + "ছিষ্টেম নেভিগেশ্বনৰ ছেটিং" "শ্বেয়াৰ কৰক" "স্ক্ৰীনশ্বট" @@ -94,6 +96,8 @@ "বাতিল কৰক" "এৰি যাওক" "স্ক্ৰীনখন ঘূৰাওক" + + "টাস্কবাৰৰ শিক্ষাৰ পেনেলটো প্ৰদর্শিত হৈছে" "টাস্কবাৰৰ শিক্ষাৰ পেনেলটো বন্ধ হৈছে" "এপ্‌ সলনি কৰিবলৈ টাস্কবাৰডাল ব্যৱহাৰ কৰক" @@ -110,6 +114,10 @@ "শেহতীয়া" "জাননী" "ক্ষিপ্ৰ ছেটিং" + + + + "ওপৰৰ বাঁওফাললৈ নিয়ক" "তলৰ সোঁফাললৈ নিয়ক" diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml index ff01f86f2b..06cc80e610 100644 --- a/quickstep/res/values-az/strings.xml +++ b/quickstep/res/values-az/strings.xml @@ -77,23 +77,25 @@ "Dərslik %1$d/%2$d" "Hər şey hazırdır!" "Əsas səhifəyə keçmək üçün yuxarı çəkin" - + "Əsas ekranınıza keçmək üçün əsas düyməyə toxunun" + + + - "Telefondan istifadəyə başlamağa hazırsınız" - "Planşetdən istifadəyə başlamağa hazırsınız" "Sistem naviqasiya ayarları" "Paylaşın" "Skrinşot" "Ayırın" "Bölmə ekranını istifadə etmək üçün başqa tətbiqə toxunun" - - + "Bölünmüş ekrandan istifadə üçün başqa tətbiq seçin" "Bu əməliyyata tətbiq və ya təşkilatınız tərəfindən icazə verilmir" "Naviqasiya dərsliyi ötürülsün?" "Bunu sonra %1$s tətbiqində tapa bilərsiniz" "Ləğv edin" "Ötürün" "Ekranı fırladın" + + "Tapşırıq panelindəki təlim bölməsi görünür" "Tapşırıq panelindəki təlim bölməsi bağlanıb" "Tətbiqləri keçirmək üçün tapşırıq panelindən istifadə edin" @@ -110,6 +112,10 @@ "Sonuncular" "Bildirişlər" "Sürətli Ayarlar" + + + + "Yuxarı/sola köçürün" "Aşağı/sağa köçürün" diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml index 881237cf42..307d2b2966 100644 --- a/quickstep/res/values-b+sr+Latn/strings.xml +++ b/quickstep/res/values-b+sr+Latn/strings.xml @@ -77,23 +77,25 @@ "Vodič %1$d/%2$d" "Gotovo!" "Prevucite nagore da biste otvorili početni ekran" - + "Dodirnite dugme Početak da bisti išli na početni ekran" + + + - "Spremni ste da počnete da koristite telefon" - "Spremni ste da počnete da koristite tablet" "Podešavanja kretanja kroz sistem" "Deli" "Snimak ekrana" "Podeli" "Dodirnite drugu aplikaciju za podeljeni ekran" - - + "Odaberite drugu aplikaciju za podeljeni ekran" "Aplikacija ili organizacija ne dozvoljavaju ovu radnju" "Želite da preskočite vodič za kretanje?" "Možete da pronađete ovo kasnije u aplikaciji %1$s" "Otkaži" "Preskoči" "Rotirajte ekran" + + "Edukativno okno iz trake zadataka se pojavilo" "Edukativno okno iz trake zadataka je zatvoreno" "Koristite traku zadataka da biste menjali aplikacije" @@ -110,6 +112,10 @@ "Nedavno" "Obaveštenja" "Brza podešavanja" + + + + "Premesti gore levo" "Premesti dole desno" diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml index db280f2d95..a3b55568da 100644 --- a/quickstep/res/values-be/strings.xml +++ b/quickstep/res/values-be/strings.xml @@ -77,23 +77,25 @@ "Дапаможнік %1$d/%2$d" "Гатова!" "Каб перайсці на галоўны экран, правядзіце пальцам уверх" - + "Каб перайсці на галоўны экран, націсніце кнопку галоўнага экрана" + + + - "Вы можаце пачаць карыстанне тэлефонам" - "Вы можаце пачаць карыстанне планшэтам" "Налады навігацыі ў сістэме" "Абагуліць" "Здымак экрана" "Падзелены экран" "Для падзеленага экрана націсніце на іншую праграму" - - + "Каб падзяліць экран, выберыце іншую праграму" "Гэта дзеянне не дазволена праграмай ці вашай арганізацыяй" "Прапусціць дапаможнік па навігацыі?" "Знайсці дапаможнік можна ў праграме \"%1$s\"" "Скасаваць" "Прапусціць" "Павярнуць экран" + + "З\'явілася панэль навучання на панэлі задач" "Панэль навучання на панэлі задач закрыта" "Выкарыстоўвайце панэль задач для пераключэння праграм" @@ -110,6 +112,10 @@ "Нядаўнія" "Апавяшчэнні" "Хуткія налады" + + + + "Перамясціць уверх/улева" "Перамясціць уніз/управа" diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml index 375fa6a8b4..1d44effe4a 100644 --- a/quickstep/res/values-bg/strings.xml +++ b/quickstep/res/values-bg/strings.xml @@ -79,8 +79,10 @@ "Прекарайте пръст нагоре, за да отворите началния екран" - "Можете да започнете да използвате телефона си" - "Можете да започнете да използвате таблета си" + + + + "Настройки за навигиране в системата" "Споделяне" "Екранна снимка" @@ -94,6 +96,8 @@ "Отказ" "Пропускане" "Завъртане на екрана" + + "Показва се урокът за лентата на задачите" "Урокът за лентата на задачите бе затворен" "Използвайте лентата на задачите за превключване между прил." @@ -110,6 +114,10 @@ "Скорошни" "Известия" "Бързи настройки" + + + + "Преместване горе/вляво" "Преместване долу/вдясно" diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml index 24d2f1a2f5..992599e388 100644 --- a/quickstep/res/values-bn/strings.xml +++ b/quickstep/res/values-bn/strings.xml @@ -77,23 +77,25 @@ "টিউটোরিয়াল %1$d/%2$d" "সব রেডি!" "হোম স্ক্রিনে যেতে উপরের দিকে সোয়াইপ করুন" - + "আপনার হোম স্ক্রিনে যাওয়ার জন্য হোম বোতামে ট্যাপ করুন" + + + - "এবারে আপনি ফোন ব্যবহার করতে পারবেন" - "এবারে আপনি ট্যাবলেট ব্যবহার করতে পারবেন" "সিস্টেম নেভিগেশন সেটিংস" "শেয়ার করুন" "স্ক্রিনশট নিন" "স্প্লিট" "স্প্লিটস্ক্রিন ব্যবহার করতে অন্য অ্যাপে ট্যাপ করুন" - - + "স্প্লিট স্ক্রিন ব্যবহার করতে অন্য অ্যাপ বেছে নিন" "এই অ্যাপ বা আপনার প্রতিষ্ঠান এই অ্যাকশনটি পারফর্ম করার অনুমতি দেয়নি" "নেভিগেশন টিউটোরিয়াল এড়িয়ে যেতে চান?" "আপনি %1$s অ্যাপে পরে এটি খুঁজে পাবেন" "বাতিল করুন" "এড়িয়ে যান" "স্ক্রিন ঘোরান" + + "টাস্কবার এডুকেশন দেখানো হয়েছে" "টাস্কবার এডুকেশন বন্ধ করা আছে" "অ্যাপ পাল্টানোর জন্য টাস্কবার ব্যবহার করুন" @@ -110,6 +112,10 @@ "সম্প্রতি" "বিজ্ঞপ্তি" "দ্রুত সেটিংস" + + + + "উপরে/বাঁদিকে সরান" "নিচে/ডানদিকে সরান" diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml index 208e457ef6..18803ded38 100644 --- a/quickstep/res/values-bs/strings.xml +++ b/quickstep/res/values-bs/strings.xml @@ -77,23 +77,25 @@ "Vodič %1$d/%2$d" "Sve je spremno!" "Prevucite prema gore da odete na početni ekran" - + "Dodirnite dugme za početni ekran da odete napočetni ekran" + + + - "Sve je spremno da počnete koristiti telefon" - "Sve je spremno da počnete koristiti tablet" "Postavke navigiranja sistemom" "Dijeli" "Snimak ekrana" "Podijeli" "Dodirnite drugu apl. da koristite podijeljeni ekran" - - + "Odaberite drugu apl. da koristite podijeljeni ekran" "Ovu radnju ne dozvoljava aplikacija ili vaša organizacija" "Preskočiti vodič za navigiranje?" "Možete ga pronaći kasnije u aplikaciji %1$s" "Otkaži" "Preskoči" "Rotiranje ekrana" + + "Edukacija o programskoj traci je prikazana" "Edukacija o programskoj traci je zatvorena" "Koristite programsku traku da promijenite aplikacije" @@ -110,6 +112,10 @@ "Nedavno" "Obavještenja" "Brze postavke" + + + + "Premjesti gore lijevo" "Premjesti dolje desno" diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml index 2eb14927a3..86e16a1432 100644 --- a/quickstep/res/values-ca/strings.xml +++ b/quickstep/res/values-ca/strings.xml @@ -79,8 +79,10 @@ "Llisca cap amunt per anar a la pàgina d\'inici" - "Ja pots començar a utilitzar el telèfon" - "Ja pots començar a utilitzar la tauleta" + + + + "Configuració de navegació del sistema" "Comparteix" "Captura de pantalla" @@ -94,6 +96,8 @@ "Cancel·la" "Omet" "Gira la pantalla" + + "Ha aparegut el tauler educatiu de la barra de tasques" "S\'ha tancat el tauler educatiu de la barra de tasques" "Utilitza la barra de tasques per canviar d\'aplicació" @@ -110,6 +114,10 @@ "Recents" "Notificacions" "Config. ràpida" + + + + "Mou a la part superior o a l\'esquerra" "Mou a la part inferior o a la dreta" diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml index e337de0cab..15f209aace 100644 --- a/quickstep/res/values-cs/strings.xml +++ b/quickstep/res/values-cs/strings.xml @@ -77,23 +77,25 @@ "Výukový program %1$d/%2$d" "Hotovo!" "Přejetím nahoru se vrátíte na plochu" - + "Klepnutím na tlačítko plochy se vrátíte na plochu" + + + - "Jste připraveni začít používat telefon" - "Jste připraveni začít používat tablet" "Nastavení navigace v systému" "Sdílet" "Snímek obrazovky" "Rozdělit" "Klepnutím na jinou aplikaci rozdělíte obrazovku" - - + "Vyberte podporovanou aplikaci" "Aplikace nebo organizace zakazuje tuto akci" "Přeskočit výukový program k navigaci?" "Program později najdete v aplikaci %1$s" "Zrušit" "Přeskočit" "Otočit obrazovku" + + "Zobrazila se výuka k hlavnímu panelu" "Výuka k hlavnímu panelu byla zavřena" "Aplikace lze přepínat pomocí hlavního panelu" @@ -110,6 +112,10 @@ "Poslední" "Oznámení" "Rychlé nastavení" + + + + "Přesunout doleva nahoru" "Přesunout doprava dolů" diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml index 2c9591a21c..42f7d613db 100644 --- a/quickstep/res/values-da/strings.xml +++ b/quickstep/res/values-da/strings.xml @@ -77,23 +77,25 @@ "Selvstudie %1$d/%2$d" "Alt er parat!" "Stryg opad for at gå til startsiden" - + "Tryk på knappen Hjem for at gå til din startskærm" + + + - "Du er klar til at bruge din telefon" - "Du er klar til at bruge din tablet" "Indstillinger for systemnavigation" "Del" "Screenshot" "Opdel" "Tryk på en anden app for at bruge opdelt skærm" - - + "Vælg en anden app for at bruge opdelt skærm" "Appen eller din organisation tillader ikke denne handling" "Vil du springe selvstudiet for navigation over?" "Du kan finde dette senere i appen %1$s" "Annuller" "Spring over" "Roter skærm" + + "Vejledningen om proceslinjen blev åbnet" "Vejledningen om proceslinjen blev lukket" "Skift mellem apps ved hjælp af proceslinjen" @@ -110,6 +112,10 @@ "Seneste" "Notifikationer" "Kvikmenu" + + + + "Flyt til toppen eller venstre side" "Flyt til bunden eller højre side" diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml index d0b898384f..11d7f3dd5f 100644 --- a/quickstep/res/values-de/strings.xml +++ b/quickstep/res/values-de/strings.xml @@ -79,8 +79,10 @@ "Nach oben wischen, um den Startbildschirm aufzurufen" - "Du kannst dein Smartphone jetzt verwenden" - "Du kannst dein Tablet jetzt verwenden" + + + + "Einstellungen der Systemsteuerung" "Teilen" "Screenshot" @@ -94,6 +96,8 @@ "Abbrechen" "Überspringen" "Bildschirm drehen" + + "Anleitung für Taskleiste eingeblendet" "Anleitung für Taskleiste geschlossen" "Über die Taskleiste zwischen Apps wechseln" @@ -110,6 +114,10 @@ "Letzte Apps" "Benachrichtigungen" "Schnelleinstellungen" + + + + "Nach oben / Nach links verschieben" "Nach unten / Nach rechts verschieben" diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml index a2ab151c5b..95e0a26ec0 100644 --- a/quickstep/res/values-el/strings.xml +++ b/quickstep/res/values-el/strings.xml @@ -77,23 +77,25 @@ "Οδηγός %1$d/%2$d" "Όλα έτοιμα!" "Σύρετε προς τα πάνω για μετάβαση στην αρχική οθόνη." - + "Πατήστε το κουμπί αρχικής οθόνης για να μεταβείτε στην αρχική οθόνη" + + + - "Είστε έτοιμοι να ξεκινήσετε να χρησιμοποιείτε το τηλέφωνό σας" - "Είστε έτοιμοι να ξεκινήσετε να χρησιμοποιείτε το tablet." "Ρυθμίσεις πλοήγησης συστήματος" "Κοινοποίηση" "Στιγμιότυπο οθόνης" "Διαχωρισμός" "Πατήστε άλλη εφαρμογή για χρήση διαχωρισμού οθόνης" - - + "Επιλέξτε άλλη εφαρμογή για διαχωρισμό οθόνης" "Αυτή η ενέργεια δεν επιτρέπεται από την εφαρμογή ή τον οργανισμό σας." "Παράβλεψη οδηγού πλοήγησης;" "Βρείτε τον αργότερα στην εφαρμογή %1$s" "Ακύρωση" "Παράβλεψη" "Περιστροφή οθόνης" + + "Η εκπαίδευση για τη γραμμή εργασιών εμφανίστηκε" "Η εκπαίδευση για τη γραμμή εργασιών έκλεισε" "Χρήση της γραμμής εργασιών για εναλλαγή εφαρμογών" @@ -110,6 +112,10 @@ "Πρόσφατα" "Ειδοποιήσεις" "Γρήγορες ρυθμ." + + + + "Μετακίνηση επάνω/αριστερά" "Μετακίνηση κάτω/δεξιά" diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml index 19b0c3c65c..30fca73df8 100644 --- a/quickstep/res/values-en-rAU/strings.xml +++ b/quickstep/res/values-en-rAU/strings.xml @@ -77,23 +77,25 @@ "Tutorial %1$d/%2$d" "Ready!" "Swipe up to go home" - + "Tap the home button to go to your home screen" + + + - "You’re ready to start using your phone" - "You’re ready to start using your tablet" "System navigation settings" "Share" "Screenshot" "Split" "Tap another app to use split-screen" - - + "Choose another app to use split screen" "This action isn\'t allowed by the app or your organisation" "Skip navigation tutorial?" "You can find this later in the %1$s app" "Cancel" "Skip" "Rotate screen" + + "Taskbar education appeared" "Taskbar education closed" "Use the taskbar to switch apps" @@ -110,6 +112,10 @@ "Recents" "Notifications" "Quick Settings" + + + + "Move to top/left" "Move to bottom/right" diff --git a/quickstep/res/values-en-rCA/strings.xml b/quickstep/res/values-en-rCA/strings.xml index f6498c3be2..d8cd13d8ae 100644 --- a/quickstep/res/values-en-rCA/strings.xml +++ b/quickstep/res/values-en-rCA/strings.xml @@ -77,23 +77,25 @@ "Tutorial %1$d/%2$d" "All set!" "Swipe up to go Home" - + "Tap the home button to go to your home screen" + + + - "You’re ready to start using your phone" - "You’re ready to start using your tablet" "System navigation settings" "Share" "Screenshot" "Split" "Tap another app to use splitscreen" - - + "Choose another app to use split screen" "This action isn\'t allowed by the app or your organization" "Skip navigation tutorial?" "You can find this later in the %1$s app" "Cancel" "Skip" "Rotate screen" + + "Taskbar education appeared" "Taskbar education closed" "Use the taskbar to switch apps" @@ -110,6 +112,10 @@ "Recents" "Notifications" "Quick Settings" + + + + "Move to top/left" "Move to bottom/right" diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml index 19b0c3c65c..30fca73df8 100644 --- a/quickstep/res/values-en-rGB/strings.xml +++ b/quickstep/res/values-en-rGB/strings.xml @@ -77,23 +77,25 @@ "Tutorial %1$d/%2$d" "Ready!" "Swipe up to go home" - + "Tap the home button to go to your home screen" + + + - "You’re ready to start using your phone" - "You’re ready to start using your tablet" "System navigation settings" "Share" "Screenshot" "Split" "Tap another app to use split-screen" - - + "Choose another app to use split screen" "This action isn\'t allowed by the app or your organisation" "Skip navigation tutorial?" "You can find this later in the %1$s app" "Cancel" "Skip" "Rotate screen" + + "Taskbar education appeared" "Taskbar education closed" "Use the taskbar to switch apps" @@ -110,6 +112,10 @@ "Recents" "Notifications" "Quick Settings" + + + + "Move to top/left" "Move to bottom/right" diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml index 19b0c3c65c..30fca73df8 100644 --- a/quickstep/res/values-en-rIN/strings.xml +++ b/quickstep/res/values-en-rIN/strings.xml @@ -77,23 +77,25 @@ "Tutorial %1$d/%2$d" "Ready!" "Swipe up to go home" - + "Tap the home button to go to your home screen" + + + - "You’re ready to start using your phone" - "You’re ready to start using your tablet" "System navigation settings" "Share" "Screenshot" "Split" "Tap another app to use split-screen" - - + "Choose another app to use split screen" "This action isn\'t allowed by the app or your organisation" "Skip navigation tutorial?" "You can find this later in the %1$s app" "Cancel" "Skip" "Rotate screen" + + "Taskbar education appeared" "Taskbar education closed" "Use the taskbar to switch apps" @@ -110,6 +112,10 @@ "Recents" "Notifications" "Quick Settings" + + + + "Move to top/left" "Move to bottom/right" diff --git a/quickstep/res/values-en-rXC/strings.xml b/quickstep/res/values-en-rXC/strings.xml index 55b99c862c..8394c46ddf 100644 --- a/quickstep/res/values-en-rXC/strings.xml +++ b/quickstep/res/values-en-rXC/strings.xml @@ -77,23 +77,25 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‎‎‎‏‏‏‎‎‎‎‏‎‏‎‏‏‎‏‏‎‏‎‏‏‎‎‏‎‏‎‏‏‎‏‏‏‎‎‎‎‎‏‎‎‏‏‎‎‏‎‏‏‏‏‏‎‏‎‎‎‎Tutorial ‎‏‎‎‏‏‎%1$d‎‏‎‎‏‏‏‎/‎‏‎‎‏‏‎%2$d‎‏‎‎‏‏‏‎‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‎‏‎‎‎‎‎‎‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎All set!‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‎‎‎‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎Swipe up to go Home‎‏‎‎‏‎" - + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎Tap the home button to go to your home screen‎‏‎‎‏‎" + + + - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‎‎‎‏‎‎‎‎‎‏‏‎‏‏‏‏‎‏‏‎‎‏‎‎‏‎‎‎‏‏‏‎‏‎‏‎‎‎‏‎‎‏‎‏‏‎‏‏‎‏‎‎‏‎‏‎‎‎You’re ready to start using your phone‎‏‎‎‏‎" - "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‏‏‏‏‏‏‎‎‎‏‎‎‎‎‎‏‏‎‏‎‎‏‏‎‎‎‎‏‏‏‏‎‎‎‎‏‏‏‏‏‎‎‏‏‏‏‎You’re ready to start using your tablet‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‏‏‎""‎‏‎‎‏‏‏‎System navigation settings‎‏‎‎‏‏‎""‎‏‎‎‏‏‏‎‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‏‏‎‏‏‎‎‎‎‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎Share‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‎Screenshot‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‏‎‎‎‏‏‏‎‏‏‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‏‏‏‏‎‎‏‎‎‏‎‎‎‏‎‎‏‏‏‏‎‎‏‎‏‏‎‏‎‏‎‎‎Split‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‏‎‏‏‎‎‎‎‎‎‎‎‎‏‏‎‎‎‏‎‎‏‎‏‏‎‎‏‏‎‏‎‏‎‎‎‏‎‏‎‏‏‎‏‏‎‏‎‎‎‏‏‎‎‎‎‎Tap another app to use splitscreen‎‏‎‎‏‎" - - + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‎‏‏‎‎‎‎‎‏‎‎‏‏‏‎‎‎‎‏‎‎‏‎‎‏‎‏‎‎‎‎‎‏‏‏‏‎‎‎‎‎‎‎‏‎‏‎‏‏‏‎‏‏‎‎‏‎‎Choose another app to use split screen‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‎‏‏‏‏‎‎‏‎‏‏‏‏‏‏‎‎‎‏‏‎‎‎‎‏‎‎‏‏‎‎‏‏‏‎‏‎‏‏‏‎‎‎‎‎‎‎‎‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‎This action isn\'t allowed by the app or your organization‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‏‏‏‎‏‎‎‏‏‎‏‏‎‏‏‏‎‎‎‎‎‎‎‏‏‏‎‎‏‏‎‏‏‎‏‏‎‎‎‎‎‏‎‎‏‏‎‎‏‎‎‏‏‏‎‏‎‎Skip navigation tutorial?‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‏‏‏‎‎‎‏‏‎‎‏‏‏‎‎‏‏‎‏‎‏‏‎‏‏‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‏‏‏‏‎‏‎‎‏‏‏‎‎You can find this later in the ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎ app‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‎‏‏‎‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‎‎Cancel‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‎‎‎‎Skip‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‏‏‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎Rotate screen‎‏‎‎‏‎" + + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‎‏‏‎‎‏‎Taskbar education appeared‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‏‏‏‎‎Taskbar education closed‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‎‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎Use the taskbar to switch apps‎‏‎‎‏‎" @@ -110,6 +112,10 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‎‏‏‏‎‎Recents‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‎‎‏‏‎‎Notifications‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‎‎‏‏‎‎‎‎‏‏‏‏‎Quick Settings‎‏‎‎‏‎" + + + + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‏‏‏‎Move to top/left‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎‏‎‎‎‏‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎Move to bottom/right‎‏‎‎‏‎" diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml index 7bb40e9ebf..1ab25e65f4 100644 --- a/quickstep/res/values-es-rUS/strings.xml +++ b/quickstep/res/values-es-rUS/strings.xml @@ -77,23 +77,25 @@ "Instructivo %1$d/%2$d" "Todo listo" "Desliza el dedo hacia arriba para ir a la pantalla principal" - + "Presiona el botón de inicio para ir a la pantalla principal" + + + - "Ya puedes empezar a usar tu teléfono" - "Ya puedes empezar a usar tu tablet" "Configuración de navegación del sistema" "Compartir" "Captura de pantalla" "Pantalla dividida" "Presiona otra app para usar la pantalla dividida" - - + "Elige otra app para usar la pantalla dividida" "La app o tu organización no permiten realizar esta acción" "¿Omitir el instructivo de navegación?" "Puedes encontrarlo en la app de %1$s" "Cancelar" "Omitir" "Girar pantalla" + + "Se abrió la barra de herramientas Educación" "Se cerró la barra de herramientas Educación" "Usa la barra de tareas para cambiar de app" @@ -110,6 +112,10 @@ "Recientes" "Notificaciones" "Config. rápida" + + + + "Mover a la parte superior o izquierda" "Mover a la parte inferior o derecha" diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml index 6610768d77..1c73134f0c 100644 --- a/quickstep/res/values-es/strings.xml +++ b/quickstep/res/values-es/strings.xml @@ -79,8 +79,10 @@ "Desliza el dedo hacia arriba para ir a la pantalla de inicio" - "Ya puedes empezar a usar tu teléfono" - "Ya puedes empezar a usar tu tablet" + + + + "Ajustes de navegación del sistema" "Compartir" "Hacer captura" @@ -94,6 +96,8 @@ "Cancelar" "Saltar" "Girar la pantalla" + + "Ha aparecido una nota sobre la barra de tareas" "Nota sobre la barra de tareas cerrada" "Usa la barra de tareas para cambiar de aplicación" @@ -110,6 +114,10 @@ "Recientes" "Notificaciones" "Ajustes rápidos" + + + + "Mover arriba/a la izquierda" "Mover abajo/a la derecha" diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml index 67f4e1c04e..19b3817c7c 100644 --- a/quickstep/res/values-et/strings.xml +++ b/quickstep/res/values-et/strings.xml @@ -77,23 +77,25 @@ "Õpetus %1$d/%2$d" "Valmis!" "Avakuvale liikumiseks pühkige üles" - + "Avakuvale liikumiseks puudutage avakuva nuppu" + + + - "Olete valmis oma telefoni kasutama." - "Olete valmis oma tahvelarvutit kasutama" "Süsteemi navigeerimisseaded" "Jaga" "Ekraanipilt" "Eralda" "Jagatud kuva kasutamiseks puudutage muud rakendust" - - + "Valige jagatud ekraanikuva jaoks muu rakendus" "Rakendus või teie organisatsioon on selle toimingu keelanud" "Kas jätta navigeerimise õpetused vahele?" "Leiate selle hiljem rakendusest %1$s" "Tühista" "Jäta vahele" "Pöörake ekraani" + + "Tegumiriba juhised kuvati" "Tegumiriba juhised on suletud" "Kasutage rakenduste vahetamiseks tegumiriba" @@ -110,6 +112,10 @@ "Hiljutised" "Märguanded" "Kiirseaded" + + + + "Teisalda üles/vasakule" "Teisalda alla/paremale" diff --git a/quickstep/res/values-eu/strings.xml b/quickstep/res/values-eu/strings.xml index 0185bb9202..8fa85337e5 100644 --- a/quickstep/res/values-eu/strings.xml +++ b/quickstep/res/values-eu/strings.xml @@ -77,23 +77,25 @@ "Tutoriala: %1$d/%2$d" "Dena prest!" "Pasatu hatza gora hasierako pantailara joateko" - + "Hasierako pantailara joateko, sakatu Hasiera botoia" + + + - "Prest zaude telefonoa erabiltzen hasteko" - "Prest zaude tableta erabiltzen hasteko" "Sisteman nabigatzeko ezarpenak" "Partekatu" "Atera pantaila-argazki bat" "Zatitu" "Sakatu beste aplikazio bat pantaila zatitzeko" - - + "Pantaila zatitua ikusteko, aukeratu beste aplikazio bat" "Aplikazioak edo erakundeak ez du eman ekintza hori gauzatzeko baimena" "Nabigazio-tutoriala saltatu nahi duzu?" "%1$s aplikazioan dago eskuragarri tutoriala" "Utzi" "Saltatu" "Biratu pantaila" + + "Agertu egin da zereginen barraren tutoriala" "Itxi egin da zereginen barraren tutoriala" "Erabili zereginen barra aplikazioz aldatzeko" @@ -110,6 +112,10 @@ "Azkenak" "Jakinarazpenak" "Ezarpen bizkorrak" + + + + "Eraman gora, ezkerretara" "Eraman behera, eskuinetara" diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml index 44c9975f3f..94a48f93e4 100644 --- a/quickstep/res/values-fa/strings.xml +++ b/quickstep/res/values-fa/strings.xml @@ -77,23 +77,25 @@ "آموزش گام‌به‌گام %1$d/%2$d" "همه چیز آماده است!" "برای رفتن به «صفحه اصلی»، تند به‌بالا بکشید" - + "برای رفتن به صفحه اصلی، روی دکمه صفحه اصلی ضربه بزنید" + + + - "آماده‌اید از تلفنتان استفاده کنید" - "آماده‌اید از رایانه لوحی‌تان استفاده کنید" "تنظیمات پیمایش سیستم" "هم‌رسانی" "نماگرفت" "دونیمه" "برای استفاده از صفحهٔ دونیمه، روی برنامه دیگری ضربه بزنید" - - + "انتخاب برنامه‌ای دیگر برای استفاده از صفحه دونیمه" "برنامه یا سازمان شما اجازه نمی‌دهد این کنش انجام شود." "آموزش گام‌به‌گام پیمایش رد شود؟" "می‌توانید آن را بعداً در برنامه %1$s پیدا کنید" "لغو" "رد شدن" "چرخاندن صفحه" + + "پانل آموزشی نوار وظیفه نمایان شد" "پانل آموزشی نوار وظیفه بسته شد" "برای جابه‌جایی بین برنامه‌ها، از نوار وظیفه استفاده کنید" @@ -110,6 +112,10 @@ "موارد اخیر" "اعلان‌ها" "تنظیمات فوری" + + + + "انتقال به بالا/ چپ" "انتقال به پایین/ راست" diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml index adff666707..a5c2b9cd96 100644 --- a/quickstep/res/values-fi/strings.xml +++ b/quickstep/res/values-fi/strings.xml @@ -77,23 +77,25 @@ "Ohje %1$d/%2$d" "Valmis" "Siirry aloitusnäytölle pyyhkäisemällä ylös" - + "Siirry aloitusnäytölle napauttamalla aloitusnäyttöpainiketta" + + + - "Olet valmis aloittamaan puhelimen käytön" - "Olet valmis aloittamaan tabletin käytön" "Järjestelmän navigointiasetukset" "Jaa" "Kuvakaappaus" "Jaa" "Avaa jaettu näyttö napauttamalla toista sovellusta" - - + "Käytä jaettua näyttöä valitsemalla toinen sovellus" "Sovellus tai organisaatio ei salli tätä toimintoa" "Ohitetaanko navigointiohje?" "Löydät tämän myöhemmin sovelluksesta: %1$s" "Peru" "Ohita" "Käännä näyttö" + + "Tehtäväpalkin ohje näkyvissä" "Tehtäväpalkin ohje suljettu" "Vaihda sovellusta tehtäväpalkin kautta" @@ -110,6 +112,10 @@ "Viimeaikaiset" "Ilmoitukset" "Pika-asetukset" + + + + "Siirrä ylös tai vasemmalle" "Siirrä alas tai oikealle" diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml index 63f1a1a337..261b25561e 100644 --- a/quickstep/res/values-fr-rCA/strings.xml +++ b/quickstep/res/values-fr-rCA/strings.xml @@ -79,8 +79,10 @@ "Balayez l\'écran vers le haut pour accéder à l\'écran d\'accueil" - "Vous êtes maintenant prêt à utiliser votre téléphone" - "Vous êtes maintenant prêt à utiliser votre tablette" + + + + "Paramètres de navigation du système" "Partager" "Capture d\'écran" @@ -94,6 +96,8 @@ "Annuler" "Ignorer" "Faire pivoter l\'écran" + + "La barre des tâches éducatives s\'est affichée" "La barre des tâches éducatives est fermée" "Utilisez la barre des tâches pour changer les applications" @@ -110,6 +114,10 @@ "Récents" "Notifications" "Paramètres rapides" + + + + "Déplacer vers le coin supérieur gauche de l\'écran" "Déplacer vers le coin inférieur droit de l\'écran" diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml index 5eccc91df1..4eb5ebb5eb 100644 --- a/quickstep/res/values-fr/strings.xml +++ b/quickstep/res/values-fr/strings.xml @@ -77,23 +77,25 @@ "Tutoriel %1$d sur %2$d" "Tout est prêt !" "Balayez l\'écran vers le haut pour revenir à l\'accueil" - + "Appuyez sur le bouton d\'accueil pour accéder à votre écran d\'accueil" + + + - "Vous pouvez maintenant utiliser votre téléphone" - "Vous pouvez maintenant utiliser votre tablette" "Paramètres de navigation système" "Partager" "Capture d\'écran" "Partager" "Appuyez sur autre appli pour utiliser écran partagé" - - + "Sélect. autre appli pour utiliser l\'écran partagé" "Cette action n\'est pas autorisée par l\'application ou par votre organisation" "Ignorer le tutoriel de navigation ?" "Vous le retrouverez dans l\'appli %1$s" "Annuler" "Passer" "Faire pivoter l\'écran" + + "Infos sur la barre des tâches affichées" "Infos sur la barre des tâches fermées" "Utilisez la barre des tâches pour changer d\'application" @@ -110,6 +112,10 @@ "Récents" "Notifications" "Réglages rapides" + + + + "Déplacer en haut ou à gauche" "Déplacer en bas ou à droite" diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml index 95c8761c98..e3dacb6b9c 100644 --- a/quickstep/res/values-gl/strings.xml +++ b/quickstep/res/values-gl/strings.xml @@ -77,23 +77,25 @@ "Titorial %1$d/%2$d" "Todo listo" "Pasa o dedo cara arriba para ir á pantalla de inicio" - + "Toca o botón de inicio para ir á pantalla de inicio" + + + - "Xa podes comezar a utilizar o teléfono" - "Todo está listo para comezar a utilizar a tableta" "Configuración da navegación do sistema" "Compartir" "Facer captura" "Dividir" "Para usar a pantalla dividida, toca outra app" - - + "Escolle outra app para usar a pantalla dividida" "A aplicación ou a túa organización non permite realizar esta acción" "Queres omitir o titorial de navegación?" "Podes atopalo máis tarde na aplicación %1$s" "Cancelar" "Omitir" "Xira a pantalla" + + "Panel de información de barra de tarefas aberto" "Panel de información de barra de tarefas pechado" "Usa a barra de ferramentas para cambiar de aplicación" @@ -110,6 +112,10 @@ "Recentes" "Notificacións" "Configuración rápida" + + + + "Mover á parte superior ou á esquerda" "Mover á parte inferior ou á dereita" diff --git a/quickstep/res/values-gu/strings.xml b/quickstep/res/values-gu/strings.xml index 051077da0d..c52f39c9dd 100644 --- a/quickstep/res/values-gu/strings.xml +++ b/quickstep/res/values-gu/strings.xml @@ -77,23 +77,25 @@ "ટ્યૂટૉરિઅલ %1$d/%2$d" "બધું સેટ થઈ ગયું!" "હોમપેજ પર જવા માટે ઉપરની તરફ સ્વાઇપ કરો" - + "તમારી હોમ સ્ક્રીન પર જવા માટે હોમ બટન ટૅપ કરો" + + + - "તમે તમારા ફોનનો ઉપયોગ કરવા માટે તૈયાર છો" - "તમે તમારા ટૅબ્લેટનો ઉપયોગ કરવા માટે તૈયાર છો" "સિસ્ટમના નૅવિગેશન સેટિંગ" "શેર કરો" "સ્ક્રીનશૉટ" "વિભાજિત કરો" "સ્પલિટસ્ક્રીનના વપરાશ માટે, કોઈ અન્ય ઍપ પર ટૅપ કરો" - - + "સ્ક્રીન વિભાજનનો ઉપયોગ કરવા કોઈ અન્ય ઍપ પસંદ કરો" "ઍપ કે તમારી સંસ્થા દ્વારા આ ક્રિયા કરવાની મંજૂરી નથી" "નૅવિગેશન ટ્યૂટૉરિઅલ છોડી દઈએ?" "તમે આને પછીથી %1$s ઍપમાં જોઈ શકો છો" "રદ કરો" "છોડો" "સ્ક્રીન ફેરવો" + + "ટાસ્કબારનું શિક્ષણ આપતી પૅનલ દેખાય છે" "ટાસ્કબારનું શિક્ષણ આપતી પૅનલ બંધ થઈ છે" "ઍપ સ્વિચ કરવા માટે, ટાસ્કબારનો ઉપયોગ કરો" @@ -110,6 +112,10 @@ "તાજેતરના" "નોટિફિકેશન" "ઝડપી સેટિંગ" + + + + "સૌથી ઉપર ડાબી બાજુએ ખસેડો" "સૌથી નીચે જમણી બાજુએ ખસેડો" diff --git a/quickstep/res/values-hi/strings.xml b/quickstep/res/values-hi/strings.xml index 434845ff8f..51d593da3c 100644 --- a/quickstep/res/values-hi/strings.xml +++ b/quickstep/res/values-hi/strings.xml @@ -77,23 +77,25 @@ "ट्यूटोरियल %1$d/%2$d" "हो गया!" "होम स्क्रीन पर जाने के लिए, ऊपर की ओर स्वाइप करें" - + "होम स्क्रीन पर जाने के लिए, होम बटन पर टैप करें" + + + - "अब आपका फ़ोन, इस्तेमाल के लिए तैयार है" - "आप टैबलेट को इस्तेमाल करने के लिए तैयार हैं" "सिस्टम नेविगेशन सेटिंग" "शेयर करें" "स्क्रीनशॉट लें" "स्प्लिट स्क्रीन मोड" "स्प्लिट स्क्रीन मोड के लिए, दूसरे ऐप पर टैप करें" - - + "स्प्लिट स्क्रीन के लिए, दूसरा ऐप्लिकेशन चुनें" "ऐप्लिकेशन या आपका संगठन इस कार्रवाई की अनुमति नहीं देता" "क्या आपको नेविगेशन ट्यूटोरियल छोड़ना है?" "इसे बाद में %1$s ऐप्लिकेशन पर देखा जा सकता है" "रद्द करें" "छोड़ें" "स्क्रीन घुमाएं" + + "टास्कबार ट्यूटोरियल दिखाया गया" "टास्कबार ट्यूटोरियल बंद किया गया" "ऐप्लिकेशन स्विच करने के लिए, टास्कबार का इस्तेमाल करें" @@ -110,6 +112,10 @@ "हाल ही के" "सूचनाएं" "फटाफट सेटिंग" + + + + "ऊपर/बाईं तरफ़ ले जाएं" "नीचे/दाईं तरफ़ ले जाएं" diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml index 681105e3d3..5201c24905 100644 --- a/quickstep/res/values-hr/strings.xml +++ b/quickstep/res/values-hr/strings.xml @@ -77,23 +77,25 @@ "Vodič %1$d/%2$d" "Sve je spremno!" "Prijeđite prstom prema gore da biste otvorili početni zaslon" - + "Dodirnite gumb početnog zaslona da biste prešli na početni zaslon" + + + - "Spremni ste za početak upotrebe telefona" - "Spremni ste za početak upotrebe tableta" "Postavke navigacije sustavom" "Podijeli" "Snimka zaslona" "Podijeli" "Dodirnite drugu aplikaciju za podijeljeni zaslon" - - + "Odaberite drugu aplikaciju za upotrebu podijeljenog zaslona" "Aplikacija ili vaša organizacija ne dopuštaju ovu radnju" "Želite li preskočiti vodič za kretanje?" "Kasnije ga možete pronaći u aplikaciji %1$s" "Odustani" "Preskoči" "Zakretanje zaslona" + + "Upute za programsku traku su se pojavile" "Upute za programsku traku su zatvorene" "Upotrijebite program. traku da biste promijenili aplikaciju" @@ -110,6 +112,10 @@ "Najnovije" "Obavijesti" "Brze postavke" + + + + "Premjesti gore/lijevo" "Premjesti dolje/desno" diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml index 46e4b2bd69..35ed5a9221 100644 --- a/quickstep/res/values-hu/strings.xml +++ b/quickstep/res/values-hu/strings.xml @@ -77,23 +77,25 @@ "Útmutató (%2$d/%1$d.)" "Kész is!" "Felfelé csúsztatva megjelenik a Kezdőképernyő" - + "A kezdőképernyőre való lépéshez koppintson a kezdőképernyő gombra" + + + - "Készen áll a telefon használatára" - "Készen áll a táblagép használatára" "Rendszer-navigációs beállítások" "Megosztás" "Képernyőkép" "Felosztás" "Koppintson másik appra a képernyőmegosztáshoz" - - + "Válasszon másik appot a képernyő felosztásához" "Az alkalmazás vagy az Ön szervezete nem engedélyezi ezt a műveletet" "Kihagyja a navigáció bemutatóját?" "Ezt később megtalálhatja a(z) %1$s alkalmazásban" "Mégse" "Kihagyás" "Képernyő elforgatása" + + "Az eszköztár használatát ismertető panel megjelent" "Az eszköztár használatát ismertető panel bezárult" "Az eszköztárral válthat az alkalmazások között" @@ -110,6 +112,10 @@ "Legutóbbiak" "Értesítések" "Gyorsbeállítások" + + + + "Mozgatás felülre vagy a bal oldalra" "Mozgatás alulra vagy a jobb oldalra" diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml index cc49954127..bb27ef24c5 100644 --- a/quickstep/res/values-hy/strings.xml +++ b/quickstep/res/values-hy/strings.xml @@ -77,23 +77,25 @@ "Ուղեցույց %1$d/%2$d" "Պատրաստ է" "Մատը սահեցրեք վերև՝ հիմնական էկրան անցնելու համար" - + "Հիմնական էկրան վերադառնալու համար սեղմեք գլխավոր էկրանի կոճակը" + + + - "Դուք արդեն կարող եք օգտագործել ձեր հեռախոսը" - "Դուք արդեն կարող եք օգտագործել ձեր պլանշետը" "Նավիգացիայի համակարգային կարգավորումներ" "Կիսվել" "Սքրինշոթ անել" "Տրոհել" "Հպեք այլ հավելվածի՝ էկրանը տրոհելու համար" - - + "Ընտրեք այլ հավելված՝ կիսված էկրանից օգտվելու համար" "Այս գործողությունն արգելված է հավելվածի կամ ձեր կազմակերպության կողմից" "Բաց թողնե՞լ նավիգացիայի ուղեցույցը" "Հետագայում սա կարող եք գտնել «%1$s» հավելվածում" "Չեղարկել" "Բաց թողնել" "Պտտել էկրանը" + + "Խնդրագոտու «Կրթություն» վահանակը բացվեց" "Խնդրագոտու «Կրթություն» վահանակը փակվեց" "Օգտագործեք խնդրագոտին՝ մի հավելվածից մյուսին անցնելու համար" @@ -110,6 +112,10 @@ "Վերջինները" "Ծանուցումներ" "Արագ կարգավորումներ" + + + + "Տեղափոխել վերևի ձախ անկյուն" "Տեղափոխել ներքևի աջ անկյուն" diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml index 9012ba6cd9..68604b96dd 100644 --- a/quickstep/res/values-in/strings.xml +++ b/quickstep/res/values-in/strings.xml @@ -77,23 +77,25 @@ "Tutorial %1$d/%2$d" "Semua siap." "Geser ke atas untuk beralih ke Layar utama" - + "Ketuk tombol layar utama untuk membuka layar utama" + + + - "Anda sudah siap untuk mulai menggunakan ponsel" - "Anda sudah siap untuk mulai menggunakan tablet" "Setelan navigasi sistem" "Bagikan" "Screenshot" "Pisahkan" "Ketuk aplikasi lain untuk menggunakan layar terpisah" - - + "Pilih aplikasi lain untuk memakai layar terpisah" "Tindakan ini tidak diizinkan oleh aplikasi atau organisasi Anda" "Lewati tutorial gestur?" "Anda dapat menemukan tutorial ini di lain waktu di aplikasi %1$s" "Batal" "Lewati" "Putar layar" + + "Edukasi taskbar ditampilkan" "Edukasi taskbar ditutup" "Gunakan taskbar untuk beralih aplikasi" @@ -110,6 +112,10 @@ "Terbaru" "Notifikasi" "Setelan Cepat" + + + + "Pindahkan ke atas/kiri" "Pindahkan ke bawah/kanan" diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml index d7f2075cfe..39dfbee9fe 100644 --- a/quickstep/res/values-is/strings.xml +++ b/quickstep/res/values-is/strings.xml @@ -77,23 +77,25 @@ "Leiðsögn %1$d/%2$d" "Allt tilbúið!" "Strjúktu upp til að fara á heimaskjáinn" - + "Ýttu á heimahnappinn til að fara á heimaskjáinn" + + + - "Þú getur byrjað að nota símann" - "Þú getur byrjað að nota spjaldtölvuna" "Stillingar kerfisstjórnunar" "Deila" "Skjámynd" "Skipta" "Ýttu á annað forrit til að nota skjáskiptingu" - - + "Veldu annað forrit til að nota skjáskiptingu" "Forritið eða fyrirtækið leyfir ekki þessa aðgerð" "Sleppa flettileiðsögn?" "Þú getur fundið þetta síðar í forritinu %1$s" "Hætta við" "Sleppa" "Snúa skjánum" + + "Leiðsögn verkefnastiku sýnileg" "Leiðsögn verkefnastiku lokað" "Notaðu verkefnastikuna til að skipta á milli forrita" @@ -110,6 +112,10 @@ "Nýlegt" "Tilkynningar" "Flýtistillingar" + + + + "Færa efst/til vinstri" "Færa neðst/til hægri" diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml index 7df4dee155..ad5197e98a 100644 --- a/quickstep/res/values-it/strings.xml +++ b/quickstep/res/values-it/strings.xml @@ -77,23 +77,25 @@ "Tutorial %1$d/%2$d" "Finito." "Scorri verso l\'alto per andare alla schermata Home" - + "Tocca il pulsante Home per andare alla schermata Home" + + + - "Puoi iniziare a usare il tuo telefono" - "Puoi iniziare a usare il tuo tablet" "Impostazioni Navigazione del sistema" "Condividi" "Screenshot" "Dividi" "Tocca un\'altra app per usare lo schermo diviso" - - + "Scegli un\'altra app per usare lo schermo diviso" "Questa azione non è consentita dall\'app o dall\'organizzazione" "Saltare il tutorial di navigazione?" "Puoi trovarlo in un secondo momento nell\'app %1$s" "Annulla" "Salta" "Ruota lo schermo" + + "Riquadro Formazione barra delle applicazioni visualizzato" "Riquadro Formazione barra delle applicazioni chiuso" "Usa la barra delle applicazioni per cambiare app" @@ -110,6 +112,10 @@ "Recenti" "Notifiche" "Impostazioni rapide" + + + + "Sposta in alto/a sinistra" "Sposta in basso/a destra" diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml index 899011a35a..be508b9f6c 100644 --- a/quickstep/res/values-iw/strings.xml +++ b/quickstep/res/values-iw/strings.xml @@ -77,23 +77,25 @@ "מדריך %1$d/%2$d" "הכול מוכן!" "כדי לעבור לדף הבית, מחליקים כלפי מעלה" - + "כדי לעבור אל מסך הבית יש להקיש על הלחצן הראשי" + + + - "הכול מוכן ואפשר להתחיל להשתמש בטלפון" - "הכול מוכן ואפשר להתחיל להשתמש בטאבלט" "הגדרות הניווט של המערכת" "שיתוף" "צילום מסך" "פיצול" "צריך להקיש על אפליקציה אחרת כדי להשתמש במסך מפוצל" - - + "כדי להשתמש במסך מפוצל צריך לבחור אפליקציה אחרת" "האפליקציה או הארגון שלך אינם מתירים את הפעולה הזאת" "לדלג על המדריך לניווט?" "ניתן למצוא את המדריך מאוחר יותר באפליקציה %1$s" "ביטול" "דילוג" "סיבוב המסך" + + "חלונית ההסברים על שורת המשימות מופיעה" "חלונית ההסברים על שורת המשימות נסגרה" "כדי לעבור בין אפליקציות, משתמשים בשורת המשימות" @@ -110,6 +112,10 @@ "לאחרונה" "התראות" "הגדרות מהירות" + + + + "העברה לפינה השמאלית/העליונה" "העברה לפינה הימנית/התחתונה" diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml index 3614e2db4d..4349d46db5 100644 --- a/quickstep/res/values-ja/strings.xml +++ b/quickstep/res/values-ja/strings.xml @@ -77,23 +77,25 @@ "チュートリアル %1$d/%2$d" "設定完了" "ホームに移動するには上にスワイプします" - + "ホームボタンをタップすると、ホーム画面に移動します" + + + - "スマートフォンを使用する準備ができました" - "これでタブレットが使えるようになりました" "システム ナビゲーションの設定" "共有" "スクリーンショット" "分割" "分割画面を使用するには、他のアプリをタップします" - - + "分割画面にするには、別のアプリを選択してください" "この操作はアプリまたは組織で許可されていません" "操作チュートリアルをスキップしますか?" "チュートリアルは後から %1$s アプリで確認できます" "キャンセル" "スキップ" "画面を回転" + + "タスクバーの説明を開きました" "タスクバーの説明を閉じました" "アプリを切り替えるには、タスクバーを使用します" @@ -110,6 +112,10 @@ "最近" "通知" "クイック設定" + + + + "上 / 左に移動" "下 / 右に移動" diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml index b862c6f5d8..a3895b1ca3 100644 --- a/quickstep/res/values-ka/strings.xml +++ b/quickstep/res/values-ka/strings.xml @@ -77,23 +77,25 @@ "სახელმძღვანელო %1$d/%2$d" "მზადაა!" "მთავარ გვერდზე გადასასვლელად გადაფურცლეთ ზევით" - + "შეეხეთ მთავარი ეკრანის ღილაკს მთავარ ეკრანზე გადასასვლელად" + + + - "მზად ხართ ტელეფონის გამოსაყენებლად" - "მზად ხართ ტაბლეტის გამოსაყენებლად" "სისტემის ნავიგაციის პარამეტრები" "გაზიარება" "ეკრანის ანაბეჭდი" "გაყოფა" "შეეხეთ სხვა აპს ეკრანის გასაყოფად" - - + "აირჩიეთ სხვა აპი ეკრანის გასაყოფად" "ეს მოქმედება არ არის დაშვებული აპის ან თქვენი ორგანიზაციის მიერ" "გსურთ, გამოტოვოთ ნავიგაციის სახელმძღვანელო?" "ამის მოგვიანებით პოვნა %1$s აპში შეგიძლიათ" "გაუქმება" "გამოტოვება" "ეკრანის შეტრიალება" + + "ამოცანების ზოლის სასწავლო არე გამოჩნდა" "ამოცანების ზოლის სასწავლო არე დაიხურა" "აპების გადასართავად გამოიყენეთ ამოცანათა ზოლი" @@ -110,6 +112,10 @@ "ბოლოდროინდელი" "შეტყობინებები" "სწრაფი პარამეტრები" + + + + "ზემოთ/მარცხნივ გადატანა" "ქვემოთ/მარჯვნივ გადატანა" diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml index 8f42ff6c53..35341760e0 100644 --- a/quickstep/res/values-kk/strings.xml +++ b/quickstep/res/values-kk/strings.xml @@ -79,8 +79,10 @@ "Негізгі экранға өту үшін жоғары қарай сырғытыңыз." - "Телефоныңыз пайдалануға дайын." - "Планшетіңіз пайдалануға дайын." + + + + "Навигацияның жүйелік параметрлері" "Бөлісу" "Скриншот" @@ -94,6 +96,8 @@ "Бас тарту" "Өткізіп жіберу" "Экранды бұру" + + "Тапсырмалар тақтасы бойынша нұсқаулық ашылды." "Тапсырмалар тақтасы бойынша нұсқаулық жабылды." "Қолданбаларды ауыстыру үшін тапсырма тақтасын пайдаланыңыз." @@ -110,6 +114,10 @@ "Соңғылары" "Хабарландырулар" "Жылдам параметрлер" + + + + "Жоғары/солға жылжыту" "Төмен/оңға жылжыту" diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml index d1ed52899b..4880a30d81 100644 --- a/quickstep/res/values-km/strings.xml +++ b/quickstep/res/values-km/strings.xml @@ -77,23 +77,25 @@ "មេរៀនទី %1$d/%2$d" "រួចហើយ!" "អូសឡើងលើ ដើម្បី​ទៅកាន់​អេក្រង់ដើម" - + "ចុចប៊ូតុងដើម ដើម្បីចូលទៅកាន់អេក្រង់ដើមរបស់អ្នក" + + + - "អ្នក​អាច​ចាប់ផ្ដើម​ប្រើ​ទូរសព្ទ​របស់អ្នក​បានហើយ" - "អ្នកអាចចាប់ផ្ដើមប្រើថេប្លេតរបស់អ្នកបានហើយ" "ការកំណត់​ការរុករក​ប្រព័ន្ធ" "ចែករំលែក" "រូបថតអេក្រង់" "បំបែក" "ចុចកម្មវិធី​ផ្សេងទៀត ដើម្បីប្រើមុខងារ​បំបែកអេក្រង់" - - + "ជ្រើសរើសកម្មវិធីផ្សេងទៀត ដើម្បីប្រើមុខងារ​បំបែកអេក្រង់" "សកម្មភាពនេះ​មិនត្រូវបានអនុញ្ញាតដោយកម្មវិធី​ ឬ​ស្ថាប័ន​របស់អ្នកទេ" "រំលង​មេរៀន​អំពី​ការរុករក​ឬ?" "អ្នកអាចស្វែងរកមេរៀននេះនៅពេលក្រោយក្នុងកម្មវិធី %1$s" "បោះបង់" "រំលង" "បង្វិលអេក្រង់" + + "ការបង្រៀនអំពីរបារកិច្ចការបានបង្ហាញ" "ការបង្រៀនអំពីរបារកិច្ចការត្រូវបានបិទ" "ប្រើ​របារកិច្ចការ ដើម្បី​ប្ដូរកម្មវិធី" @@ -110,6 +112,10 @@ "ថ្មីៗ" "ការ​ជូនដំណឹង" "ការកំណត់រហ័ស" + + + + "ផ្លាស់ទីទៅខាងលើ/ឆ្វេង" "ផ្លាស់ទីទៅខាងក្រោម/ស្ដាំ" diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml index 99fb8ba089..2f308b743e 100644 --- a/quickstep/res/values-kn/strings.xml +++ b/quickstep/res/values-kn/strings.xml @@ -77,23 +77,25 @@ "ಟ್ಯುಟೋರಿಯಲ್ %1$d/%2$d" "ಎಲ್ಲವೂ ಸಿದ್ಧವಾಗಿದೆ!" "ಮುಖಪುಟಕ್ಕೆ ಹೋಗಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ" - + "ನಿಮ್ಮ ಮುಖಪುಟದ ಪರದೆಗೆ ಹೋಗಲು ಮುಖಪುಟ ಬಟನ್ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ" + + + - "ನಿಮ್ಮ ಫೋನ್ ಬಳಸುವುದನ್ನು ಪ್ರಾರಂಭಿಸಲು ನೀವು ಸಿದ್ದರಾಗಿರುವಿರಿ" - "ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್‌‌ ಬಳಸುವುದನ್ನು ಪ್ರಾರಂಭಿಸಲು ನೀವು ಸಿದ್ದರಾಗಿರುವಿರಿ" "ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಶನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು" "ಹಂಚಿಕೊಳ್ಳಿ" "ಸ್ಕ್ರೀನ್‌ಶಾಟ್" "ವಿಭಜಿಸಿ" "ಸ್ಪ್ಲಿಟ್ ಸ್ಕ್ರೀನ್ ಅನ್ನು ಬಳಸಲು ಬೇರೊಂದು ಆ್ಯಪ್ ಮೇಲೆ ಟ್ಯಾಪ್ ಮಾಡಿ" - - + "\"ಪರದೆ ಬೇರ್ಪಡಿಸಿ\" ಬಳಸಲು ಬೇರೆ ಆ್ಯಪ್ ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ" "ಆ್ಯಪ್ ಅಥವಾ ನಿಮ್ಮ ಸಂಸ್ಥೆಯು ಈ ಕ್ರಿಯೆಯನ್ನು ಅನುಮತಿಸುವುದಿಲ್ಲ" "ನ್ಯಾವಿಗೇಶನ್ ಟ್ಯುಟೋರಿಯಲ್ ಸ್ಕಿಪ್ ಮಾಡಬೇಕೇ?" "%1$s ಆ್ಯಪ್‌ನಲ್ಲಿ ಇದನ್ನು ನಂತರ ಕಾಣಬಹುದು" "ರದ್ದುಮಾಡಿ" "ಸ್ಕಿಪ್ ಮಾಡಿ" "ಸ್ಕ್ರೀನ್ ತಿರುಗಿಸಿ" + + "ಟಾಸ್ಕ್‌ಬಾರ್ ಶಿಕ್ಷಣ ಕಾಣಿಸಿಕೊಂಡಿದೆ" "ಟಾಸ್ಕ್‌ಬಾರ್ ಶಿಕ್ಷಣ ಮುಚ್ಚಿದೆ" "ಆ್ಯಪ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಟಾಸ್ಕ್ ಬಾರ್ ಬಳಸಿ" @@ -110,6 +112,10 @@ "ಇತ್ತೀಚಿನವು" "ಅಧಿಸೂಚನೆಗಳು" "ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳು" + + + + "ಮೇಲಿನ/ಎಡಭಾಗಕ್ಕೆ ಸರಿಸಿ" "ಕೆಳಗಿನ/ಬಲಭಾಗಕ್ಕೆ ಸರಿಸಿ" diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml index 8af2ef782e..bf7727e17b 100644 --- a/quickstep/res/values-ko/strings.xml +++ b/quickstep/res/values-ko/strings.xml @@ -77,23 +77,25 @@ "튜토리얼 %1$d/%2$d" "설정 완료" "위로 스와이프하여 홈으로 이동" - + "홈 화면으로 이동하려면 홈 버튼을 탭하세요." + + + - "휴대전화를 사용할 준비가 되었습니다." - "태블릿을 사용할 준비가 되었습니다." "시스템 탐색 설정" "공유" "스크린샷" "분할" "다른 앱을 탭하여 화면 분할 사용" - - + "화면 분할을 사용하려면 다른 앱을 선택하세요." "이 작업은 앱 또는 조직에서 허용되지 않습니다." "이동 방법 튜토리얼을 건너뛰시겠습니까?" "이 튜토리얼은 %1$s 앱에서 다시 볼 수 있습니다." "취소" "건너뛰기" "화면 회전" + + "작업 표시줄 튜토리얼 패널 표시됨" "작업 표시줄 튜토리얼 패널 닫힘" "작업 표시줄을 사용하여 앱 전환" @@ -110,6 +112,10 @@ "최근 항목" "알림" "빠른 설정" + + + + "상단/왼쪽으로 이동" "하단/오른쪽으로 이동" diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml index b7721f4d91..95c569f31b 100644 --- a/quickstep/res/values-ky/strings.xml +++ b/quickstep/res/values-ky/strings.xml @@ -79,8 +79,10 @@ "Башкы бетке өтүү үчүн экранды өйдө сүрүңүз" - "Телефонуңузду колдоно берсеңиз болот" - "Планшетиңизди колдоно берсеңиз болот" + + + + "Өтүү аракетинин системалык параметрлери" "Бөлүшүү" "Скриншот" @@ -94,6 +96,8 @@ "Жокко чыгаруу" "Өткрп жиберүү" "Экранды буруу" + + "Тапшырмалар тактасынын окутуу панели көрсөтүлдү" "Тапшырмалар тактасынын окутуу панели жабылды" "Тапшырмалар тактасы аркылуу башка колдонмого которула аласыз" @@ -110,6 +114,10 @@ "Акыркылар" "Билдирмелер" "Ыкчам жөндөөлөр" + + + + "Жогорку/сол бурчка жылдыруу" "Төмөнкү/оң бурчка жылдыруу" diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml index a1d8640631..8e857b2c16 100644 --- a/quickstep/res/values-lo/strings.xml +++ b/quickstep/res/values-lo/strings.xml @@ -77,23 +77,25 @@ "ການສອນການນຳໃຊ້ທີ %1$d/%2$d" "ຮຽບຮ້ອຍໝົດແລ້ວ!" "ປັດຂຶ້ນເພື່ອໄປຫາໜ້າຫຼັກ" - + "ແຕະປຸ່ມໜ້າທຳອິດເພື່ອໄປຫາໂຮມສະກຣີນຂອງທ່ານ" + + + - "ທ່ານພ້ອມເລີ່ມຕົ້ນໃຊ້ໂທລະສັບຂອງທ່ານແລ້ວ" - "ທ່ານພ້ອມເລີ່ມຕົ້ນໃຊ້ແທັບເລັດຂອງທ່ານແລ້ວ" "ການຕັ້ງຄ່າການນຳທາງລະບົບ" "ແບ່ງປັນ" "ຮູບໜ້າຈໍ" "ແບ່ງ" "ແຕະແອັບອື່ນເພື່ອໃຊ້ການແຍກໜ້າຈໍ" - - + "ເລືອກແອັບອື່ນເພື່ອໃຊ້ການແບ່ງໜ້າຈໍ" "ແອັບ ຫຼື ອົງການຂອງທ່ານບໍ່ອະນຸຍາດໃຫ້ໃຊ້ຄຳສັ່ງນີ້" "ຂ້າມການສອນການນຳໃຊ້ການນຳທາງບໍ?" "ທ່ານສາມາດຊອກສ່ວນນີ້ພາຍຫຼັງໄດ້ໃນແອັບ %1$s" "ຍົກເລີກ" "ຂ້າມ" "ໝຸນໜ້າຈໍ" + + "ສະແດງການສຶກສາແຖບໜ້າວຽກແລ້ວ" "ປິດການສຶກສາແຖບໜ້າວຽກແລ້ວ" "ໃຊ້ແຖບໜ້າວຽກເພື່ອສະຫຼັບແອັບ" @@ -110,6 +112,10 @@ "ຫຼ້າສຸດ" "ການແຈ້ງເຕືອນ" "ການຕັ້ງຄ່າດ່ວນ" + + + + "ຍ້າຍໄປຊ້າຍ/ເທິງ" "ຍ້າຍໄປຂວາ/ລຸ່ມ" diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml index 0ee9f0a2a7..2e1958bc9b 100644 --- a/quickstep/res/values-lt/strings.xml +++ b/quickstep/res/values-lt/strings.xml @@ -77,23 +77,25 @@ "Mokymo programa: %1$d%2$d" "Paruošta!" "Perbraukite aukštyn, kad grįžtumėte į pagrindinį ekraną" - + "Norėdami eiti į pagrindinį ekraną, palieskite pagrindinio ekrano mygtuką" + + + - "Esate pasiruošę pradėti naudoti telefoną" - "Esate pasiruošę pradėti naudoti planšetinį kompiuterį" "Sistemos naršymo nustatymai" "Bendrinti" "Ekrano kopija" "Išskaidymo režimas" "Pal. kitą progr., kad gal. naud. išsk. ekr. rež." - - + "Išskaidyto ekrano režimą naudokite kita programa" "Jūsų organizacijoje arba naudojant šią programą neleidžiama atlikti šio veiksmo" "Praleisti naršymo mokymo programą?" "Tai galėsite rasti vėliau programoje „%1$s“" "Atšaukti" "Praleisti" "Pasukti ekraną" + + "Užduočių juostos patarimai rodomi" "Užduočių juostos patarimai uždaryti" "Naudokite užduočių juostą, kad gal. perjungti programas" @@ -110,6 +112,10 @@ "Naujausi" "Pranešimai" "Spartieji nustatymai" + + + + "Perkelti aukštyn, kairėn" "Perkelti žemyn, dešinėn" diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml index 27460f43e7..3b7029ee62 100644 --- a/quickstep/res/values-lv/strings.xml +++ b/quickstep/res/values-lv/strings.xml @@ -77,23 +77,25 @@ "%1$d. mācību darbība no %2$d" "Gatavs!" "Velciet augšup, lai pārietu uz sākuma ekrānu." - + "Pieskarieties pogai Sākums, lai dotos uz sākuma ekrānu" + + + - "Varat sākt izmantot savu tālruni" - "Varat sākt izmantot savu planšetdatoru" "Sistēmas navigācijas iestatījumi" "Kopīgot" "Veikt ekrānuzņēmumu" "Sadalīt" "Piesk. citai lietotnei, lai izm. ekrāna sadalīšanu" - - + "Izvēlieties citu lietotni, lai sadalītu ekrānu" "Lietotne vai jūsu organizācija neatļauj veikt šo darbību." "Vai izlaist navigācijas mācības?" "Varēsiet to vēlāk atrast lietotnē %1$s." "Atcelt" "Izlaist" "Pagriezt ekrānu" + + "Tika atvērta uzdevumjoslas apmācība" "Tika aizvērta uzdevumjoslas apmācība" "Izmantojiet uzdevumjoslu, lai pārslēgtu lietotnes." @@ -110,6 +112,10 @@ "Nesenie" "Paziņojumi" "Ātrie iestatīj." + + + + "Pārvietot uz augšējo/kreiso stūri" "Pārvietot uz apakšējo/labo stūri" diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml index 38ec94bf8d..fa96161015 100644 --- a/quickstep/res/values-mk/strings.xml +++ b/quickstep/res/values-mk/strings.xml @@ -77,23 +77,25 @@ "Упатство %1$d/%2$d" "Готово!" "Повлечете нагоре за да појдете на почетниот екран" - + "Допрете го копчето за почетен екран за да одите на почетниот екран" + + + - "Спремни сте да почнете да го користите телефонот" - "Спремни сте да почнете да го користите таблетот" "Поставки за системска навигација" "Сподели" "Слика од екранот" "Раздели" "Допрете друга апликација за да користите поделен екран" - - + "Изберете друга апликација за да користите поделен екран" "Апликацијата или вашата организација не го дозволува дејствово" "Да се прескокне упатството за навигација?" "Ова може да го најдете подоцна во апликацијата %1$s" "Откажи" "Прескокни" "Ротирајте го екранот" + + "Се појави лентата за задачи за образование" "Затворена е лентата за задачи за образование" "Префрлувајте се меѓу апликации преку лентата за задачи" @@ -110,6 +112,10 @@ "Неодамнешни" "Известувања" "Брзи поставки" + + + + "Премести горе лево" "Премести долу десно" diff --git a/quickstep/res/values-ml/strings.xml b/quickstep/res/values-ml/strings.xml index bc7efb9395..311f37d527 100644 --- a/quickstep/res/values-ml/strings.xml +++ b/quickstep/res/values-ml/strings.xml @@ -77,23 +77,25 @@ "ട്യൂട്ടോറിയൽ %1$d/%2$d" "എല്ലാം സജ്ജീകരിച്ചു!" "ഹോമിലേക്ക് പോകാൻ മുകളിലേക്ക് സ്വൈപ്പ് ചെയ്യുക" - + "നിങ്ങളുടെ ഹോം സ്ക്രീനിലേക്ക് പോകാൻ ഹോം ബട്ടൺ ടാപ്പ് ചെയ്യുക" + + + - "ഫോൺ ഉപയോഗിച്ച് തുടങ്ങാൻ നിങ്ങൾ തയ്യാറാണ്" - "ടാബ്‌ലെറ്റ് ഉപയോഗിച്ച് തുടങ്ങാൻ നിങ്ങൾ തയ്യാറാണ്" "സിസ്‌റ്റം നാവിഗേഷൻ ക്രമീകരണം" "പങ്കിടുക" "സ്ക്രീൻഷോട്ട്" "വിഭജിക്കുക" "സ്പ്ലിറ്റ് സ്ക്രീനിനായി മറ്റൊരു ആപ്പ് ടാപ്പുചെയ്യൂ" - - + "സ്ക്രീൻ വിഭജന മോഡിന് മറ്റൊരു ആപ്പ് തിരഞ്ഞെടുക്കൂ" "ഈ നടപടി എടുക്കുന്നത് ആപ്പോ നിങ്ങളുടെ സ്ഥാപനമോ അനുവദിക്കുന്നില്ല" "നാവിഗേഷൻ ട്യൂട്ടോറിയൽ ഒഴിവാക്കണോ?" "%1$s ആപ്പിൽ നിങ്ങൾക്ക് ഇത് പിന്നീട് കാണാനാകും" "റദ്ദാക്കുക" "ഒഴിവാക്കുക" "സ്‌ക്രീൻ റൊട്ടേറ്റ് ചെയ്യുക" + + "ടാസ്ക്ക്ബാർ വിവര പാനൽ ദൃശ്യമായി" "ടാസ്ക്ക്ബാർ വിവര പാനൽ അടച്ചു" "ആപ്പുകൾ മാറാൻ ടാസ്ക്ക്ബാർ ഉപയോഗിക്കുക" @@ -110,6 +112,10 @@ "അടുത്തിടെയുള്ളവ" "അറിയിപ്പുകൾ" "ദ്രുത ക്രമീകരണം" + + + + "മുകളിലേക്കോ ഇടത്തേക്കോ നീക്കുക" "താഴേക്കോ വലത്തേക്കോ നീക്കുക" diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml index 45e66e4c6e..027a343037 100644 --- a/quickstep/res/values-mn/strings.xml +++ b/quickstep/res/values-mn/strings.xml @@ -77,23 +77,25 @@ "%1$d/%2$d практик хичээл" "Тохируулж дууслаа!" "Нүүр хуудас руу очихын тулд дээш шударна уу" - + "Үндсэн нүүр лүүгээ очихын тулд нүүр хуудасны товчлуурыг товшино уу" + + + - "Та утсаа ашиглаж эхлэхэд бэлэн боллоо" - "Та таблетаа ашиглаж эхлэхэд бэлэн боллоо" "Системийн навигацын тохиргоо" "Хуваалцах" "Дэлгэцийн агшин дарах" "Хуваах" "Дэлгэц хуваахыг ашиглах бол өөр аппыг товшино уу" - - + "Дэлгэцийг хуваах горим ашиглах өөр апп сонгоно уу" "Энэ үйлдлийг апп эсвэл танай байгууллага зөвшөөрдөггүй" "Навигацын практик хичээлийг алгасах уу?" "Та үүнийг дараа нь %1$s аппаас олох боломжтой" "Цуцлах" "Алгасах" "Дэлгэцийг эргүүлэх" + + "Боловсролын ажлын талбар гарч ирсэн" "Боловсролын ажлын талбарыг хаасан" "Аппуудыг сэлгэхийн тулд талбарыг ашиглана уу" @@ -110,6 +112,10 @@ "Саяхны" "Мэдэгдэл" "Шуурхай тохиргоо" + + + + "Зүүн дээд хэсэг рүү зөөх" "Баруун доод хэсэг рүү зөөх" diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml index f6f8c142df..2fcf758890 100644 --- a/quickstep/res/values-mr/strings.xml +++ b/quickstep/res/values-mr/strings.xml @@ -77,23 +77,25 @@ "ट्यूटोरियल %1$d/%2$d" "सर्व तयार आहे!" "होम वर जाण्यासाठी वरती स्वाइप करा" - + "तुमच्या होम स्क्रीनवर जाण्यासाठी होम बटणावर टॅप करा" + + + - "तुम्ही तुमचा फोन वापरण्यास सुरुवात करू शकता" - "तुम्ही तुमचा टॅबलेट वापरण्यास सुरुवात करू शकता" "सिस्टीम नेव्हिगेशन सेटिंग्ज" "शेअर करा" "स्क्रीनशॉट" "स्प्लिट" "स्प्लिटस्क्रीन वापरण्यासाठी दुसऱ्या ॲपवर टॅप करा" - - + "स्प्लिट स्क्रीन वापरण्यासाठी दुसरे ॲप निवडा" "अ‍ॅप किंवा तुमच्या संस्थेद्वारे ही क्रिया करण्याची अनुमती नाही" "नेव्हिगेशन ट्यूटोरियल वगळायचे आहे का?" "तुम्हाला हे नंतर %1$s ॲपमध्ये मिळेल" "रद्द करा" "वगळा" "स्क्रीन फिरवा" + + "टास्कबारशी संबंधित माहिती देणारे पॅनल उघडले आहे" "टास्कबारशी संबंधित माहिती देणारे पॅनल बंद केले आहे" "ॲप्स स्विच करण्यासाठी टास्कबार वापरा" @@ -110,6 +112,10 @@ "अलीकडील" "सूचना" "क्विक सेटिंग्ज" + + + + "सर्वात वरती/डावीकडे हलवा" "तळाशी/उजवीकडे हलवा" diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml index d173790e28..3f49c1253c 100644 --- a/quickstep/res/values-ms/strings.xml +++ b/quickstep/res/values-ms/strings.xml @@ -77,23 +77,25 @@ "Tutorial %1$d/%2$d" "Siap!" "Leret ke atas untuk kembali ke Laman Utama" - + "Ketik butang skrin utama untuk pergi ke skrin utama anda" + + + - "Anda sudah sedia untuk mula menggunakan telefon anda" - "Anda bersedia untuk mula menggunakan tablet anda" "Tetapan navigasi sistem" "Kongsi" "Tangkapan skrin" "Pisah" "Ketik apl lain untuk menggunakan skrin pisah" - - + "Pilih apl lain untuk menggunakan skrin pisah" "Tindakan ini tidak dibenarkan oleh apl atau organisasi anda" "Langkau tutorial navigasi?" "Anda boleh mendapatkan tutorial ini kemudian dalam apl %1$s" "Batal" "Langkau" "Putar skrin" + + "Pendidikan bar tugas muncul" "Pendidikan bar tugas ditutup" "Gunakan bar tugas untuk menukar apl" @@ -110,6 +112,10 @@ "Terbaharu" "Pemberitahuan" "Tetapan Pantas" + + + + "Alihkan ke atas/kiri" "Alihkan ke bawah/kanan" diff --git a/quickstep/res/values-my/strings.xml b/quickstep/res/values-my/strings.xml index 20441d1771..825a263531 100644 --- a/quickstep/res/values-my/strings.xml +++ b/quickstep/res/values-my/strings.xml @@ -77,23 +77,25 @@ "ရှင်းလင်းပို့ချချက် %1$d/%2$d" "အားလုံး အဆင်သင့်ပါ။" "ပင်မစာမျက်နှာသို့သွားရန် အပေါ်သို့ ပွတ်ဆွဲပါ" - + "ပင်မစာမျက်နှာသို့ သွားရန် ပင်မခလုတ်ကို တို့ပါ" + + + - "သင့်ဖုန်း စသုံးရန် အသင့်ဖြစ်ပါပြီ" - "သင့်တက်ဘလက်ကို စသုံးရန် အသင့်ဖြစ်ပါပြီ" "စနစ် လမ်းညွှန် ဆက်တင်များ" "မျှဝေရန်" "ဖန်သားပြင်ဓာတ်ပုံ" "ခွဲထုတ်ရန်" "မျက်နှာပြင်ခွဲ၍ပြသရန် အက်ပ်နောက်တစ်ခုကို တို့ပါ" - - + "မျက်နှာပြင်ခွဲ၍ပြသခြင်းသုံးရန် နောက်အက်ပ်တစ်ခုရွေးပါ" "ဤလုပ်ဆောင်ချက်ကို အက်ပ် သို့မဟုတ် သင်၏အဖွဲ့အစည်းက ခွင့်မပြုပါ" "လမ်းညွှန်ခြင်း ရှင်းလင်းပို့ချချက်ကို ကျော်မလား။" "၎င်းကို နောက်မှ %1$s အက်ပ်တွင် ရှာနိုင်သည်" "မလုပ်တော့" "ကျော်ရန်" "ဖန်သားပြင်လှည့်ရန်" + + "ပညာရေး လုပ်ဆောင်စရာဘား ပြထားသည်" "ပညာရေး လုပ်ဆောင်စရာဘား ပိတ်ထားသည်" "အက်ပ်များပြောင်းရန် လုပ်ဆောင်စရာဘားကို သုံးပါ" @@ -110,6 +112,10 @@ "လတ်တလောများ" "အကြောင်းကြားချက်" "အမြန်ဆက်တင်များ" + + + + "အပေါ်/ဘယ်ဘက်သို့ ရွှေ့ရန်" "အောက်ခြေ/ညာဘက်သို့ ရွှေ့ရန်" diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml index 4045c7c80a..bf4daa7fd1 100644 --- a/quickstep/res/values-nb/strings.xml +++ b/quickstep/res/values-nb/strings.xml @@ -77,23 +77,25 @@ "Veiledning %1$d/%2$d" "Alt er klart!" "Sveip opp for å gå til startskjermen" - + "Trykk på hjemknappen for å gå til startskjermen" + + + - "Du er klar til å begynne å bruke telefonen" - "Du er klar til å begynne å bruke nettbrettet" "Innstillinger for systemnavigasjon" "Del" "Skjermdump" "Del opp" "Trykk på en annen app for å bruke delt skjerm" - - + "Velg en annen app for å bruke delt skjerm" "Appen eller organisasjonen din tillater ikke denne handlingen" "Vil du hoppe over navigeringsveiledningen?" "Du kan finne dette i %1$s-appen senere" "Avbryt" "Hopp over" "Rotér skjermen" + + "Opplæringen for oppgavelinjen vises" "Opplæringen for oppgavelinjen er lukket" "Bruk oppgavelinjen for å bytte app" @@ -110,6 +112,10 @@ "Nylige" "Varsler" "Hurtiginnst." + + + + "Flytt til øverst/venstre" "Flytt til nederst/høyre" diff --git a/quickstep/res/values-ne/strings.xml b/quickstep/res/values-ne/strings.xml index fe081fec42..d856d7cae5 100644 --- a/quickstep/res/values-ne/strings.xml +++ b/quickstep/res/values-ne/strings.xml @@ -77,23 +77,25 @@ "ट्युटोरियल %1$d/%2$d" "सबै तयार भयो!" "होममा जान माथितिर स्वाइप गर्नुहोस्" - + "आफ्नो होम स्क्रिनमा जान होम बटनमा ट्याप गर्नुहोस्" + + + - "तपाईं आफ्नो फोन चलाउन थाल्न सक्नुहुन्छ" - "तपाईं अब आफ्नो ट्याब्लेट चलाउन थाल्न सक्नुहुन्छ" "सिस्टम नेभिगेसनसम्बन्धी सेटिङ" "सेयर गर्नुहोस्" "स्क्रिनसट" "स्प्लिट गर्नुहोस्" "स्प्लिटक्रिन प्रयोग गर्न अर्को एपमा ट्याप गर्नुहोस्" - - + "स्प्लिट स्क्रिन प्रयोग गर्न अर्को एप रोज्नुहोस्" "यो एप वा तपाईंको सङ्गठनले यो कारबाही गर्ने अनुमति दिँदैन" "नेभिगेसन ट्युटोरियल स्किप गर्ने हो?" "तपाईं पछि %1$s नामक एपमा गई यो ट्युटोरियल भेट्टाउन सक्नुहुन्छ" "रद्द गर्नुहोस्" "स्किप गर्नु…" "स्क्रिन घुमाउनुहोस्" + + "टास्कबार एजुकेसन देखिएको छ" "टास्कबार एजुकेसन बन्द गरिएको छ" "एउटा एपबाट अर्को एपमा जान टास्कबार प्रयोग गर्नुहोस्" @@ -110,6 +112,10 @@ "हालसालैका बटनहरू" "सूचनाहरू" "द्रुत सेटिङ" + + + + "सिरान/बायाँतिर सार्नुहोस्" "फेद/दायाँतिर सार्नुहोस्" diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml index 543983310e..4887930cef 100644 --- a/quickstep/res/values-nl/strings.xml +++ b/quickstep/res/values-nl/strings.xml @@ -77,23 +77,25 @@ "Tutorial %1$d/%2$d" "Klaar" "Swipe omhoog om naar het startscherm te gaan" - + "Tik op de startknop om naar je startscherm te gaan" + + + - "Je bent klaar om je telefoon te gebruiken" - "Je bent klaar om je tablet te gebruiken" "Navigatie-instellingen van systeem" "Delen" "Screenshot" "Splitsen" "Tik op nog een app om je scherm te splitsen" - - + "Kies andere app om gesplitst scherm te gebruiken" "Deze actie wordt niet toegestaan door de app of je organisatie" "Navigatietutorial overslaan?" "Je vindt dit later terug in de app %1$s" "Annuleren" "Overslaan" "Scherm draaien" + + "Uitleg van taakbalk geopend" "Uitleg van taakbalk gesloten" "Gebruik de taakbalk om van app te wisselen" @@ -110,6 +112,10 @@ "Recent" "Meldingen" "Snelle instellingen" + + + + "Naar boven/links verplaatsen" "Naar beneden/rechts verplaatsen" diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml index aa998bab5f..9a0681f68b 100644 --- a/quickstep/res/values-or/strings.xml +++ b/quickstep/res/values-or/strings.xml @@ -77,23 +77,25 @@ "ଟ୍ୟୁଟୋରିଆଲ୍ %1$d/%2$d" "ସମ୍ପୂର୍ଣ୍ଣ ଭାବେ ପ୍ରସ୍ତୁତ!" "ହୋମକୁ ଯିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ କରନ୍ତୁ" - + "ଆପଣଙ୍କ ହୋମ ସ୍କ୍ରିନକୁ ଯିବା ପାଇଁ ହୋମ ବଟନରେ ଟାପ କରନ୍ତୁ" + + + - "ଆପଣ ଆପଣଙ୍କ ଫୋନ୍ ବ୍ୟବହାର କରିବା ପାଇଁ ପ୍ରସ୍ତୁତ ଅଛନ୍ତି" - "ଆପଣ ଆପଣଙ୍କ ଟାବଲେଟ ବ୍ୟବହାର କରିବା ଆରମ୍ଭ କରିବାକୁ ପ୍ରସ୍ତୁତ ଅଛନ୍ତି" "ସିଷ୍ଟମ ନାଭିଗେସନ ସେଟିଂସ" "ସେୟାର୍ କରନ୍ତୁ" "ସ୍କ୍ରିନସଟ୍" "ସ୍ପ୍ଲିଟ୍" "ସ୍ପ୍ଲିଟସ୍କ୍ରିନ ବ୍ୟବହାର କରିବାକୁ ଅନ୍ୟ ଏକ ଆପରେ ଟାପ କର" - - + "ସ୍ପ୍ଲିଟ ସ୍କ୍ରିନ ବ୍ୟବହାର କରିବାକୁ ଅନ୍ୟ ଏକ ଆପ ବାଛନ୍ତୁ" "ଆପ୍ କିମ୍ବା ଆପଣଙ୍କ ସଂସ୍ଥା ଦ୍ୱାରା ଏହି କାର୍ଯ୍ୟକୁ ଅନୁମତି ଦିଆଯାଇ ନାହିଁ" "ନାଭିଗେସନ୍ ଟ୍ୟୁଟୋରିଆଲକୁ ବାଦ୍ ଦେବେ?" "ଆପଣ ପରେ ଏହାକୁ %1$s ଆପରେ ପାଇପାରିବେ" "ବାତିଲ କରନ୍ତୁ" "ବାଦ୍ ଦିଅନ୍ତୁ" "ସ୍କ୍ରିନ ଘୂରାନ୍ତୁ" + + "ଟାସ୍କବାର୍ ଶିକ୍ଷା ଦେଖାଯାଇଛି" "ଟାସ୍କବାର୍ ଶିକ୍ଷା ବନ୍ଦ ହୋଇଯାଇଛି" "ଆପଗୁଡ଼ିକୁ ସ୍ୱିଚ କରିବା ପାଇଁ ଟାସ୍କବାର ବ୍ୟବହାର କରନ୍ତୁ" @@ -110,6 +112,10 @@ "ବର୍ତ୍ତମାନର" "ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ" "କ୍ୱିକ ସେଟିଂସ" + + + + "ଶୀର୍ଷ/ବାମକୁ ମୁଭ କରନ୍ତୁ" "ନିମ୍ନ/ଡାହାଣକୁ ମୁଭ କରନ୍ତୁ" diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml index 4bcf4d6ae2..f217d32835 100644 --- a/quickstep/res/values-pa/strings.xml +++ b/quickstep/res/values-pa/strings.xml @@ -77,23 +77,25 @@ "ਟਿਊਟੋਰੀਅਲ %1$d/%2$d" "ਪੂਰੀ ਤਰ੍ਹਾਂ ਤਿਆਰ!" "ਹੋਮ \'ਤੇ ਜਾਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ" - + "ਆਪਣੀ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਜਾਣ ਲਈ ਹੋਮ ਬਟਨ \'ਤੇ ਟੈਪ ਕਰੋ" + + + - "ਤੁਸੀਂ ਆਪਣਾ ਫ਼ੋਨ ਵਰਤਣ ਲਈ ਤਿਆਰ ਹੋ" - "ਤੁਸੀਂ ਆਪਣਾ ਟੈਬਲੈੱਟ ਵਰਤਣ ਲਈ ਤਿਆਰ ਹੋ" "ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਸੈਟਿੰਗਾਂ" "ਸਾਂਝਾ ਕਰੋ" "ਸਕ੍ਰੀਨਸ਼ਾਟ" "ਸਪਲਿਟ" "ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਰਤਣ ਲਈ ਕਿਸੇ ਹੋਰ ਐਪ \'ਤੇ ਟੈਪ ਕਰੋ" - - + "ਸਪਲਿਟ ਸਕ੍ਰੀਨ ਵਰਤਣ ਲਈ ਕਿਸੇ ਹੋਰ ਐਪ ਨੂੰ ਚੁਣੋ" "ਐਪ ਜਾਂ ਤੁਹਾਡੀ ਸੰਸਥਾ ਵੱਲੋਂ ਇਸ ਕਾਰਵਾਈ ਦੀ ਇਜਾਜ਼ਤ ਨਹੀਂ ਹੈ" "ਕੀ ਨੈਵੀਗੇਸ਼ਨ ਟਿਊਟੋਰੀਅਲ ਨੂੰ ਛੱਡਣਾ ਹੈ?" "ਤੁਸੀਂ ਇਸਨੂੰ ਬਾਅਦ ਵਿੱਚ %1$s ਐਪ ਵਿੱਚ ਲੱਭ ਸਕਦੇ ਹੋ" "ਰੱਦ ਕਰੋ" "ਛੱਡੋ" "ਸਕ੍ਰੀਨ ਘੁਮਾਓ" + + "ਟਾਸਕਵਾਰ ਸਿੱਖਿਆ ਪੈਨਲ ਦਿਖਾਇਆ ਗਿਆ" "ਟਾਸਕਵਾਰ ਸਿੱਖਿਆ ਪੈਨਲ ਬੰਦ ਕੀਤਾ ਗਿਆ" "ਐਪਾਂ ਸਵਿੱਚ ਕਰਨ ਲਈ ਟਾਸਕਬਾਰ ਵਰਤੋ" @@ -110,6 +112,10 @@ "ਹਾਲੀਆ" "ਸੂਚਨਾਵਾਂ" "ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ" + + + + "ਸਿਖਰਲੇ/ਖੱਬੇ ਪਾਸੇ ਲੈ ਕੇ ਜਾਓ" "ਹੇਠਾਂ/ਸੱਜੇ ਪਾਸੇ ਲੈ ਕੇ ਜਾਓ" diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml index 0394bb7f72..99aae6f9d7 100644 --- a/quickstep/res/values-pl/strings.xml +++ b/quickstep/res/values-pl/strings.xml @@ -79,8 +79,10 @@ "Aby przejść na ekran główny, przesuń palcem w górę" - "Teraz możesz zacząć używać telefonu" - "Teraz możesz zacząć używać tabletu" + + + + "Ustawienia nawigacji w systemie" "Udostępnij" "Zrzut ekranu" @@ -94,6 +96,8 @@ "Anuluj" "Pomiń" "Obróć ekran" + + "Wskazówki na temat paska zadań zostały wyświetlone" "Wskazówki na temat paska zadań zostały zamknięte" "Używaj paska zadań, aby przełączać aplikacje" @@ -110,6 +114,10 @@ "Ostatnie" "Powiadomienia" "Szybkie ustawienia" + + + + "Przesuń w górny lewy róg" "Przesuń w dolny prawy róg" diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml index 47bc834b64..8aadb338c6 100644 --- a/quickstep/res/values-pt-rPT/strings.xml +++ b/quickstep/res/values-pt-rPT/strings.xml @@ -77,23 +77,25 @@ "Tutorial %1$d/%2$d" "Tudo pronto!" "Deslize rapidamente para cima para aceder ao ecrã principal" - + "Toque no botão página inicial para aceder ao ecrã principal" + + + - "Já pode começar a utilizar o seu telemóvel" - "Já pode começar a usar o seu tablet" "Definições de navegação do sistema" "Partilhar" "Fazer captura de ecrã" "Dividir" "Toque noutra app para utilizar o ecrã dividido" - - + "Escolher outra app para usar o ecrã dividido" "Esta ação não é permitida pela app ou a sua entidade." "Ignorar o tutorial de navegação?" "Pode encontrar isto mais tarde na app %1$s" "Cancelar" "Ignorar" "Rodar ecrã" + + "Informação da barra de tarefas apresentada" "Informação da barra de tarefas fechada" "Utilize a barra de ferramentas para alternar entre apps" @@ -110,6 +112,10 @@ "Recentes" "Notificações" "Definiç. rápidas" + + + + "Mover para a parte superior esquerda" "Mover para a part superior direita" diff --git a/quickstep/res/values-pt/strings.xml b/quickstep/res/values-pt/strings.xml index 6a366089f1..4b2bc9c7fa 100644 --- a/quickstep/res/values-pt/strings.xml +++ b/quickstep/res/values-pt/strings.xml @@ -77,23 +77,25 @@ "Tutorial %1$d/%2$d" "Tudo pronto!" "Deslize para cima para acessar a tela inicial" - + "Toque no botão home para ir para a tela inicial" + + + - "Você já pode começar a usar seu smartphone" - "Você já pode começar a usar seu tablet" "Configurações de navegação do sistema" "Compartilhar" "Capturar tela" "Dividir" "Toque em outro app para dividir a tela" - - + "Escolha outro app para usar na tela dividida" "Essa ação não é permitida pelo app ou pela organização" "Pular o tutorial de navegação?" "Veja o tutorial mais tarde no app %1$s" "Cancelar" "Pular" "Girar a tela" + + "As dicas sobre a barra de tarefas foram abertas" "As dicas sobre a barra de tarefas foram fechadas" "Use a barra de tarefas para alternar entre apps" @@ -110,6 +112,10 @@ "Recentes" "Notificações" "Config. rápidas" + + + + "Mover para cima/para a esquerda" "Mover para baixo/para a direita" diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml index 9856a6c1e1..33d1fef59f 100644 --- a/quickstep/res/values-ro/strings.xml +++ b/quickstep/res/values-ro/strings.xml @@ -77,23 +77,25 @@ "Tutorialul %1$d / %2$d" "Gata!" "Glisează în sus pentru a accesa ecranul de pornire" - + "Atinge butonul ecran de pornire ca să accesezi ecranul de pornire" + + + - "Ești gata să folosești telefonul" - "Ești gata să folosești tableta" "Setările de navigare ale sistemului" "Distribuie" "Captură de ecran" "Împărțit" "Atinge altă aplicație pentru ecranul împărțit" - - + "Alege altă aplicație pentru ecranul împărțit" "Această acțiune nu este permisă de aplicație sau de organizația ta" "Omiți tutorialul de navigare?" "Îl poți găsi mai târziu în aplicația %1$s" "Anulează" "Omite" "Rotește ecranul" + + "Panoul cu informații despre bara de activități s-a afișat" "Panoul cu informații despre bara de activități s-a închis" "Folosește bara de activități ca să comuți între aplicații" @@ -110,6 +112,10 @@ "Recente" "Notificări" "Setări rapide" + + + + "Mută în stânga sus" "Mută în dreapta jos" diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml index de3343e10a..23528fde76 100644 --- a/quickstep/res/values-ru/strings.xml +++ b/quickstep/res/values-ru/strings.xml @@ -77,23 +77,25 @@ "Руководство (шаг %1$d из %2$d)" "Готово!" "Чтобы перейти на главный экран, проведите вверх." - + "Нажмите кнопку главного экрана, чтобы открыть его." + + + - "Теперь вы можете использовать телефон." - "Теперь вы можете использовать планшет." "Системные настройки навигации" "Поделиться" "Скриншот" "Разделить" "Для разделения экрана нажмите на другое приложение." - - + "Выберите другое приложение для разделения экрана." "Это действие заблокировано приложением или организацией." "Пропустить руководство по жестам?" "Его можно найти в приложении \"%1$s\"." "Отмена" "Пропустить" "Повернуть экран" + + "Обучение по работе с панелью задач показано" "Обучение по работе с панелью задач скрыто" "Используйте панель задач, чтобы переключать приложения." @@ -110,6 +112,10 @@ "Недавние" "Уведомления" "Быстрые настройки" + + + + "Переместить вверх или влево" "Переместить вниз или вправо" diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml index 509490c612..e18f512045 100644 --- a/quickstep/res/values-si/strings.xml +++ b/quickstep/res/values-si/strings.xml @@ -77,23 +77,25 @@ "නිබන්ධනය %1$d/%2$d" "සියල්ල සූදානම්!" "මුල් පිටුවට යාමට ඉහළට ස්වයිප් කරන්න" - + "ඔබේ මුල් තිරය වෙත යාමට මුල් පිටුව බොත්තම තට්ටු කරන්න" + + + - "ඔබ ඔබගේ දුරකථනය භාවිත කිරීම පටන් ගැනීමට සූදානම්" - "ඔබ ඔබගේ ටැබ්ලටය භාවිත කිරීම පටන් ගැනීමට සූදානම්" "පද්ධති සංචාලන සැකසීම්" "බෙදා ගන්න" "තිර රුව" "බෙදන්න" "බෙදුම් තිරය භාවිත කිරීමට තවත් යෙදුමක් තට්ටු කරන්න" - - + "බෙදීම් තිරය භාවිතා කිරීමට වෙනත් යෙදුමක් තෝරා ගන්න" "මෙම ක්‍රියාව යෙදුම හෝ ඔබේ සංවිධානය මගින් ඉඩ නොදේ" "නිබන්ධනය සංචාලනය මඟ හරින්නද?" "ඔබට මෙය පසුව %1$s යෙදුම තුළ සොයා ගත හැකිය" "අවලංගු කරන්න" "මඟ හරින්න" "තිරය කරකවන්න" + + "කාර්ය තීරු අධ්‍යාපනය දිස් විය" "කාර්ය තීරු අධ්‍යාපනය වසා ඇත" "යෙදුම් මාරු කිරීමට කාර්ය තීරුව භාවිත කරන්න" @@ -110,6 +112,10 @@ "මෑත" "දැනුම්දීම්" "ඉක්මන් සැකසීම්" + + + + "ඉහළ/වම වෙත ගෙන යන්න" "පහළ/දකුණ වෙත ගෙන යන්න" diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml index f9372def02..523080d96c 100644 --- a/quickstep/res/values-sk/strings.xml +++ b/quickstep/res/values-sk/strings.xml @@ -77,23 +77,25 @@ "Návod %1$d/%2$d" "Hotovo" "Potiahnutím nahor prejdete na plochu" - + "Na plochu prejdete klepnutím na tlačidlo plochy" + + + - "Telefón môžete začať používať" - "Tablet môžete začať používať" "Nastavenia navigácie systémom" "Zdieľať" "Snímka obrazovky" "Rozdeliť" "Rozdel. obrazovku spustíte klepnutím na inú aplik." - - + "Na použitie rozd. obrazovky vyberte inú aplikáciu" "Aplikácia alebo vaša organizácia túto akciu nepovoľuje" "Chcete preskočiť návod na navigáciu?" "Tento návod nájdete v aplikácii %1$s" "Zrušiť" "Preskočiť" "Otočiť obrazovku" + + "Zobrazila sa výuka k hlavnému panelu" "Výuka k hlavnému panelu bola zatvorená" "Aplikácie je možné prepínať pomocou panela úloh" @@ -110,6 +112,10 @@ "Nedávne" "Upozornenia" "Rýchle nastavenia" + + + + "Presunúť hore alebo doľava" "Presunúť dole alebo doprava" diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml index 0a5a271462..c80a899480 100644 --- a/quickstep/res/values-sl/strings.xml +++ b/quickstep/res/values-sl/strings.xml @@ -77,23 +77,25 @@ "Vadnica %1$d/%2$d" "Končano" "Povlecite navzgor za začetni zaslon" - + "Za pomik na začetni zaslon se dotaknite gumba za začetni zaslon." + + + - "Pripravljeni ste, da začnete uporabljati telefon" - "Pripravljeni ste, da začnete uporabljati tablični računalnik." "Nastavitve krmarjenja po sistemu" "Deli" "Posnetek zaslona" "Razdeli" "Za uporabo razdeljenega zaslona se dotaknite še ene aplikacije." - - + "Izberite drugo aplikacijo za uporabo razdeljenega zaslona." "Aplikacija ali vaša organizacija ne dovoljuje tega dejanja" "Želite preskočiti vadnico za krmarjenje?" "To lahko pozneje najdete v aplikaciji %1$s." "Prekliči" "Preskoči" "Sukanje zaslona" + + "Poučni nasveti o opravilni vrstici so prikazani." "Poučni nasveti o opravilni vrstici so zaprti." "Za preklop aplikacij uporabite opravilno vrstico." @@ -110,6 +112,10 @@ "Nedavno" "Obvestila" "Hitre nastavitve" + + + + "Premakni na vrh/levo" "Premakni na dno/desno" diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml index f326693364..33a8f9f2f5 100644 --- a/quickstep/res/values-sq/strings.xml +++ b/quickstep/res/values-sq/strings.xml @@ -79,8 +79,10 @@ "Rrëshqit shpejt lart për të shkuar tek \"Ekrani bazë\"" - "Je gati për të filluar përdorimin e telefonit tënd" - "Je gati që të fillosh të përdorësh tabletin" + + + + "Cilësimet e navigimit të sistemit" "Ndaj" "Pamja e ekranit" @@ -94,6 +96,8 @@ "Anulo" "Kapërce" "Rrotullo ekranin" + + "Edukimi i shiritit të detyrave u shfaq" "Edukimi nga shiriti i detyrave u mbyll" "Përdor shiritin e detyrave për të ndryshuar aplikacionet" @@ -110,6 +114,10 @@ "Të fundit" "Njoftimet" "Cilësimet shpejt" + + + + "Lëviz në krye/majtas" "Lëviz në fund/djathtas" diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml index 518023aeac..e53a5a45ac 100644 --- a/quickstep/res/values-sr/strings.xml +++ b/quickstep/res/values-sr/strings.xml @@ -77,23 +77,25 @@ "Водич %1$d/%2$d" "Готово!" "Превуците нагоре да бисте отворили почетни екран" - + "Додирните дугме Почетак да бисти ишли на почетни екран" + + + - "Спремни сте да почнете да користите телефон" - "Спремни сте да почнете да користите таблет" "Подешавања кретања кроз систем" "Дели" "Снимак екрана" "Подели" "Додирните другу апликацију за подељени екран" - - + "Одаберите другу апликацију за подељени екран" "Апликација или организација не дозвољавају ову радњу" "Желите да прескочите водич за кретање?" "Можете да пронађете ово касније у апликацији %1$s" "Откажи" "Прескочи" "Ротирајте екран" + + "Едукативно окно из траке задатака се појавило" "Едукативно окно из траке задатака је затворено" "Користите траку задатака да бисте мењали апликације" @@ -110,6 +112,10 @@ "Недавно" "Обавештења" "Брза подешавања" + + + + "Премести горе лево" "Премести доле десно" diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml index 2d9db938d3..8c3ea532a2 100644 --- a/quickstep/res/values-sv/strings.xml +++ b/quickstep/res/values-sv/strings.xml @@ -77,23 +77,25 @@ "Självstudie %1$d/%2$d" "Klart!" "Svep uppåt för att öppna startskärmen" - + "Tryck på hemknappen för att öppna startskärmen" + + + - "Nu kan du börja använda telefonen" - "Nu kan du börja använda surfplattan" "Systemnavigeringsinställningar" "Dela" "Skärmbild" "Delat" "Tryck på en annan app för att använda delad skärm" - - + "Välj en annan app för att använda delad skärm" "Appen eller organisationen tillåter inte den här åtgärden" "Vill du hoppa över självstudierna?" "Du hittar det här igen i %1$s-appen" "Avbryt" "Hoppa över" "Rotera skärmen" + + "Information om aktivitetsfältet visades" "Information om aktivitetsfältet stängdes" "Använd aktivitetsfältet för att byta mellan appar" @@ -110,6 +112,10 @@ "Senaste" "Aviseringar" "Snabbinställn." + + + + "Flytta högst upp/till vänster" "Flytta längst ned/till höger" diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml index aadf378f1f..5bba2c5b3d 100644 --- a/quickstep/res/values-sw/strings.xml +++ b/quickstep/res/values-sw/strings.xml @@ -79,8 +79,10 @@ "Telezesha kidole juu ili uende kwenye skrini ya kwanza" - "Uko tayari kuanza kutumia simu yako" - "Uko tayari kuanza kutumia kompyuta kibao yako" + + + + "Mipangilio ya usogezaji kwenye mfumo" "Shiriki" "Picha ya skrini" @@ -94,6 +96,8 @@ "Ghairi" "Ruka" "Zungusha skrini" + + "Paneli ya elimu kwenye upau wa shughuli inaonyeshwa" "Paneli ya elimu kwenye upau wa shughuli imefungwa" "Tumia upau wa shughuli kubadilisha programu" @@ -110,6 +114,10 @@ "Vilivyotumika majuzi" "Arifa" "Mipangilio ya Haraka" + + + + "Sogeza juu/kushoto" "Sogeza chini/kulia" diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml index 77c3c37d98..58bcf80919 100644 --- a/quickstep/res/values-ta/strings.xml +++ b/quickstep/res/values-ta/strings.xml @@ -79,8 +79,10 @@ "முகப்புத் திரைக்குச் செல்ல மேல்நோக்கி ஸ்வைப் செய்யுங்கள்" - "மொபைலைப் பயன்படுத்தத் தயாராகிவிட்டீர்கள்" - "உங்கள் டேப்லெட்டைப் பயன்படுத்தத் தயாராகிவிட்டீர்கள்" + + + + "சிஸ்டம் வழிசெலுத்தல் அமைப்புகள்" "பகிர்" "ஸ்கிரீன்ஷாட்" @@ -94,6 +96,8 @@ "ரத்துசெய்" "தவிர்" "திரையைச் சுழற்றும்" + + "பணிப்பட்டியை எவ்வாறு பயன்படுத்துவது என்பது பற்றிய பலகம் காட்டப்படுகிறது" "பணிப்பட்டியை எவ்வாறு பயன்படுத்துவது என்பது பற்றிய பலகம் மூடப்பட்டது" "ஆப்ஸிற்கு இடையே மாற பணிப்பட்டியைப் பயன்படுத்தவும்" @@ -110,6 +114,10 @@ "சமீபத்தியவை" "அறிவிப்புகள்" "விரைவு அமைப்புகள்" + + + + "மேலே/இடதுபுறம் நகர்த்தும்" "கீழே/வலதுபுறம் நகர்த்தும்" diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml index 052ca5d477..313fa4c002 100644 --- a/quickstep/res/values-te/strings.xml +++ b/quickstep/res/values-te/strings.xml @@ -77,23 +77,25 @@ "ట్యుటోరియల్ %1$d/%2$d" "అంతా సెట్ అయింది!" "మొదటి స్క్రీన్‌కు వెళ్లడానికి పైకి స్వైప్ చేయండి" - + "మీ మొదటి స్క్రీన్‌కు వెళ్లడానికి హోమ్ బటన్‌ను ట్యాప్ చేయండి" + + + - "మీరు మీ ఫోన్‌ను ఉపయోగించడానికి సిద్ధంగా ఉన్నారు" - "మీరు మీ టాబ్లెట్‌ను ఉపయోగించడానికి సిద్ధంగా ఉన్నారు" "సిస్టమ్ నావిగేషన్ సెట్టింగ్‌లు" "షేర్ చేయండి" "స్క్రీన్‌షాట్" "స్ప్లిట్ చేయండి" "స్క్రీన్ విభజనను ఉపయోగించడానికి మరొక యాప్ నొక్కండి" - - + "స్ప్లిట్ స్క్రీన్ ఉపయోగానికి మరొక యాప్ ఎంచుకోండి" "ఈ చర్యను యాప్ గానీ, మీ సంస్థ గానీ అనుమతించవు" "నావిగేషన్ ట్యుటోరియల్‌ను స్కిప్ చేయాలా?" "%1$s యాప్‌లో మీరు తర్వాత కనుగొనవచ్చు" "రద్దు చేయి" "స్కిప్ చేయండి" "స్క్రీన్‌ను తిప్పండి" + + "టాస్క్‌బార్ శిక్షణకు సంబంధించిన ప్యానెల్ కనిపించింది" "టాస్క్‌బార్ శిక్షణకు సంబంధించిన ప్యానెల్ మూసివేయబడింది" "యాప్‌లను స్విచ్ చేయడానికి టాస్క్‌బార్‌ను ఉపయోగించండి" @@ -110,6 +112,10 @@ "ఇటీవలివి" "నోటిఫికేషన్‌లు" "క్విక్ సెట్టింగ్‌లు" + + + + "ఎగువ/ఎడమ వైపునకు తరలించండి" "దిగువ/కుడి వైపునకు తరలించండి" diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml index 13f0e12c90..d338c50d1e 100644 --- a/quickstep/res/values-th/strings.xml +++ b/quickstep/res/values-th/strings.xml @@ -77,23 +77,25 @@ "บทแนะนำ %1$d/%2$d" "เรียบร้อยแล้ว" "ปัดขึ้นเพื่อไปที่หน้าแรก" - + "แตะปุ่มหน้าแรกเพื่อไปที่หน้าจอหลัก" + + + - "คุณเริ่มใช้โทรศัพท์ได้แล้ว" - "คุณเริ่มใช้แท็บเล็ตได้แล้ว" "การตั้งค่าการนำทางของระบบ" "แชร์" "ภาพหน้าจอ" "แยก" "แตะที่แอปอื่นเพื่อใช้แบ่งหน้าจอ" - - + "เลือกแอปอื่นเพื่อใช้การแยกหน้าจอ" "แอปหรือองค์กรของคุณไม่อนุญาตการดำเนินการนี้" "ข้ามบทแนะนำการนำทางไหม" "คุณดูบทแนะนำนี้ได้ภายหลังในแอป \"%1$s\"" "ยกเลิก" "ข้าม" "หมุนหน้าจอ" + + "แถบงาน Education ปรากฎขึ้น" "ปิดแถบงาน Education แล้ว" "ใช้แถบงานเพื่อเปลี่ยนแอป" @@ -110,6 +112,10 @@ "ล่าสุด" "การแจ้งเตือน" "การตั้งค่าด่วน" + + + + "ย้ายไปที่ด้านบนหรือด้านซ้าย" "ย้ายไปที่ด้านล่างหรือด้านขวา" diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml index 68b39025fd..2efb9beae9 100644 --- a/quickstep/res/values-tl/strings.xml +++ b/quickstep/res/values-tl/strings.xml @@ -77,23 +77,25 @@ "Tutorial %1$d/%2$d" "Handa na ang lahat!" "Mag-swipe pataas para pumunta sa Home" - + "I-tap ang button ng home para pumunta sa iyong home screen" + + + - "Handa mo nang simulan ang paggamit sa iyong telepono" - "Handa mo nang simulan ang paggamit sa iyong tablet" "Mga setting ng navigation ng system" "Ibahagi" "Screenshot" "Split" "Mag-tap ng ibang app para gamitin ang splitscreen" - - + "Pumili ng ibang app para gamitin ang split screen" "Hindi pinapayagan ng app o ng iyong organisasyon ang pagkilos na ito" "Laktawan ang tutorial sa pag-navigate?" "Makikita mo ito sa %1$s app sa ibang pagkakataon" "Kanselahin" "Laktawan" "I-rotate ang screen" + + "Lumabas ang edukasyon sa taskbar" "Sarado ang edukasyon sa taskbar" "Gamitin ang taskbar para magpalipat-lipat sa mga app" @@ -110,6 +112,10 @@ "Mga Kamakailan" "Mga Notification" "Quick Settings" + + + + "Ilipat sa itaas/kaliwa" "Ilipat sa ibaba/kanan" diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml index c7f7ac9b28..c3ebde3f32 100644 --- a/quickstep/res/values-tr/strings.xml +++ b/quickstep/res/values-tr/strings.xml @@ -77,23 +77,25 @@ "Eğitim %1$d/%2$d" "İşlem tamam!" "Ana ekrana gitmek için yukarı kaydırın" - + "Ana ekranınıza gitmek için ana sayfa düğmesine dokunun" + + + - "Telefonunuzu kullanmaya hazırsınız" - "Tabletinizi kullanmaya hazırsınız" "Sistem gezinme ayarları" "Paylaş" "Ekran görüntüsü" "Böl" "Bölünmüş ekran için başka bir uygulamaya dokunun" - - + "Bölünmüş ekran kullanmak için başka bir uygulama seçin" "Uygulamanız veya kuruluşunuz bu işleme izin vermiyor" "Gezinme eğitimi atlansın mı?" "Bunu daha sonra %1$s uygulamasında bulabilirsiniz" "İptal" "Atla" "Ekranı döndür" + + "Görev çubuğu eğitimi görüntülendi" "Görev çubuğu eğitimi kapatıldı" "Görev çubuğundan uygulamalar arasında geçiş yapabilirsiniz" @@ -110,6 +112,10 @@ "Son Kullanılanlar" "Bildirimler" "Hızlı Ayarlar" + + + + "Sol üste taşı" "Sağ alta taşı" diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml index 173f637f09..f47ea648e1 100644 --- a/quickstep/res/values-uk/strings.xml +++ b/quickstep/res/values-uk/strings.xml @@ -79,8 +79,10 @@ "Щоб перейти на головний екран, проведіть пальцем угору" - "Тепер ви можете користуватися телефоном" - "Тепер ви можете користуватися планшетом" + + + + "Системні налаштування навігації" "Поділитися" "Знімок екрана" @@ -94,6 +96,8 @@ "Скасувати" "Пропустити" "Обернути екран" + + "Панель завдань Education відкрито" "Панель завдань Education закрито" "Переходьте між додатками за допомогою панелі завдань" @@ -110,6 +114,10 @@ "Нещодавні" "Сповіщення" "Швидкі налаштув." + + + + "Перемістити вгору або вліво" "Перемістити вниз або вправо" diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml index 89e518b0ed..aaf35ff783 100644 --- a/quickstep/res/values-ur/strings.xml +++ b/quickstep/res/values-ur/strings.xml @@ -77,23 +77,25 @@ "ٹیوٹوریل %1$d/%2$d" "سب کچھ تیار ہے!" "ہوم پر جانے کے لیے اوپر سوائپ کریں" - + "اپنی ہوم اسکرین پر جانے کے لیے ہوم بٹن پر تھپتھپائیں" + + + - "آپ اپنا فون استعمال شروع کرنے کے لیے تیار ہیں" - "آپ اپنے ٹیبلیٹ کا استعمال شروع کرنے کے لیے تیار ہیں" "سسٹم نیویگیشن کی ترتیبات" "اشتراک کریں" "اسکرین شاٹ" "اسپلٹ" "اسپلٹ اسکرین کا استعمال کرنے کیلئے دوسری ایپ پر تھپتھپائیں" - - + "اسپلٹ اسکرین کے استعمال کیلئے دوسری ایپ منتخب کریں" "ایپ یا آپ کی تنظیم کی جانب سے اس کارروائی کی اجازت نہیں ہے" "نیویگیشن کا ٹیوٹوریل نظر انداز کریں؟" "آپ اسے بعد میں %1$s ایپ میں تلاش کر سکتے ہیں" "منسوخ کریں" "نظر انداز کریں" "اسکرین کو گھمائیں" + + "ٹاکس بار کا تعلیمی پینل ظاہر ہو گیا" "ٹاسک بار کا تعلیمی پینل بند ہو گیا" "ایپس کو سوئچ کرنے کیلئے ٹاسک بار کا استعمال کریں" @@ -110,6 +112,10 @@ "حالیہ" "اطلاعات" "فوری ترتیبات" + + + + "اوپر/بائیں طرف منتقل کریں" "نیچے/دائیں طرف منتقل کریں" diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml index 56a76d5f58..5af96eb57e 100644 --- a/quickstep/res/values-uz/strings.xml +++ b/quickstep/res/values-uz/strings.xml @@ -77,23 +77,25 @@ "Darslik: %1$d/%2$d" "Hammasi tayyor!" "Boshiga qaytish uchun tepaga suring" - + "Bosh ekranga oʻtish uchun bosh ekran tugmasini bosing" + + + - "Telefoningiz xizmatga tayyor" - "Planshetingiz xizmatga tayyor" "Tizim navigatsiya sozlamalari" "Ulashish" "Skrinshot" "Ajratish" "Ekranni ikkiga ajratish uchun boshqa ilovani bosing" - - + "Ekranni ikkiga ajratish uchun boshqa ilovani tanlang" "Bu amal ilova yoki tashkilotingiz tomonidan taqiqlangan" "Navigatsiya darsi yopilsinmi?" "Bu darslar %1$s ilovasida chiqadi" "Bekor qilish" "Tashlab ketish" "Ekranni burish" + + "Taʼlim vazifalar paneli chiqdi" "Taʼlim vazifalar paneli yopildi" "Ilovalarni vazifalar panelida almashtirish mumkin" @@ -110,6 +112,10 @@ "Oxirgilar" "Bildirishnomalar" "Tezkor sozlamalar" + + + + "Yuqoriga yoki chapga oʻtkazish" "Pastga yoki oʻngga oʻtkazish" diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml index 3b17966f88..948ec2031b 100644 --- a/quickstep/res/values-vi/strings.xml +++ b/quickstep/res/values-vi/strings.xml @@ -77,23 +77,25 @@ "Hướng dẫn %1$d/%2$d" "Đã hoàn tất!" "Vuốt lên để chuyển đến Màn hình chính" - + "Nhấn vào nút màn hình chính để chuyển đến màn hình chính" + + + - "Vậy là bạn đã sẵn sàng sử dụng điện thoại của mình" - "Bạn đã sẵn sàng sử dụng máy tính bảng" "Chế độ cài đặt di chuyển trên hệ thống" "Chia sẻ" "Chụp ảnh màn hình" "Chia đôi màn hình" "Nhấn vào một ứng dụng khác để dùng màn hình chia đôi" - - + "Chọn một ứng dụng khác để dùng chế độ chia đôi màn hình" "Ứng dụng hoặc tổ chức của bạn không cho phép thực hiện hành động này" "Bỏ qua phần hướng dẫn thao tác?" "Bạn có thể tìm lại phần hướng dẫn này trong ứng dụng %1$s" "Hủy" "Bỏ qua" "Xoay màn hình" + + "Đã hiện bảng hướng dẫn trên thanh tác vụ" "Đã đóng bảng hướng dẫn trên thanh tác vụ" "Dùng thanh tác vụ để chuyển đổi ứng dụng" @@ -110,6 +112,10 @@ "Gần đây" "Thông báo" "Cài đặt nhanh" + + + + "Chuyển lên trên cùng/sang bên trái" "Chuyển xuống dưới cùng/sang bên phải" diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml index 0ff369e38d..576ae3a64e 100644 --- a/quickstep/res/values-zh-rCN/strings.xml +++ b/quickstep/res/values-zh-rCN/strings.xml @@ -77,23 +77,25 @@ "教程 %1$d/%2$d" "大功告成!" "向上滑动即可转到主屏幕" - + "点按主屏幕按钮即可前往主屏幕" + + + - "您可以开始使用手机了" - "您可以开始使用平板电脑了" "系统导航设置" "分享" "屏幕截图" "拆分" "点按另一个应用即可使用分屏" - - + "另外选择一个应用才可使用分屏模式" "该应用或您所在的单位不允许执行此操作" "要跳过导航教程吗?" "您之后可以在“%1$s”应用中找到此教程" "取消" "跳过" "旋转屏幕" + + "任务栏教程已显示" "任务栏教程已关闭" "使用任务栏切换应用" @@ -110,6 +112,10 @@ "最近用过" "通知" "快捷设置" + + + + "移到顶部/左侧" "移到底部/右侧" diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml index ff648dfe62..83337a26a9 100644 --- a/quickstep/res/values-zh-rHK/strings.xml +++ b/quickstep/res/values-zh-rHK/strings.xml @@ -77,23 +77,25 @@ "教學課程 %1$d/%2$d" "設定完成!" "向上滑動即可前往主畫面" - + "輕按主按鈕即可前往主畫面" + + + - "您可以開始使用手機了" - "您可以開始使用平板電腦了" "系統導覽設定" "分享" "螢幕截圖" "分割" "輕按其他應用程式以使用分割螢幕" - - + "選擇其他應用程式才能使用分割螢幕" "應用程式或您的機構不允許此操作" "要略過手勢操作教學課程嗎?" "您之後可以在「%1$s」應用程式找到這些說明" "取消" "略過" "旋轉螢幕" + + "顯示咗工作列教學" "閂咗工作列教學" "使用工作列即可切換應用程式" @@ -110,6 +112,10 @@ "最近" "通知" "快速設定" + + + + "移至上方/左側" "移至底部/右側" diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml index 23bee1757a..b6961a194f 100644 --- a/quickstep/res/values-zh-rTW/strings.xml +++ b/quickstep/res/values-zh-rTW/strings.xml @@ -77,23 +77,25 @@ "教學課程 %1$d/%2$d" "設定完成!" "向上滑動即可前往主畫面" - + "輕觸主畫面按鈕即可前往主畫面" + + + - "你可以開始使用手機了" - "你可以開始使用平板電腦了" "系統操作機制設定" "分享" "螢幕截圖" "分割" "輕觸另一個應用程式即可使用分割畫面" - - + "必須選擇另一個應用程式才能使用分割畫面" "這個應用程式或貴機構不允許執行這個動作" "要略過手勢操作教學課程嗎?" "你之後可以在「%1$s」應用程式找到這些說明" "取消" "略過" "旋轉螢幕" + + "工作列教學課程已顯示" "工作列教學課程已關閉" "使用工作列即可切換應用程式" @@ -110,6 +112,10 @@ "最近使用" "通知" "快速設定" + + + + "移到上方/左側" "移到底部/右側" diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml index 46ba92994f..1e6df97a0d 100644 --- a/quickstep/res/values-zu/strings.xml +++ b/quickstep/res/values-zu/strings.xml @@ -77,23 +77,25 @@ "Okokufundisa %1$d/%2$d" "Konke kusethiwe!" "Swayiphela phezulu ukuze uye Ekhaya" - + "Thepha inkinobho yasekhaya ukuze uye kusikrini sasekhaya" + + + - "Usulungele ukuqala ukusebenzisa ifoni yakho" - "Usulungele ukuqala ukusebenzisa ithebulethi yakho" "Amasethingi wokuzulazula isistimu" "Yabelana" "Isithombe-skrini" "Hlukanisa" "Thepha enye i-app ukuze usebenzise isikrini sokuhlukanisa" - - + "Khetha enye i-app ukuze usebenzise ukuhlukanisa isikrini" "Lesi senzo asivunyelwanga uhlelo lokusebenza noma inhlangano yakho" "Yeqa isifundo sokuzulazula?" "Lokhu ungakuthola kamuva ku-app ye-%1$s" "Khansela" "Yeqa" "Zungezisa isikrini" + + "Imfuno yebha yomsebenzi ivelile" "Imfundo yebha yomsebenzi ivaliwe" "Sebenzisa ibha yomsebenzi ukushintsha ama-app" @@ -110,6 +112,10 @@ "Okwakamuva" "Izaziso" "Amasethingi Asheshayo" + + + + "Hamba phezulu/kwesokunxele" "Hamba phansi/kwesokudla" From 259723de32428a62f518263c3079ba0e4eba29e4 Mon Sep 17 00:00:00 2001 From: Holly Sun Date: Tue, 22 Nov 2022 11:54:13 -0800 Subject: [PATCH 284/429] Catch exception to prevent crash. Bug: 258234624 Test: QA verify Change-Id: I31df77b33f19426d136673d1ce9866fa6e60729c --- .../android/launcher3/touch/ItemClickHandler.java | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java index b4be06159a..098cf80a3a 100644 --- a/src/com/android/launcher3/touch/ItemClickHandler.java +++ b/src/com/android/launcher3/touch/ItemClickHandler.java @@ -28,6 +28,7 @@ import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_SU import android.app.AlertDialog; import android.app.PendingIntent; +import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; import android.content.IntentSender; @@ -315,10 +316,16 @@ public class ItemClickHandler { */ public static void onClickSearchAction(Launcher launcher, SearchActionItemInfo itemInfo) { if (itemInfo.getIntent() != null) { - if (itemInfo.hasFlags(SearchActionItemInfo.FLAG_SHOULD_START_FOR_RESULT)) { - launcher.startActivityForResult(itemInfo.getIntent(), 0); - } else { - launcher.startActivity(itemInfo.getIntent()); + try { + if (itemInfo.hasFlags(SearchActionItemInfo.FLAG_SHOULD_START_FOR_RESULT)) { + launcher.startActivityForResult(itemInfo.getIntent(), 0); + } else { + launcher.startActivity(itemInfo.getIntent()); + } + } catch (ActivityNotFoundException e) { + Toast.makeText(launcher, + launcher.getResources().getText(R.string.shortcut_not_available), + Toast.LENGTH_SHORT).show(); } } else if (itemInfo.getPendingIntent() != null) { try { From 807823155d4a323df5328652bf4b26343b7f46c0 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 22 Nov 2022 15:56:12 -0800 Subject: [PATCH 285/429] Check for isTaskbarPresent in addition to isTransientTaskbar when the method is called outside of taskbar. This prevents the case where phone runs transient taskbar logic. Bug: 260006210 Test: added local logs, tested in phone mode Change-Id: I600c06d6c797bd68461ac033dcc2c6158f221024 --- .../android/quickstep/AbsSwipeUpHandler.java | 82 +++++++++++-------- .../OtherActivityInputConsumer.java | 29 +------ .../com/android/quickstep/views/TaskView.java | 2 +- 3 files changed, 50 insertions(+), 63 deletions(-) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 9aedbf8517..19ffd2ac35 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -316,6 +316,7 @@ public abstract class AbsSwipeUpHandler, private final float mQuickSwitchScaleScrollThreshold; private final int mTaskbarAppWindowThreshold; + private final int mTaskbarHomeOverviewThreshold; private final int mTaskbarCatchUpThreshold; private boolean mTaskbarAlreadyOpen; private final boolean mIsTransientTaskbar; @@ -344,21 +345,29 @@ public abstract class AbsSwipeUpHandler, mContinuingLastGesture = continuingLastGesture; Resources res = context.getResources(); - mTaskbarAppWindowThreshold = res - .getDimensionPixelSize(ENABLE_TASKBAR_REVISED_THRESHOLDS.get() - ? R.dimen.taskbar_app_window_threshold_v2 - : R.dimen.taskbar_app_window_threshold); - mTaskbarCatchUpThreshold = res.getDimensionPixelSize(R.dimen.taskbar_catch_up_threshold); - mIsTransientTaskbar = DisplayController.isTransientTaskbar(mActivity); - mQuickSwitchScaleScrollThreshold = res .getDimension(R.dimen.quick_switch_scaling_scroll_threshold); mSplashMainWindowShiftLength = -res .getDimensionPixelSize(R.dimen.starting_surface_exit_animation_window_shift_length); - initAfterSubclassConstructor(); + initTransitionEndpoints(mRemoteTargetHandles[0].getTaskViewSimulator() + .getOrientationState().getLauncherDeviceProfile()); initStateCallbacks(); + + mIsTransientTaskbar = mDp.isTaskbarPresent + && DisplayController.isTransientTaskbar(mActivity); + TaskbarUIController controller = mActivityInterface.getTaskbarController(); + mTaskbarAlreadyOpen = controller != null && !controller.isTaskbarStashed(); + mTaskbarAppWindowThreshold = res + .getDimensionPixelSize(ENABLE_TASKBAR_REVISED_THRESHOLDS.get() + ? R.dimen.taskbar_app_window_threshold_v2 + : R.dimen.taskbar_app_window_threshold); + mTaskbarHomeOverviewThreshold = res.getDimensionPixelSize( + ENABLE_TASKBAR_REVISED_THRESHOLDS.get() + ? R.dimen.taskbar_home_overview_threshold_v2 + : R.dimen.taskbar_home_overview_threshold); + mTaskbarCatchUpThreshold = res.getDimensionPixelSize(R.dimen.taskbar_catch_up_threshold); } @Nullable @@ -737,18 +746,12 @@ public abstract class AbsSwipeUpHandler, } /** - * Sets whether or not we should clamp the scroll offset. - * This is used to avoid x-axis movement when swiping up transient taskbar. - * @param clampScrollOffset When true, we clamp the scroll to 0 before the clamp threshold is - * met. + * Returns threshold that needs to be met in order for motion pause to be allowed. */ - public void setClampScrollOffset(boolean clampScrollOffset) { - if (mRecentsView == null) { - mStateCallback.runOnceAtState(STATE_LAUNCHER_PRESENT, - () -> mRecentsView.setClampScrollOffset(clampScrollOffset)); - return; - } - mRecentsView.setClampScrollOffset(clampScrollOffset); + public float getThresholdToAllowMotionPause() { + return mIsTransientTaskbar + ? mTaskbarHomeOverviewThreshold + : 0; } public void setIsLikelyToStartNewTask(boolean isLikelyToStartNewTask) { @@ -947,10 +950,33 @@ public abstract class AbsSwipeUpHandler, } notifyGestureStartedAsync(); setIsLikelyToStartNewTask(isLikelyToStartNewTask, false /* animate */); + + if (mIsTransientTaskbar && !mTaskbarAlreadyOpen && !isLikelyToStartNewTask) { + setClampScrollOffset(true); + } mStateCallback.setStateOnUiThread(STATE_GESTURE_STARTED); mGestureStarted = true; } + /** + * Sets whether or not we should clamp the scroll offset. + * This is used to avoid x-axis movement when swiping up transient taskbar. + * @param clampScrollOffset When true, we clamp the scroll to 0 before the clamp threshold is + * met. + */ + private void setClampScrollOffset(boolean clampScrollOffset) { + if (!mIsTransientTaskbar) { + return; + } + if (mRecentsView == null) { + mStateCallback.runOnceAtState(STATE_LAUNCHER_PRESENT, + () -> mRecentsView.setClampScrollOffset(clampScrollOffset)); + return; + } + mRecentsView.setClampScrollOffset(clampScrollOffset); + } + + /** * Notifies the launcher that the swipe gesture has started. This can be called multiple times. */ @@ -1177,6 +1203,8 @@ public abstract class AbsSwipeUpHandler, float currentShift = mCurrentShift.value; final GestureEndTarget endTarget = calculateEndTarget(velocity, endVelocity, isFling, isCancel); + + setClampScrollOffset(false); // Set the state, but don't notify until the animation completes mGestureState.setEndTarget(endTarget, false /* isAtomic */); mAnimationFactory.setEndTarget(endTarget); @@ -1969,15 +1997,6 @@ public abstract class AbsSwipeUpHandler, || app.windowConfiguration.getActivityType() == ACTIVITY_TYPE_HOME; } - /** - * To be called at the end of constructor of subclasses. This calls various methods which can - * depend on proper class initialization. - */ - protected void initAfterSubclassConstructor() { - initTransitionEndpoints(mRemoteTargetHandles[0].getTaskViewSimulator() - .getOrientationState().getLauncherDeviceProfile()); - } - protected void performHapticFeedback() { VibratorWrapper.INSTANCE.get(mContext).vibrate(OVERVIEW_HAPTIC); } @@ -2231,13 +2250,6 @@ public abstract class AbsSwipeUpHandler, return scaleProgress; } - /** - * Updates the current status of taskbar during this swipe. - */ - public void setTaskbarAlreadyOpen(boolean taskbarAlreadyOpen) { - mTaskbarAlreadyOpen = taskbarAlreadyOpen; - } - /** * Overrides the gesture displacement to keep the app window at the bottom of the screen while * the transient taskbar is being swiped in. diff --git a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java index bf666ea8a6..db243da3bd 100644 --- a/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java +++ b/quickstep/src/com/android/quickstep/inputconsumers/OtherActivityInputConsumer.java @@ -27,7 +27,6 @@ import static com.android.launcher3.PagedView.ACTION_MOVE_ALLOW_EASY_FLING; import static com.android.launcher3.PagedView.DEBUG_FAILED_QUICKSWITCH; import static com.android.launcher3.Utilities.EDGE_NAV_BAR; import static com.android.launcher3.Utilities.squaredHypot; -import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_REVISED_THRESHOLDS; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.TraceHelper.FLAG_CHECK_FOR_RACE_CONDITIONS; import static com.android.launcher3.util.VelocityUtils.PX_PER_MS; @@ -48,11 +47,9 @@ import androidx.annotation.UiThread; import com.android.launcher3.R; import com.android.launcher3.Utilities; -import com.android.launcher3.taskbar.TaskbarUIController; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.shared.TestProtocol; import com.android.launcher3.tracing.InputConsumerProto; -import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.TraceHelper; import com.android.quickstep.AbsSwipeUpHandler; @@ -134,10 +131,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC // Might be displacement in X or Y, depending on the direction we are swiping from the nav bar. private float mStartDisplacement; - private final boolean mIsTransientTaskbar; - private final boolean mTaskbarAlreadyOpen; - private final int mTaskbarHomeOverviewThreshold; - public OtherActivityInputConsumer(Context base, RecentsAnimationDeviceState deviceState, TaskAnimationManager taskAnimationManager, GestureState gestureState, boolean isDeferredDownTarget, Consumer onCompleteCallback, @@ -161,14 +154,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC mInputMonitorCompat = inputMonitorCompat; mInputEventReceiver = inputEventReceiver; - TaskbarUIController controller = mActivityInterface.getTaskbarController(); - mTaskbarAlreadyOpen = controller != null && !controller.isTaskbarStashed(); - mIsTransientTaskbar = DisplayController.isTransientTaskbar(base); - mTaskbarHomeOverviewThreshold = base.getResources() - .getDimensionPixelSize(ENABLE_TASKBAR_REVISED_THRESHOLDS.get() - ? R.dimen.taskbar_home_overview_threshold_v2 - : R.dimen.taskbar_home_overview_threshold); - boolean continuingPreviousGesture = mTaskAnimationManager.isRecentsAnimationRunning(); mIsDeferredDownTarget = !continuingPreviousGesture && isDeferredDownTarget; @@ -340,10 +325,8 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC } if (mDeviceState.isFullyGesturalNavMode()) { - boolean minSwipeMet = upDist >= mMotionPauseMinDisplacement; - if (mIsTransientTaskbar) { - minSwipeMet = upDist >= mTaskbarHomeOverviewThreshold; - } + boolean minSwipeMet = upDist >= Math.max(mMotionPauseMinDisplacement, + mInteractionHandler.getThresholdToAllowMotionPause()); mInteractionHandler.setCanSlowSwipeGoHome(minSwipeMet); mMotionPauseDetector.setDisallowPause(!minSwipeMet || isLikelyToStartNewTask); @@ -379,11 +362,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC // Notify the handler that the gesture has actually started mInteractionHandler.onGestureStarted(isLikelyToStartNewTask); - - mInteractionHandler.setTaskbarAlreadyOpen(mTaskbarAlreadyOpen); - if (mIsTransientTaskbar && !mTaskbarAlreadyOpen && !isLikelyToStartNewTask) { - mInteractionHandler.setClampScrollOffset(true); - } } private void startTouchTrackingForWindowAnimation(long touchTimeMs) { @@ -479,9 +457,6 @@ public class OtherActivityInputConsumer extends ContextWrapper implements InputC @UiThread private void onInteractionGestureFinished() { Preconditions.assertUIThread(); - if (mInteractionHandler != null) { - mInteractionHandler.setClampScrollOffset(false); - } removeListener(); mInteractionHandler = null; cleanupAfterGesture(); diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index 4de69cd372..bda30a576b 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -1632,7 +1632,7 @@ public class TaskView extends FrameLayout implements Reusable { */ private static RectF getInsetsToDrawInFullscreen(PreviewPositionHelper pph, DeviceProfile dp, boolean isTaskbarTransient) { - if (isTaskbarTransient) { + if (dp.isTaskbarPresent && isTaskbarTransient) { return pph.getClippedInsets(); } return dp.isTaskbarPresent && !dp.isTaskbarPresentInApps From 81bc0b78cefa0d2c5a838a7fd333bf0a0dcaa89b Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Wed, 23 Nov 2022 15:26:06 -0800 Subject: [PATCH 286/429] Disallow transient taskbar to un/stash in certain sys ui states Bug: 258604928 Test: cant un/stash with keyguard, notifications, or qs open can un/stash in app as expected Change-Id: Ib422a35fb31fc818123eae39ac3a7e6deb79f187 --- .../taskbar/TaskbarStashController.java | 21 ++++++++++++++----- 1 file changed, 16 insertions(+), 5 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 6274ec0f0f..722430e808 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -21,9 +21,14 @@ import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_HIDE; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_SHOW; import static com.android.launcher3.taskbar.Utilities.appendFlag; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_BOUNCER_SHOWING; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SHOWING; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_IME_SWITCHER_SHOWING; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED; import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_SCREEN_PINNING; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING; +import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED; import android.animation.Animator; import android.animation.AnimatorListenerAdapter; @@ -66,7 +71,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba public static final int FLAG_IN_APP = 1 << 0; public static final int FLAG_STASHED_IN_APP_MANUAL = 1 << 1; // long press, persisted - public static final int FLAG_STASHED_IN_APP_PINNED = 1 << 2; // app pinning + public static final int FLAG_STASHED_IN_SYSUI_STATE = 1 << 2; // app pinning, keyguard, etc. public static final int FLAG_STASHED_IN_APP_EMPTY = 1 << 3; // no hotseat icons public static final int FLAG_STASHED_IN_APP_SETUP = 1 << 4; // setup wizard and AllSetActivity public static final int FLAG_STASHED_IN_APP_IME = 1 << 5; // IME is visible @@ -81,7 +86,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba // If we're in an app and any of these flags are enabled, taskbar should be stashed. 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_SYSUI_STATE | FLAG_STASHED_IN_APP_EMPTY | FLAG_STASHED_IN_APP_SETUP | FLAG_STASHED_IN_APP_IME | FLAG_STASHED_IN_TASKBAR_ALL_APPS | FLAG_STASHED_SMALL_SCREEN | FLAG_STASHED_IN_APP_AUTO; @@ -751,12 +756,18 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba long animDuration = TASKBAR_STASH_DURATION; long startDelay = 0; - updateStateForFlag(FLAG_STASHED_IN_APP_PINNED, - hasAnyFlag(systemUiStateFlags, SYSUI_STATE_SCREEN_PINNING)); + updateStateForFlag(FLAG_STASHED_IN_SYSUI_STATE, hasAnyFlag(systemUiStateFlags, + SYSUI_STATE_SCREEN_PINNING + | SYSUI_STATE_BOUNCER_SHOWING + | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING + | SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED + | SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED + | SYSUI_STATE_QUICK_SETTINGS_EXPANDED)); // Only update FLAG_STASHED_IN_APP_IME when system gesture is not in progress. mIsImeShowing = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_IME_SHOWING); mIsImeSwitcherShowing = hasAnyFlag(systemUiStateFlags, SYSUI_STATE_IME_SWITCHER_SHOWING); + if (!mIsSystemGestureInProgress) { updateStateForFlag(FLAG_STASHED_IN_APP_IME, shouldStashForIme()); animDuration = TASKBAR_STASH_DURATION_FOR_IME; @@ -900,7 +911,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba StringJoiner sj = new StringJoiner("|"); appendFlag(sj, flags, FLAGS_IN_APP, "FLAG_IN_APP"); appendFlag(sj, flags, FLAG_STASHED_IN_APP_MANUAL, "FLAG_STASHED_IN_APP_MANUAL"); - appendFlag(sj, flags, FLAG_STASHED_IN_APP_PINNED, "FLAG_STASHED_IN_APP_PINNED"); + appendFlag(sj, flags, FLAG_STASHED_IN_SYSUI_STATE, "FLAG_STASHED_IN_SYSUI_STATE"); appendFlag(sj, flags, FLAG_STASHED_IN_APP_EMPTY, "FLAG_STASHED_IN_APP_EMPTY"); appendFlag(sj, flags, FLAG_STASHED_IN_APP_SETUP, "FLAG_STASHED_IN_APP_SETUP"); appendFlag(sj, flags, FLAG_STASHED_IN_APP_IME, "FLAG_STASHED_IN_APP_IME"); From bc75ac55fd20d8ecbf38631aba80832d533099cd Mon Sep 17 00:00:00 2001 From: Pat Manning Date: Thu, 24 Nov 2022 14:57:08 +0000 Subject: [PATCH 287/429] Allow 3p launchers to use swipe proxy in AllSetActivity Bug: 257926371 Test: manual Change-Id: If70412ecaa81481d8147abb3c52859ae4ea54a11 --- .../src/com/android/quickstep/interaction/AllSetActivity.java | 3 --- 1 file changed, 3 deletions(-) diff --git a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java index 897b55949c..2af9cbcfcb 100644 --- a/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java +++ b/quickstep/src/com/android/quickstep/interaction/AllSetActivity.java @@ -256,9 +256,6 @@ public class AllSetActivity extends Activity { } private AnimatedFloat createSwipeUpProxy(GestureState state) { - if (!state.getHomeIntent().getComponent().getPackageName().equals(getPackageName())) { - return null; - } if (state.getRunningTaskId() != getTaskId()) { return null; } From 209dd03b695bcfb8e0e73155be57211400bf3162 Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Tue, 22 Nov 2022 15:49:42 -0800 Subject: [PATCH 288/429] Send corrent SUW insets for taskbar portrait vs landscape * There were two separate blocks of code for sending insets for Taskbar during SUW, consolidate those * We also weren't changing Taskbar window height corresponding to the added insets/change of height for different orientations in SUW Fixes: 253538830 Test: Went through SUW and switched orientations, no back button overlap Change-Id: Ifb3bc1c20a793ef062bf338a3bdf933b8ae98c28 --- .../taskbar/NavbarButtonsViewController.java | 5 +++-- .../launcher3/taskbar/TaskbarActivityContext.java | 9 ++++++++- .../launcher3/taskbar/TaskbarStashController.java | 12 ++++-------- 3 files changed, 15 insertions(+), 11 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index 875327dc8a..243523612a 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -210,7 +210,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT DeviceProfile deviceProfile = mContext.getDeviceProfile(); Resources resources = mContext.getResources(); Point p = !mContext.isUserSetupComplete() - ? new Point(0, resources.getDimensionPixelSize(R.dimen.taskbar_suw_frame)) + ? new Point(0, controllers.taskbarActivityContext.getSetupWindowHeight()) : DimensionUtils.getTaskbarPhoneDimensions(deviceProfile, resources, TaskbarManager.isPhoneMode(deviceProfile)); mNavButtonsView.getLayoutParams().height = p.y; @@ -691,8 +691,9 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT (resources.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size) / 2); navButtonsLayoutParams.setMarginEnd(0); navButtonsLayoutParams.gravity = Gravity.START; + mNavButtonsView.getLayoutParams().height = + mControllers.taskbarActivityContext.getSetupWindowHeight(); mNavButtonContainer.setLayoutParams(navButtonsLayoutParams); - mNavButtonContainer.requestLayout(); } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index f51bc555ce..31ec271041 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -341,6 +341,9 @@ public class TaskbarActivityContext extends BaseTaskbarContext { public void onConfigurationChanged(@Config int configChanges) { mControllers.onConfigurationChanged(configChanges); + if (!mIsUserSetupComplete) { + setTaskbarWindowHeight(getSetupWindowHeight()); + } } public boolean isThreeButtonNav() { @@ -673,7 +676,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { } if (!isUserSetupComplete()) { - return resources.getDimensionPixelSize(R.dimen.taskbar_suw_frame); + return getSetupWindowHeight(); } if (DisplayController.isTransientTaskbar(this)) { @@ -685,6 +688,10 @@ public class TaskbarActivityContext extends BaseTaskbarContext { return mDeviceProfile.taskbarSize + Math.max(getLeftCornerRadius(), getRightCornerRadius()); } + public int getSetupWindowHeight() { + return getResources().getDimensionPixelSize(R.dimen.taskbar_suw_frame); + } + /** * Either adds or removes {@link WindowManager.LayoutParams#FLAG_NOT_FOCUSABLE} on the taskbar * window. diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 6274ec0f0f..9a2d8757c4 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -369,11 +369,11 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba if (supportsVisualStashing() && hasAnyFlag(FLAGS_REPORT_STASHED_INSETS_TO_APP)) { DeviceProfile dp = mActivity.getDeviceProfile(); - if (hasAnyFlag(FLAG_STASHED_IN_APP_SETUP) && dp.isTaskbarPresent && !dp.isLandscape) { + if (hasAnyFlag(FLAG_STASHED_IN_APP_SETUP) && dp.isTaskbarPresent) { // We always show the back button in SUW but in portrait the SUW layout may not - // be wide enough to support overlapping the nav bar with its content. For now, - // just inset by the bar height. - return mUnstashedHeight; + // be wide enough to support overlapping the nav bar with its content. + // We're sending different res values in portrait vs landscape + return mActivity.getResources().getDimensionPixelSize(R.dimen.taskbar_suw_insets); } boolean isAnimating = mAnimator != null && mAnimator.isStarted(); if (!mControllers.stashedHandleViewController.isStashedHandleVisible() @@ -387,10 +387,6 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba return mStashedHeight; } - if (!mActivity.isUserSetupComplete()) { - // Special insets for SUW. - return mActivity.getResources().getDimensionPixelSize(R.dimen.taskbar_suw_insets); - } return mUnstashedHeight; } From 92400681a92ea3e0ad1175eac2c74578a9bc6e9e Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Mon, 21 Nov 2022 19:36:13 +0000 Subject: [PATCH 289/429] Remove Taskbar EDU icon wave animation. As per the latest mocks, the taskbar will be stashed during EDU to prevent taskbar interactions that inadvertently close the EDU sheet. Thus, this animation is no longer needed. Test: Manual Bug: 217261955 Change-Id: I8c5999121b7bb927b748d6163575dc4555ece84c --- quickstep/res/values/dimens.xml | 2 - .../taskbar/LauncherTaskbarUIController.java | 7 - .../taskbar/TaskbarEduController.java | 137 ------------------ .../taskbar/TaskbarUIController.java | 5 - 4 files changed, 151 deletions(-) diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml index 50f123676f..5a58bc25f6 100644 --- a/quickstep/res/values/dimens.xml +++ b/quickstep/res/values/dimens.xml @@ -272,8 +272,6 @@ 108dp 316dp 4dp - 25dp - 4dp 112dp 88dp 40dp diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index 0945bf2d1d..87753594fe 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -42,7 +42,6 @@ import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.logging.InstanceId; import com.android.launcher3.logging.InstanceIdSequence; import com.android.launcher3.model.data.ItemInfo; -import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.OnboardingPrefs; @@ -51,7 +50,6 @@ import com.android.quickstep.RecentsAnimationCallbacks; import com.android.quickstep.views.RecentsView; import java.io.PrintWriter; -import java.util.Arrays; import java.util.Set; import java.util.stream.Stream; @@ -256,11 +254,6 @@ public class LauncherTaskbarUIController extends TaskbarUIController { mTaskbarOverrideBackgroundAlpha.updateValue(forceHide ? 0 : 1); } - @Override - public Stream getAppIconsForEdu() { - return Arrays.stream(mLauncher.getAppsView().getAppsStore().getApps()); - } - /** * Starts the taskbar education flow, if the user hasn't seen it yet. */ diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java index 365ec75715..49bf90ca82 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java @@ -15,70 +15,23 @@ */ package com.android.launcher3.taskbar; -import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; -import static com.android.launcher3.anim.Interpolators.ACCEL_2; -import static com.android.launcher3.anim.Interpolators.ACCEL_DEACCEL; -import static com.android.launcher3.anim.Interpolators.DEACCEL; -import static com.android.launcher3.anim.Interpolators.FAST_OUT_SLOW_IN; - -import android.animation.Animator; -import android.animation.AnimatorListenerAdapter; -import android.animation.AnimatorSet; -import android.animation.Keyframe; -import android.animation.ObjectAnimator; -import android.animation.PropertyValuesHolder; -import android.animation.TimeInterpolator; -import android.content.res.Resources; -import android.text.TextUtils; -import android.view.View; - import com.android.launcher3.R; -import com.android.launcher3.icons.BitmapInfo; -import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; -import com.android.launcher3.uioverrides.PredictedAppIcon; import java.io.PrintWriter; -import java.util.Collections; -import java.util.List; -import java.util.stream.Collectors; /** Handles the Taskbar Education flow. */ public class TaskbarEduController implements TaskbarControllers.LoggableTaskbarController { - private static final long WAVE_ANIM_DELAY = 250; - private static final long WAVE_ANIM_STAGGER = 50; - private static final long WAVE_ANIM_EACH_ICON_DURATION = 633; - private static final long WAVE_ANIM_SLOT_MACHINE_DURATION = 1085; - // The fraction of each icon's animation at which we reach the top point of the wave. - private static final float WAVE_ANIM_FRACTION_TOP = 0.4f; - // The fraction of each icon's animation at which we reach the bottom, before overshooting. - private static final float WAVE_ANIM_FRACTION_BOTTOM = 0.9f; - private static final TimeInterpolator WAVE_ANIM_TO_TOP_INTERPOLATOR = FAST_OUT_SLOW_IN; - private static final TimeInterpolator WAVE_ANIM_TO_BOTTOM_INTERPOLATOR = ACCEL_2; - private static final TimeInterpolator WAVE_ANIM_OVERSHOOT_INTERPOLATOR = DEACCEL; - private static final TimeInterpolator WAVE_ANIM_OVERSHOOT_RETURN_INTERPOLATOR = ACCEL_DEACCEL; - private static final float WAVE_ANIM_ICON_SCALE = 1.2f; - // How many icons to cycle through in the slot machine (+ the original icon at each end). - private static final int WAVE_ANIM_SLOT_MACHINE_NUM_ICONS = 3; - private final TaskbarActivityContext mActivity; - private final float mWaveAnimTranslationY; - private final float mWaveAnimTranslationYReturnOvershoot; // Initialized in init. TaskbarControllers mControllers; private TaskbarEduView mTaskbarEduView; - private Animator mAnim; public TaskbarEduController(TaskbarActivityContext activity) { mActivity = activity; - - final Resources resources = activity.getResources(); - mWaveAnimTranslationY = resources.getDimension(R.dimen.taskbar_edu_wave_anim_trans_y); - mWaveAnimTranslationYReturnOvershoot = resources.getDimension( - R.dimen.taskbar_edu_wave_anim_trans_y_return_overshoot); } public void init(TaskbarControllers controllers) { @@ -98,103 +51,13 @@ public class TaskbarEduController implements TaskbarControllers.LoggableTaskbarC () -> mControllers.navbarButtonsViewController.setSlideInViewVisible(false)); mTaskbarEduView.addOnCloseListener(() -> mTaskbarEduView = null); mTaskbarEduView.show(); - startAnim(createWaveAnim()); }); } - /** - * Starts the given animation, ending the previous animation first if it's still playing. - */ - private void startAnim(Animator anim) { - if (mAnim != null) { - mAnim.end(); - } - mAnim = anim; - mAnim.addListener(new AnimatorListenerAdapter() { - @Override - public void onAnimationEnd(Animator animation) { - mAnim = null; - } - }); - mAnim.start(); - } - - /** - * Creates a staggered "wave" animation where each icon translates and scales up in succession. - */ - private Animator createWaveAnim() { - AnimatorSet waveAnim = new AnimatorSet(); - View[] icons = mControllers.taskbarViewController.getIconViews(); - for (int i = 0; i < icons.length; i++) { - View icon = icons[i]; - AnimatorSet iconAnim = new AnimatorSet(); - - Keyframe[] scaleKeyframes = new Keyframe[] { - Keyframe.ofFloat(0, 1f), - Keyframe.ofFloat(WAVE_ANIM_FRACTION_TOP, WAVE_ANIM_ICON_SCALE), - Keyframe.ofFloat(WAVE_ANIM_FRACTION_BOTTOM, 1f), - Keyframe.ofFloat(1f, 1f) - }; - scaleKeyframes[1].setInterpolator(WAVE_ANIM_TO_TOP_INTERPOLATOR); - scaleKeyframes[2].setInterpolator(WAVE_ANIM_TO_BOTTOM_INTERPOLATOR); - - Keyframe[] translationYKeyframes = new Keyframe[] { - Keyframe.ofFloat(0, 0f), - Keyframe.ofFloat(WAVE_ANIM_FRACTION_TOP, -mWaveAnimTranslationY), - Keyframe.ofFloat(WAVE_ANIM_FRACTION_BOTTOM, 0f), - // Half of the remaining fraction overshoots, then the other half returns to 0. - Keyframe.ofFloat( - WAVE_ANIM_FRACTION_BOTTOM + (1 - WAVE_ANIM_FRACTION_BOTTOM) / 2f, - mWaveAnimTranslationYReturnOvershoot), - Keyframe.ofFloat(1f, 0f) - }; - translationYKeyframes[1].setInterpolator(WAVE_ANIM_TO_TOP_INTERPOLATOR); - translationYKeyframes[2].setInterpolator(WAVE_ANIM_TO_BOTTOM_INTERPOLATOR); - translationYKeyframes[3].setInterpolator(WAVE_ANIM_OVERSHOOT_INTERPOLATOR); - translationYKeyframes[4].setInterpolator(WAVE_ANIM_OVERSHOOT_RETURN_INTERPOLATOR); - - iconAnim.play(ObjectAnimator.ofPropertyValuesHolder(icon, - PropertyValuesHolder.ofKeyframe(SCALE_PROPERTY, scaleKeyframes)) - .setDuration(WAVE_ANIM_EACH_ICON_DURATION)); - iconAnim.play(ObjectAnimator.ofPropertyValuesHolder(icon, - PropertyValuesHolder.ofKeyframe(View.TRANSLATION_Y, translationYKeyframes)) - .setDuration(WAVE_ANIM_EACH_ICON_DURATION)); - - if (icon instanceof PredictedAppIcon) { - // Play slot machine animation through random icons from AllAppsList. - PredictedAppIcon predictedAppIcon = (PredictedAppIcon) icon; - ItemInfo itemInfo = (ItemInfo) icon.getTag(); - List iconsToAnimate = mControllers.uiController.getAppIconsForEdu() - .filter(appInfo -> !TextUtils.equals(appInfo.title, itemInfo.title)) - .map(appInfo -> appInfo.bitmap) - .filter(bitmap -> !bitmap.isNullOrLowRes()) - .collect(Collectors.toList()); - // Pick n icons at random. - Collections.shuffle(iconsToAnimate); - if (iconsToAnimate.size() > WAVE_ANIM_SLOT_MACHINE_NUM_ICONS) { - iconsToAnimate = iconsToAnimate.subList(0, WAVE_ANIM_SLOT_MACHINE_NUM_ICONS); - } - Animator slotMachineAnim = predictedAppIcon.createSlotMachineAnim(iconsToAnimate); - if (slotMachineAnim != null) { - iconAnim.play(slotMachineAnim.setDuration(WAVE_ANIM_SLOT_MACHINE_DURATION)); - } - } - - iconAnim.setStartDelay(WAVE_ANIM_STAGGER * i); - waveAnim.play(iconAnim); - } - waveAnim.setStartDelay(WAVE_ANIM_DELAY); - return waveAnim; - } - @Override public void dumpLogs(String prefix, PrintWriter pw) { pw.println(prefix + "TaskbarEduController:"); - pw.println(prefix + "\tisShowingEdu=" + (mTaskbarEduView != null)); - pw.println(prefix + "\tmWaveAnimTranslationY=" + mWaveAnimTranslationY); - pw.println(prefix + "\tmWaveAnimTranslationYReturnOvershoot=" - + mWaveAnimTranslationYReturnOvershoot); } /** diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java index 4ec9b41ea2..6c6b002959 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java @@ -29,7 +29,6 @@ import com.android.quickstep.views.RecentsView; import com.android.quickstep.views.TaskView; import java.io.PrintWriter; -import java.util.stream.Stream; /** * Base class for providing different taskbar UI @@ -66,10 +65,6 @@ public class TaskbarUIController { protected void onStashedInAppChanged() { } - public Stream getAppIconsForEdu() { - return Stream.empty(); - } - /** Called when an icon is launched. */ public void onTaskbarIconLaunched(ItemInfo item) { } From 84633c1a9d2c50e978d373b5c746905e3f6cc605 Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Tue, 22 Nov 2022 01:16:27 +0000 Subject: [PATCH 290/429] Stash taskbar while EDU is open. The stashing behavior is consistent with the All Apps overlay. Test: Manual Bug: 217261955 Change-Id: Idae0c3d829e806be6c18f00455f7ddd0d60f0efb --- .../taskbar/TaskbarEduController.java | 43 +++++++++++++------ .../launcher3/taskbar/TaskbarEduView.java | 7 +-- .../taskbar/TaskbarStashController.java | 32 ++++++-------- .../allapps/TaskbarAllAppsSlideInView.java | 15 ++++--- .../allapps/TaskbarAllAppsViewController.java | 18 +++++++- .../overlay/TaskbarOverlayController.java | 11 +++++ 6 files changed, 84 insertions(+), 42 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java index 49bf90ca82..c53595d5b8 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduController.java @@ -15,8 +15,12 @@ */ package com.android.launcher3.taskbar; +import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_STASHED_IN_APP_EDU; +import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; + import com.android.launcher3.R; import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; +import com.android.launcher3.taskbar.overlay.TaskbarOverlayController; import java.io.PrintWriter; @@ -39,19 +43,26 @@ public class TaskbarEduController implements TaskbarControllers.LoggableTaskbarC } void showEdu() { - mActivity.setTaskbarWindowFullscreen(true); - mActivity.getDragLayer().post(() -> { - TaskbarOverlayContext overlayContext = - mControllers.taskbarOverlayController.requestWindow(); - mTaskbarEduView = (TaskbarEduView) overlayContext.getLayoutInflater().inflate( - R.layout.taskbar_edu, overlayContext.getDragLayer(), false); - mTaskbarEduView.init(new TaskbarEduCallbacks()); - mControllers.navbarButtonsViewController.setSlideInViewVisible(true); - mTaskbarEduView.setOnCloseBeginListener( - () -> mControllers.navbarButtonsViewController.setSlideInViewVisible(false)); - mTaskbarEduView.addOnCloseListener(() -> mTaskbarEduView = null); - mTaskbarEduView.show(); + TaskbarOverlayController overlayController = mControllers.taskbarOverlayController; + TaskbarOverlayContext overlayContext = overlayController.requestWindow(); + mTaskbarEduView = (TaskbarEduView) overlayContext.getLayoutInflater().inflate( + R.layout.taskbar_edu, overlayContext.getDragLayer(), false); + mTaskbarEduView.init(new TaskbarEduCallbacks()); + mControllers.navbarButtonsViewController.setSlideInViewVisible(true); + + TaskbarStashController stashController = mControllers.taskbarStashController; + stashController.updateStateForFlag(FLAG_STASHED_IN_APP_EDU, true); + stashController.applyState(overlayController.getOpenDuration()); + + mTaskbarEduView.setOnCloseBeginListener(() -> { + mControllers.navbarButtonsViewController.setSlideInViewVisible(false); + // Post in case view is closing due to gesture navigation. If a gesture is in progress, + // wait to unstash until after the gesture is finished. + MAIN_EXECUTOR.post(() -> stashController.resetFlagIfNoGestureInProgress( + FLAG_STASHED_IN_APP_EDU)); }); + mTaskbarEduView.addOnCloseListener(() -> mTaskbarEduView = null); + mTaskbarEduView.show(); } @Override @@ -84,5 +95,13 @@ public class TaskbarEduController implements TaskbarControllers.LoggableTaskbarC int getIconLayoutBoundsWidth() { return mControllers.taskbarViewController.getIconLayoutWidth(); } + + int getOpenDuration() { + return mControllers.taskbarOverlayController.getOpenDuration(); + } + + int getCloseDuration() { + return mControllers.taskbarOverlayController.getCloseDuration(); + } } } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java index bb87f48a92..d38c6d1d4d 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduView.java @@ -35,9 +35,6 @@ import com.android.launcher3.views.AbstractSlideInView; public class TaskbarEduView extends AbstractSlideInView implements Insettable { - private static final int DEFAULT_OPEN_DURATION = 500; - private static final int DEFAULT_CLOSE_DURATION = 200; - private final Rect mInsets = new Rect(); // Initialized in init. @@ -65,7 +62,7 @@ public class TaskbarEduView extends AbstractSlideInView @Override protected void handleClose(boolean animate) { - handleClose(animate, DEFAULT_CLOSE_DURATION); + handleClose(animate, mTaskbarEduCallbacks.getCloseDuration()); } @Override @@ -161,7 +158,7 @@ public class TaskbarEduView extends AbstractSlideInView mOpenCloseAnimator.setValues( PropertyValuesHolder.ofFloat(TRANSLATION_SHIFT, TRANSLATION_SHIFT_OPENED)); mOpenCloseAnimator.setInterpolator(AGGRESSIVE_EASE); - mOpenCloseAnimator.setDuration(DEFAULT_OPEN_DURATION).start(); + mOpenCloseAnimator.setDuration(mTaskbarEduCallbacks.getOpenDuration()).start(); } void snapToPage(int page) { diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 6274ec0f0f..ce0ec7dc11 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -17,7 +17,6 @@ package com.android.launcher3.taskbar; import static android.view.HapticFeedbackConstants.LONG_PRESS; -import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_HIDE; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_SHOW; import static com.android.launcher3.taskbar.Utilities.appendFlag; @@ -75,6 +74,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba public static final int FLAG_IN_SETUP = 1 << 8; // In the Setup Wizard public static final int FLAG_STASHED_SMALL_SCREEN = 1 << 9; // phone screen gesture nav, stashed public static final int FLAG_STASHED_IN_APP_AUTO = 1 << 10; // Autohide (transient taskbar). + public static final int FLAG_STASHED_IN_APP_EDU = 1 << 11; // EDU is visible. // If any of these flags are enabled, isInApp should return true. private static final int FLAGS_IN_APP = FLAG_IN_APP | FLAG_IN_SETUP; @@ -83,7 +83,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba 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 | FLAG_STASHED_IN_TASKBAR_ALL_APPS - | FLAG_STASHED_SMALL_SCREEN | FLAG_STASHED_IN_APP_AUTO; + | FLAG_STASHED_SMALL_SCREEN | FLAG_STASHED_IN_APP_AUTO | FLAG_STASHED_IN_APP_EDU; private static final int FLAGS_STASHED_IN_APP_IGNORING_IME = FLAGS_STASHED_IN_APP & ~FLAG_STASHED_IN_APP_IME; @@ -93,7 +93,8 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba // Currently any flag that causes us to stash in an app is included, except for IME or All Apps // since those cover 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 & ~FLAG_STASHED_IN_TASKBAR_ALL_APPS; + & ~FLAG_STASHED_IN_APP_IME & ~FLAG_STASHED_IN_TASKBAR_ALL_APPS + & ~FLAG_STASHED_IN_APP_EDU; /** * How long to stash/unstash when manually invoked via long press. @@ -701,34 +702,27 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba // Only update the following flags when system gesture is not in progress. boolean shouldStashForIme = shouldStashForIme(); - maybeResetStashedInAppAllApps( - hasAnyFlag(FLAG_STASHED_IN_APP_IME) == shouldStashForIme); + updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, false); + updateStateForFlag(FLAG_STASHED_IN_APP_EDU, false); if (hasAnyFlag(FLAG_STASHED_IN_APP_IME) != shouldStashForIme) { updateStateForFlag(FLAG_STASHED_IN_APP_IME, shouldStashForIme); applyState(TASKBAR_STASH_DURATION_FOR_IME, getTaskbarStashStartDelayForIme()); + } else { + applyState(mControllers.taskbarOverlayController.getCloseDuration()); } } /** - * Reset stashed in all apps only if no system gesture is in progress. + * Resets the flag if no system gesture is in progress. *

* Otherwise, the reset should be deferred until after the gesture is finished. * * @see #setSystemGestureInProgress */ - public void maybeResetStashedInAppAllApps() { - maybeResetStashedInAppAllApps(true); - } - - private void maybeResetStashedInAppAllApps(boolean applyState) { - if (mIsSystemGestureInProgress) { - return; - } - - updateStateForFlag(FLAG_STASHED_IN_TASKBAR_ALL_APPS, false); - if (applyState) { - applyState(ALL_APPS.getTransitionDuration( - mControllers.taskbarActivityContext, false /* isToState */)); + public void resetFlagIfNoGestureInProgress(int flag) { + if (!mIsSystemGestureInProgress) { + updateStateForFlag(flag, false); + applyState(mControllers.taskbarOverlayController.getCloseDuration()); } } diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java index c8bfc2aed0..8502752652 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java @@ -15,7 +15,6 @@ */ package com.android.launcher3.taskbar.allapps; -import static com.android.launcher3.LauncherState.ALL_APPS; import static com.android.launcher3.anim.Interpolators.EMPHASIZED; import android.animation.PropertyValuesHolder; @@ -28,6 +27,7 @@ import android.view.animation.Interpolator; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Insettable; import com.android.launcher3.R; +import com.android.launcher3.taskbar.allapps.TaskbarAllAppsViewController.TaskbarAllAppsCallbacks; import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext; import com.android.launcher3.views.AbstractSlideInView; @@ -37,6 +37,9 @@ public class TaskbarAllAppsSlideInView extends AbstractSlideInView mTaskbarStashController.resetFlagIfNoGestureInProgress( + FLAG_STASHED_IN_TASKBAR_ALL_APPS)); }); } + + class TaskbarAllAppsCallbacks { + int getOpenDuration() { + return mOverlayController.getOpenDuration(); + } + + int getCloseDuration() { + return mOverlayController.getCloseDuration(); + } + } } diff --git a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java index 019e5a608f..476e0a8bab 100644 --- a/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java +++ b/quickstep/src/com/android/launcher3/taskbar/overlay/TaskbarOverlayController.java @@ -20,6 +20,7 @@ import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY; import static com.android.launcher3.AbstractFloatingView.TYPE_ALL; import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE; +import static com.android.launcher3.LauncherState.ALL_APPS; import android.annotation.SuppressLint; import android.content.Context; @@ -150,6 +151,16 @@ public final class TaskbarOverlayController { }); } + /** The default open duration for overlays. */ + public int getOpenDuration() { + return ALL_APPS.getTransitionDuration(mTaskbarContext, true); + } + + /** The default close duration for overlays. */ + public int getCloseDuration() { + return ALL_APPS.getTransitionDuration(mTaskbarContext, false); + } + @SuppressLint("WrongConstant") private LayoutParams createLayoutParams() { LayoutParams layoutParams = new LayoutParams( From ce4896cff5b1619e78c9dbc4d4144bd233dedb2d Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 22 Nov 2022 14:57:07 -0800 Subject: [PATCH 291/429] Fixing shortcuts not getting theme icons Bug: 238650110 Test: Updated ThemeIconsTest Change-Id: I803cd6eefa4e393bf19901a44712622adac7f4b1 --- .../com/android/quickstep/TaskIconCache.java | 5 +- .../launcher3/icons/ShortcutCachingLogic.java | 6 +-- tests/res/xml/shortcuts.xml | 1 + .../ui/workspace/ThemeIconsTest.java | 53 ++++++++++++++++--- 4 files changed, 54 insertions(+), 11 deletions(-) diff --git a/quickstep/src/com/android/quickstep/TaskIconCache.java b/quickstep/src/com/android/quickstep/TaskIconCache.java index dc60875db8..7c05a1092c 100644 --- a/quickstep/src/com/android/quickstep/TaskIconCache.java +++ b/quickstep/src/com/android/quickstep/TaskIconCache.java @@ -249,12 +249,13 @@ public class TaskIconCache implements DisplayInfoChangeListener { private BitmapInfo getBitmapInfo(Drawable drawable, int userId, int primaryColor, boolean isInstantApp) { try (BaseIconFactory bif = getIconFactory()) { - bif.disableColorExtraction(); bif.setWrapperBackgroundColor(primaryColor); // User version code O, so that the icon is always wrapped in an adaptive icon container return bif.createBadgedIconBitmap(drawable, - new IconOptions().setUser(UserHandle.of(userId)).setInstantApp(isInstantApp)); + new IconOptions().setUser(UserHandle.of(userId)) + .setInstantApp(isInstantApp) + .setExtractedColor(0)); } } diff --git a/src/com/android/launcher3/icons/ShortcutCachingLogic.java b/src/com/android/launcher3/icons/ShortcutCachingLogic.java index 9a86ede6f2..bb7248fea7 100644 --- a/src/com/android/launcher3/icons/ShortcutCachingLogic.java +++ b/src/com/android/launcher3/icons/ShortcutCachingLogic.java @@ -32,6 +32,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.launcher3.LauncherAppState; +import com.android.launcher3.icons.BaseIconFactory.IconOptions; import com.android.launcher3.icons.cache.CachingLogic; import com.android.launcher3.shortcuts.ShortcutKey; import com.android.launcher3.util.Themes; @@ -76,9 +77,8 @@ public class ShortcutCachingLogic implements CachingLogic { Drawable unbadgedDrawable = ShortcutCachingLogic.getIcon( context, info, LauncherAppState.getIDP(context).fillResIconDpi); if (unbadgedDrawable == null) return BitmapInfo.LOW_RES_INFO; - return new BitmapInfo( - li.createScaledBitmap(unbadgedDrawable, BaseIconFactory.MODE_WITH_SHADOW), - Themes.getColorAccent(context)); + return li.createBadgedIconBitmap(unbadgedDrawable, + new IconOptions().setExtractedColor(Themes.getColorAccent(context))); } } diff --git a/tests/res/xml/shortcuts.xml b/tests/res/xml/shortcuts.xml index bdc22f98cb..fde0dbb2b1 100644 --- a/tests/res/xml/shortcuts.xml +++ b/tests/res/xml/shortcuts.xml @@ -2,6 +2,7 @@ diff --git a/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java b/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java index e66810cc3d..57731d0af9 100644 --- a/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java +++ b/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java @@ -32,6 +32,7 @@ import com.android.launcher3.BubbleTextView; import com.android.launcher3.icons.ThemedIconDrawable; import com.android.launcher3.tapl.HomeAllApps; import com.android.launcher3.tapl.HomeAppIcon; +import com.android.launcher3.tapl.HomeAppIconMenuItem; import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.ui.TaplTestsLauncher3; @@ -49,6 +50,8 @@ import java.util.Queue; public class ThemeIconsTest extends AbstractLauncherUiTest { private static final String APP_NAME = "ThemeIconTestActivity"; + private static final String SHORTCUT_APP_NAME = "LauncherTestApp"; + private static final String SHORTCUT_NAME = "Shortcut 1"; @Test public void testIconWithoutTheme() throws Exception { @@ -60,9 +63,28 @@ public class ThemeIconsTest extends AbstractLauncherUiTest { try { HomeAppIcon icon = allApps.getAppIcon(APP_NAME); - executeOnLauncher(l -> verifyIconTheme(l.getAppsView(), false)); + executeOnLauncher(l -> verifyIconTheme(APP_NAME, l.getAppsView(), false)); icon.dragToWorkspace(false, false); - executeOnLauncher(l -> verifyIconTheme(l.getWorkspace(), false)); + executeOnLauncher(l -> verifyIconTheme(APP_NAME, l.getWorkspace(), false)); + } finally { + allApps.unfreeze(); + } + } + + @Test + public void testShortcutIconWithoutTheme() throws Exception { + setThemeEnabled(false); + TaplTestsLauncher3.initialize(this); + + HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps(); + allApps.freeze(); + + try { + HomeAppIcon icon = allApps.getAppIcon(SHORTCUT_APP_NAME); + HomeAppIconMenuItem shortcutItem = + (HomeAppIconMenuItem) icon.openDeepShortcutMenu().getMenuItem(SHORTCUT_NAME); + shortcutItem.dragToWorkspace(false, false); + executeOnLauncher(l -> verifyIconTheme(SHORTCUT_NAME, l.getWorkspace(), false)); } finally { allApps.unfreeze(); } @@ -78,15 +100,34 @@ public class ThemeIconsTest extends AbstractLauncherUiTest { try { HomeAppIcon icon = allApps.getAppIcon(APP_NAME); - executeOnLauncher(l -> verifyIconTheme(l.getAppsView(), false)); + executeOnLauncher(l -> verifyIconTheme(APP_NAME, l.getAppsView(), false)); icon.dragToWorkspace(false, false); - executeOnLauncher(l -> verifyIconTheme(l.getWorkspace(), true)); + executeOnLauncher(l -> verifyIconTheme(APP_NAME, l.getWorkspace(), true)); } finally { allApps.unfreeze(); } } - private void verifyIconTheme(ViewGroup parent, boolean isThemed) { + @Test + public void testShortcutIconWithTheme() throws Exception { + setThemeEnabled(true); + TaplTestsLauncher3.initialize(this); + + HomeAllApps allApps = mLauncher.getWorkspace().switchToAllApps(); + allApps.freeze(); + + try { + HomeAppIcon icon = allApps.getAppIcon(SHORTCUT_APP_NAME); + HomeAppIconMenuItem shortcutItem = + (HomeAppIconMenuItem) icon.openDeepShortcutMenu().getMenuItem(SHORTCUT_NAME); + shortcutItem.dragToWorkspace(false, false); + executeOnLauncher(l -> verifyIconTheme(SHORTCUT_NAME, l.getWorkspace(), true)); + } finally { + allApps.unfreeze(); + } + } + + private void verifyIconTheme(String title, ViewGroup parent, boolean isThemed) { // Find the app icon Queue viewQueue = new ArrayDeque<>(); viewQueue.add(parent); @@ -100,7 +141,7 @@ public class ThemeIconsTest extends AbstractLauncherUiTest { } } else if (view instanceof BubbleTextView) { BubbleTextView btv = (BubbleTextView) view; - if (APP_NAME.equals(btv.getText())) { + if (title.equals(btv.getText())) { icon = btv; break; } From 677978c8aba8f577b39485b40e33902b2015429f Mon Sep 17 00:00:00 2001 From: Stefan Andonian Date: Thu, 11 Aug 2022 20:36:41 +0000 Subject: [PATCH 292/429] Fix for bug where expensive launcher animations were being paused and never resumed. Bug: 240623130 Test: Verified on device that the issue is not reproducible after fix. Change-Id: I7b1e2f70fd75b1eddf340a4f85465cc6d5b65f73 (cherry picked from commit 8b336195a6f287f03d17db02d961c1f2d85c4eda) --- .../src/com/android/launcher3/QuickstepTransitionManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index e1a3b729c1..9aeb3709ac 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -518,6 +518,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener appsView.setAlpha(startAlpha); SCALE_PROPERTY.set(appsView, startScale); appsView.setLayerType(View.LAYER_TYPE_NONE, null); + mLauncher.resumeExpensiveViewUpdates(); }; } else if (mLauncher.isInState(OVERVIEW)) { endListener = composeViewContentAnimator(launcherAnimator, alphas, scales); @@ -647,6 +648,7 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener overview.setFreezeViewVisibility(false); SCALE_PROPERTY.set(overview, 1f); mLauncher.getStateManager().reapplyState(); + mLauncher.resumeExpensiveViewUpdates(); }; } From 45ec83b2d6516027114aee026600490d489a7755 Mon Sep 17 00:00:00 2001 From: Anushree Ganjam Date: Tue, 29 Nov 2022 00:49:56 +0000 Subject: [PATCH 293/429] Refactor all_apps.xml contents to all_apps_content.xml We can reuse the all_apps_content.xml in other all_apps.xml This is step1. As step2, I will refactor secondary_launcher.xml and taskbar_all_apps.xml. Bug: 204781396 Test: Manual Change-Id: Ia842ca082ec38220d327f512221807ed21ad2ad3 --- res/layout/all_apps.xml | 31 +------------------- res/layout/all_apps_content.xml | 51 +++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+), 30 deletions(-) create mode 100644 res/layout/all_apps_content.xml diff --git a/res/layout/all_apps.xml b/res/layout/all_apps.xml index d0d82d48bd..f8a871a502 100644 --- a/res/layout/all_apps.xml +++ b/res/layout/all_apps.xml @@ -25,34 +25,5 @@ android:focusable="false" android:saveEnabled="false"> - - - - - - - - - - - - - - - - - + \ No newline at end of file diff --git a/res/layout/all_apps_content.xml b/res/layout/all_apps_content.xml new file mode 100644 index 0000000000..b33029fcd1 --- /dev/null +++ b/res/layout/all_apps_content.xml @@ -0,0 +1,51 @@ + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file From d25f79c48f8a8b8f8f338e42d0fc02c5879bbd70 Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Tue, 29 Nov 2022 09:30:44 -0800 Subject: [PATCH 294/429] Adding screenrecord to debug themeIconTest Bug: 260722220 Test: Updated Change-Id: I20e590436e318f9a8914a8201d95584ab26de388 --- .../android/launcher3/ui/workspace/ThemeIconsTest.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java b/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java index 57731d0af9..93329fa4d5 100644 --- a/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java +++ b/tests/src/com/android/launcher3/ui/workspace/ThemeIconsTest.java @@ -35,6 +35,8 @@ import com.android.launcher3.tapl.HomeAppIcon; import com.android.launcher3.tapl.HomeAppIconMenuItem; import com.android.launcher3.ui.AbstractLauncherUiTest; import com.android.launcher3.ui.TaplTestsLauncher3; +import com.android.launcher3.util.Executors; +import com.android.launcher3.util.rule.ScreenRecordRule.ScreenRecord; import org.junit.Test; @@ -109,6 +111,7 @@ public class ThemeIconsTest extends AbstractLauncherUiTest { } @Test + @ScreenRecord // b/260722220 public void testShortcutIconWithTheme() throws Exception { setThemeEnabled(true); TaplTestsLauncher3.initialize(this); @@ -128,6 +131,13 @@ public class ThemeIconsTest extends AbstractLauncherUiTest { } private void verifyIconTheme(String title, ViewGroup parent, boolean isThemed) { + // Wait for Launcher model to be completed + try { + Executors.MODEL_EXECUTOR.submit(() -> { }).get(); + } catch (Exception e) { + throw new RuntimeException(e); + } + // Find the app icon Queue viewQueue = new ArrayDeque<>(); viewQueue.add(parent); From 791c9cbc377d6daf2510a20e90ea98371b7d2f68 Mon Sep 17 00:00:00 2001 From: Federico Baron Date: Mon, 21 Nov 2022 13:28:32 -0800 Subject: [PATCH 295/429] Add flags for new restore icon treatment We're updating the way apps look when they're pending, downloading, and installing. It will look like this mock https://docs.google.com/presentation/d/1V9-1C3mJ3zRGsuzzzYExisr9vLYecgADa1FucMoW_aw/edit#slide=id.g16c002f332d_1_0 Bug: 254858049 Test: N/A Change-Id: I4403f857c9c1fc24c65223886008252462209804 --- src/com/android/launcher3/config/FeatureFlags.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 669159ff36..cc2119f06c 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -330,6 +330,10 @@ public final class FeatureFlags { "HOME_GARDENING_WORKSPACE_BUTTONS", false, "Change workspace edit buttons to reflect home gardening"); + public static final BooleanFlag ENABLE_DOWNLOAD_APP_UX_V2 = getDebugFlag( + "ENABLE_DOWNLOAD_APP_UX_V2", false, "Updates the download app UX" + + " to have better visuals"); + public static final BooleanFlag ENABLE_TASKBAR_REVISED_THRESHOLDS = getDebugFlag( "ENABLE_TASKBAR_REVISED_THRESHOLDS", false, "Uses revised thresholds for transient taskbar."); From 9820d4746d62eb017a0bed29fd126660b590da3e Mon Sep 17 00:00:00 2001 From: Becky Qiu Date: Tue, 29 Nov 2022 11:01:58 -0800 Subject: [PATCH 296/429] [Toast] Remove feature flag for rich answer, use all apps flag instead. This is to prepare for the server launch. Bug: 241295640, 256693300 Test: local Change-Id: Idf1fe2b05e998dbab790d3dc1a7ea63f9daa2df7 --- src/com/android/launcher3/config/FeatureFlags.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index b082a6718c..72209c6586 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -301,10 +301,6 @@ public final class FeatureFlags { "USE_SEARCH_REQUEST_TIMEOUT_OVERRIDES", false, "Use local overrides for search request timeout"); - public static final BooleanFlag ENABLE_RICH_ANSWER = new DeviceFlag( - "ENABLE_RICH_ANSWER", false, - "Enable rich answer new UI for web answer search results"); - public static final BooleanFlag CONTINUOUS_VIEW_TREE_CAPTURE = getDebugFlag( "CONTINUOUS_VIEW_TREE_CAPTURE", false, "Capture View tree every frame"); From 6f5062e64c0bab83335c2d994808563ca4b3c284 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 29 Nov 2022 11:14:12 -0800 Subject: [PATCH 297/429] Turn flag on by default: ENABLE_TASKBAR_REVISED_THRESHOLDS Bug: 260002412 Test: manual Change-Id: I2b5f2a434f5768c1834fa15d814f001e13b719da --- src/com/android/launcher3/config/FeatureFlags.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 669159ff36..51344d5ccb 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -331,7 +331,7 @@ public final class FeatureFlags { "Change workspace edit buttons to reflect home gardening"); public static final BooleanFlag ENABLE_TASKBAR_REVISED_THRESHOLDS = getDebugFlag( - "ENABLE_TASKBAR_REVISED_THRESHOLDS", false, + "ENABLE_TASKBAR_REVISED_THRESHOLDS", true, "Uses revised thresholds for transient taskbar."); public static final BooleanFlag ENABLE_TRANSIENT_TASKBAR = getDebugFlag( From 106cc895e97688b4415761da5166452dfe4d059a Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 29 Nov 2022 11:30:39 -0800 Subject: [PATCH 298/429] Allow touches on transient taskbar if ime is present. Bug: 260101467 Test: open chrome, enter url to pull up ime, swipe up to show taskbar, tap on taskbar icon Change-Id: Ic8be6c2bb82fc9b8ab83572cb8622ac157078ea9 --- .../com/android/launcher3/taskbar/TaskbarInsetsController.kt | 3 ++- .../com/android/launcher3/taskbar/TaskbarViewController.java | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt index 32c1972934..b3885121f0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt @@ -149,7 +149,8 @@ class TaskbarInsetsController(val context: TaskbarActivityContext): LoggableTask if (context.dragLayer.alpha < AlphaUpdateListener.ALPHA_CUTOFF_THRESHOLD) { // Let touches pass through us. insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION) - } else if (controllers.navbarButtonsViewController.isImeVisible) { + } else if (controllers.navbarButtonsViewController.isImeVisible + && controllers.taskbarStashController.isStashed()) { insetsInfo.setTouchableInsets(TOUCHABLE_INSETS_REGION) } else if (!controllers.uiController.isTaskbarTouchable) { // Let touches pass through us. diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index 9936d27951..b5e6fac5bb 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -193,7 +193,8 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar * Should be called when the IME visibility changes, so we can make Taskbar not steal touches. */ public void setImeIsVisible(boolean isImeVisible) { - mTaskbarView.setTouchesEnabled(!isImeVisible); + mTaskbarView.setTouchesEnabled(!isImeVisible + || DisplayController.isTransientTaskbar(mActivity)); } /** From 6811fe8ab0a50a429609d6ea394b0c1cb59aa671 Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Tue, 29 Nov 2022 12:16:04 -0800 Subject: [PATCH 299/429] Fix window x-axis movement after gesture ends. Previously we setClamp to false right after the gesture ends. So when the page settle animation gets the page offset, it would get the unclamped version which would cause the window to move in the x-axis movement even if the window didn't actually move during the gesture. Now we ensure that we setClamp to false after the page transition ends so that the scroll offset is consistent all the way until the end of the animation. Bug: 258851206 Test: 1. swipe a bit diagonally to bring up taskbar with no x-axis window movement 2. release 3. there should be no x-axis movement on window Change-Id: Ic9949d11f2e8bc7ccbd737555a3d5551f09456da --- .../src/com/android/quickstep/AbsSwipeUpHandler.java | 10 ++++++---- .../src/com/android/quickstep/views/RecentsView.java | 10 +++++----- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index 19ffd2ac35..3d8ffc418a 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -1204,7 +1204,6 @@ public abstract class AbsSwipeUpHandler, final GestureEndTarget endTarget = calculateEndTarget(velocity, endVelocity, isFling, isCancel); - setClampScrollOffset(false); // Set the state, but don't notify until the animation completes mGestureState.setEndTarget(endTarget, false /* isAtomic */); mAnimationFactory.setEndTarget(endTarget); @@ -1282,13 +1281,16 @@ public abstract class AbsSwipeUpHandler, // Let RecentsView handle the scrolling to the task, which we launch in startNewTask() // or resumeLastTask(). + Runnable onPageTransitionEnd = () -> { + mGestureState.setState(STATE_RECENTS_SCROLLING_FINISHED); + setClampScrollOffset(false); + }; if (mRecentsView != null) { ActiveGestureLog.INSTANCE.trackEvent(ActiveGestureErrorDetector.GestureEvent .SET_ON_PAGE_TRANSITION_END_CALLBACK); - mRecentsView.setOnPageTransitionEndCallback( - () -> mGestureState.setState(STATE_RECENTS_SCROLLING_FINISHED)); + mRecentsView.setOnPageTransitionEndCallback(onPageTransitionEnd); } else { - mGestureState.setState(STATE_RECENTS_SCROLLING_FINISHED); + onPageTransitionEnd.run(); } animateToProgress(startShift, endShift, duration, interpolator, endTarget, velocity); diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index dc1b885172..8b406ec4f7 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -5072,15 +5072,15 @@ public abstract class RecentsView Date: Tue, 22 Nov 2022 11:34:27 -0800 Subject: [PATCH 300/429] Searching for Golden Gate Bridge should show three queries and check if predicted app row and web suggest exists Add a method that checks if three web suggests exist and another method to check for predicted app row and web suggest exists. bug: 225583735 test: Manual - photo: https://screenshot.googleplex.com/3NoSUm7nzTvf3gX Change-Id: I7f9340229aaf4a0a3928933035f193a576995525 --- .../launcher3/tapl/SearchResultFromQsb.java | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java b/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java index ddeeac225a..bddb5935f7 100644 --- a/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java +++ b/tests/tapl/com/android/launcher3/tapl/SearchResultFromQsb.java @@ -20,6 +20,8 @@ import android.widget.TextView; import androidx.test.uiautomator.By; import androidx.test.uiautomator.UiObject2; +import java.util.ArrayList; + /** * Operations on search result page opened from home screen qsb. */ @@ -27,6 +29,9 @@ public class SearchResultFromQsb { // The input resource id in the search box. private static final String INPUT_RES = "input"; private static final String BOTTOM_SHEET_RES_ID = "bottom_sheet_background"; + + // This particular ID change should happen with caution + private static final String SEARCH_CONTAINER_RES_ID = "search_results_list_view"; private final LauncherInstrumentation mLauncher; SearchResultFromQsb(LauncherInstrumentation launcher) { @@ -49,6 +54,33 @@ public class SearchResultFromQsb { return new AllAppsAppIcon(mLauncher, icon); } + /** Find the web suggestion from search suggestion's title text */ + public void findWebSuggest(String text) { + ArrayList goldenGateResults = + new ArrayList<>(mLauncher.waitForObjectsInContainer( + mLauncher.waitForSystemLauncherObject(SEARCH_CONTAINER_RES_ID), + By.clazz(TextView.class))); + boolean found = false; + for(UiObject2 uiObject: goldenGateResults) { + String currentString = uiObject.getText(); + if (currentString.equals(text)) { + found = true; + } + } + if (!found) { + throw new IllegalStateException("Web suggestion title: " + text + " not found"); + } + } + + /** Find the total amount of views being displayed and return the size */ + public int getSearchResultItemSize() { + ArrayList searchResultItems = + new ArrayList<>(mLauncher.waitForObjectsInContainer( + mLauncher.waitForSystemLauncherObject(SEARCH_CONTAINER_RES_ID), + By.clazz(TextView.class))); + return searchResultItems.size(); + } + /** * Taps outside bottom sheet to dismiss and return to workspace. Available on tablets only. * @param tapRight Tap on the right of bottom sheet if true, or left otherwise. From c91ef50257cf60db280dd3811bef976c075232a3 Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Wed, 23 Nov 2022 14:15:07 -0800 Subject: [PATCH 301/429] Animate split confirmation after second app selection from workspace Fixes: 239824922 Test: https://recall.googleplex.com/projects/f46cfe9c-8076-4efe-bf8a-b1cc4f1f5e1b/sessions/099acb31-1e05-4d00-a670-590c177a846e Change-Id: Ifb769afcaf694a1157444f273da69331db15ab1a --- .../popup/QuickstepSystemShortcut.java | 14 +++- .../logging/StatsLogCompatManager.java | 4 + .../util/SplitToWorkspaceController.java | 77 ++++++++++++++++++- 3 files changed, 90 insertions(+), 5 deletions(-) diff --git a/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java b/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java index 7cf8201767..c65fa5fd90 100644 --- a/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java +++ b/quickstep/src/com/android/launcher3/popup/QuickstepSystemShortcut.java @@ -19,6 +19,8 @@ import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSP import static com.android.launcher3.util.SplitConfigurationOptions.getLogEventForPosition; import static com.android.quickstep.util.SplitAnimationTimings.TABLET_HOME_TO_SPLIT; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Rect; @@ -115,13 +117,19 @@ public interface QuickstepSystemShortcut { PendingAnimation anim = new PendingAnimation(TABLET_HOME_TO_SPLIT.getDuration()); RectF startingTaskRect = new RectF(); - FloatingTaskView floatingTaskView = FloatingTaskView.getFloatingTaskView(mTarget, - source.view, null /* thumbnail */, - source.drawable, startingTaskRect); + final FloatingTaskView floatingTaskView = FloatingTaskView.getFloatingTaskView(mTarget, + source.view, null /* thumbnail */, source.drawable, startingTaskRect); floatingTaskView.setAlpha(1); floatingTaskView.addStagingAnimation(anim, startingTaskRect, mTempRect, false /* fadeWithThumbnail */, true /* isStagedTask */); controller.setFirstFloatingTaskView(floatingTaskView); + anim.addListener(new AnimatorListenerAdapter() { + @Override + public void onAnimationCancel(Animator animation) { + mTarget.getDragLayer().removeView(floatingTaskView); + controller.resetState(); + } + }); anim.buildAnim().start(); } } diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java index 0ef4597c47..0a155cbd47 100644 --- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java +++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java @@ -342,6 +342,10 @@ public class StatsLogCompatManager extends StatsLogManager { return; } + if (mItemInfo == null) { + return; + } + if (mItemInfo.container < 0 || appState == null) { // Write log on the model thread so that logs do not go out of order // (for eg: drop comes after drag) diff --git a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java index e8a4b0a324..e5c74dc2e3 100644 --- a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java +++ b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java @@ -19,21 +19,39 @@ package com.android.quickstep.util; import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_FULLSCREEN_WITH_KEYBOARD_SHORTCUTS; import static com.android.launcher3.config.FeatureFlags.ENABLE_SPLIT_FROM_WORKSPACE_TO_WORKSPACE; +import android.animation.Animator; +import android.animation.AnimatorListenerAdapter; import android.content.Intent; +import android.graphics.Rect; +import android.graphics.RectF; import android.view.View; +import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; +import com.android.launcher3.R; +import com.android.launcher3.anim.PendingAnimation; +import com.android.launcher3.icons.BitmapInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; +import com.android.quickstep.views.FloatingTaskView; +import com.android.quickstep.views.RecentsView; +import com.android.systemui.shared.system.InteractionJankMonitorWrapper; /** Handles when the stage split lands on the home screen. */ public class SplitToWorkspaceController { private final Launcher mLauncher; + private final DeviceProfile mDP; private final SplitSelectStateController mController; + private final int mHalfDividerSize; + public SplitToWorkspaceController(Launcher launcher, SplitSelectStateController controller) { mLauncher = launcher; + mDP = mLauncher.getDeviceProfile(); mController = controller; + + mHalfDividerSize = mLauncher.getResources().getDimensionPixelSize( + R.dimen.multi_window_task_divider_size) / 2; } /** @@ -48,19 +66,74 @@ public class SplitToWorkspaceController { } Object tag = view.getTag(); Intent intent; + BitmapInfo bitmapInfo; if (tag instanceof WorkspaceItemInfo) { final WorkspaceItemInfo workspaceItemInfo = (WorkspaceItemInfo) tag; intent = workspaceItemInfo.intent; + bitmapInfo = workspaceItemInfo.bitmap; } else if (tag instanceof com.android.launcher3.model.data.AppInfo) { final com.android.launcher3.model.data.AppInfo appInfo = (com.android.launcher3.model.data.AppInfo) tag; intent = appInfo.intent; + bitmapInfo = appInfo.bitmap; } else { return false; } + mController.setSecondTask(intent); - mController.launchSplitTasks(aBoolean -> mLauncher.getDragLayer().removeView( - mController.getFirstFloatingTaskView())); + + boolean isTablet = mLauncher.getDeviceProfile().isTablet; + SplitAnimationTimings timings = AnimUtils.getDeviceSplitToConfirmTimings(isTablet); + PendingAnimation pendingAnimation = new PendingAnimation(timings.getDuration()); + + Rect firstTaskStartingBounds = new Rect(); + Rect firstTaskEndingBounds = new Rect(); + RectF secondTaskStartingBounds = new RectF(); + Rect secondTaskEndingBounds = new Rect(); + + RecentsView recentsView = mLauncher.getOverviewPanel(); + recentsView.getPagedOrientationHandler().getFinalSplitPlaceholderBounds(mHalfDividerSize, + mDP, mController.getActiveSplitStagePosition(), firstTaskEndingBounds, + secondTaskEndingBounds); + + FloatingTaskView firstFloatingTaskView = mController.getFirstFloatingTaskView(); + firstFloatingTaskView.getBoundsOnScreen(firstTaskStartingBounds); + firstFloatingTaskView.addConfirmAnimation(pendingAnimation, + new RectF(firstTaskStartingBounds), firstTaskEndingBounds, + false /* fadeWithThumbnail */, true /* isStagedTask */); + + FloatingTaskView secondFloatingTaskView = FloatingTaskView.getFloatingTaskView(mLauncher, + view, null /* thumbnail */, bitmapInfo.newIcon(mLauncher), + secondTaskStartingBounds); + secondFloatingTaskView.setAlpha(1); + secondFloatingTaskView.addConfirmAnimation(pendingAnimation, secondTaskStartingBounds, + secondTaskEndingBounds, true /* fadeWithThumbnail */, false /* isStagedTask */); + + pendingAnimation.addListener(new AnimatorListenerAdapter() { + private boolean mIsCancelled = false; + + @Override + public void onAnimationCancel(Animator animation) { + mIsCancelled = true; + cleanUp(); + } + + @Override + public void onAnimationEnd(Animator animation) { + if (!mIsCancelled) { + mController.launchSplitTasks(aBoolean -> cleanUp()); + InteractionJankMonitorWrapper.end( + InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER); + } + } + + private void cleanUp() { + mLauncher.getDragLayer().removeView(firstFloatingTaskView); + mLauncher.getDragLayer().removeView(secondFloatingTaskView); + mController.resetState(); + } + }); + pendingAnimation.buildAnim().start(); return true; } } From 687050a6c55f10423ce3b28bcdf80ef84fcbb379 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 30 Nov 2022 02:45:01 -0800 Subject: [PATCH 302/429] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Icc29007bba50bcceaaec8137968455017147d39e --- quickstep/res/values-af/strings.xml | 15 +++++---------- quickstep/res/values-am/strings.xml | 6 ++---- quickstep/res/values-as/strings.xml | 21 +++++++-------------- quickstep/res/values-az/strings.xml | 15 +++++---------- quickstep/res/values-b+sr+Latn/strings.xml | 15 +++++---------- quickstep/res/values-be/strings.xml | 15 +++++---------- quickstep/res/values-bg/strings.xml | 21 +++++++-------------- quickstep/res/values-bn/strings.xml | 15 +++++---------- quickstep/res/values-bs/strings.xml | 15 +++++---------- quickstep/res/values-ca/strings.xml | 21 +++++++-------------- quickstep/res/values-cs/strings.xml | 15 +++++---------- quickstep/res/values-da/strings.xml | 15 +++++---------- quickstep/res/values-de/strings.xml | 21 +++++++-------------- quickstep/res/values-el/strings.xml | 15 +++++---------- quickstep/res/values-en-rAU/strings.xml | 15 +++++---------- quickstep/res/values-en-rCA/strings.xml | 15 +++++---------- quickstep/res/values-en-rGB/strings.xml | 15 +++++---------- quickstep/res/values-en-rIN/strings.xml | 15 +++++---------- quickstep/res/values-en-rXC/strings.xml | 15 +++++---------- quickstep/res/values-es-rUS/strings.xml | 15 +++++---------- quickstep/res/values-es/strings.xml | 21 +++++++-------------- quickstep/res/values-et/strings.xml | 15 +++++---------- quickstep/res/values-fa/strings.xml | 15 +++++---------- quickstep/res/values-fi/strings.xml | 15 +++++---------- quickstep/res/values-fr-rCA/strings.xml | 21 +++++++-------------- quickstep/res/values-fr/strings.xml | 15 +++++---------- quickstep/res/values-gl/strings.xml | 15 +++++---------- quickstep/res/values-hr/strings.xml | 15 +++++---------- quickstep/res/values-hu/strings.xml | 15 +++++---------- quickstep/res/values-hy/strings.xml | 15 +++++---------- quickstep/res/values-in/strings.xml | 15 +++++---------- quickstep/res/values-is/strings.xml | 15 +++++---------- quickstep/res/values-it/strings.xml | 15 +++++---------- quickstep/res/values-iw/strings.xml | 15 +++++---------- quickstep/res/values-ja/strings.xml | 15 +++++---------- quickstep/res/values-ka/strings.xml | 15 +++++---------- quickstep/res/values-kk/strings.xml | 21 +++++++-------------- quickstep/res/values-km/strings.xml | 15 +++++---------- quickstep/res/values-kn/strings.xml | 15 +++++---------- quickstep/res/values-ko/strings.xml | 15 +++++---------- quickstep/res/values-ky/strings.xml | 21 +++++++-------------- quickstep/res/values-lo/strings.xml | 15 +++++---------- quickstep/res/values-lt/strings.xml | 15 +++++---------- quickstep/res/values-lv/strings.xml | 15 +++++---------- quickstep/res/values-mk/strings.xml | 15 +++++---------- quickstep/res/values-mn/strings.xml | 15 +++++---------- quickstep/res/values-mr/strings.xml | 15 +++++---------- quickstep/res/values-ms/strings.xml | 15 +++++---------- quickstep/res/values-nb/strings.xml | 15 +++++---------- quickstep/res/values-nl/strings.xml | 15 +++++---------- quickstep/res/values-or/strings.xml | 15 +++++---------- quickstep/res/values-pa/strings.xml | 15 +++++---------- quickstep/res/values-pl/strings.xml | 21 +++++++-------------- quickstep/res/values-pt-rPT/strings.xml | 15 +++++---------- quickstep/res/values-ro/strings.xml | 15 +++++---------- quickstep/res/values-ru/strings.xml | 15 +++++---------- quickstep/res/values-si/strings.xml | 15 +++++---------- quickstep/res/values-sk/strings.xml | 15 +++++---------- quickstep/res/values-sl/strings.xml | 15 +++++---------- quickstep/res/values-sq/strings.xml | 21 +++++++-------------- quickstep/res/values-sr/strings.xml | 15 +++++---------- quickstep/res/values-sv/strings.xml | 15 +++++---------- quickstep/res/values-sw/strings.xml | 6 ++---- quickstep/res/values-ta/strings.xml | 6 ++---- quickstep/res/values-te/strings.xml | 15 +++++---------- quickstep/res/values-th/strings.xml | 15 +++++---------- quickstep/res/values-tl/strings.xml | 15 +++++---------- quickstep/res/values-tr/strings.xml | 15 +++++---------- quickstep/res/values-uk/strings.xml | 6 ++---- quickstep/res/values-ur/strings.xml | 15 +++++---------- quickstep/res/values-uz/strings.xml | 15 +++++---------- quickstep/res/values-vi/strings.xml | 15 +++++---------- quickstep/res/values-zh-rCN/strings.xml | 15 +++++---------- quickstep/res/values-zh-rHK/strings.xml | 15 +++++---------- quickstep/res/values-zh-rTW/strings.xml | 15 +++++---------- quickstep/res/values-zu/strings.xml | 15 +++++---------- 76 files changed, 388 insertions(+), 776 deletions(-) diff --git a/quickstep/res/values-af/strings.xml b/quickstep/res/values-af/strings.xml index af7f768e29..f49f2bd2d8 100644 --- a/quickstep/res/values-af/strings.xml +++ b/quickstep/res/values-af/strings.xml @@ -78,10 +78,8 @@ "Gereed!" "Swiep op om na die tuisskerm toe te gaan" "Tik op die tuisknoppie om na jou tuisskerm toe te gaan" - - - - + "Jy is gereed om jou %1$s te begin gebruik" + "toestel" "Stelselnavigasie-instellings" "Deel" "Skermkiekie" @@ -94,8 +92,7 @@ "Kanselleer" "Slaan oor" "Draai skerm" - - + "Taakbalkopvoeding" "Taakbalkopvoeding het verskyn" "Taakbalkopvoeding is toegemaak" "Gebruik die taakbalk om tussen programme te wissel" @@ -112,10 +109,8 @@ "Onlangs" "Kennisgewings" "Kitsinstellings" - - - - + "Taakbalk" + "Navigasiebalk" "Skuif na links bo" "Skuif na regs onder" diff --git a/quickstep/res/values-am/strings.xml b/quickstep/res/values-am/strings.xml index 6064af5373..0ac7ee54c1 100644 --- a/quickstep/res/values-am/strings.xml +++ b/quickstep/res/values-am/strings.xml @@ -77,8 +77,7 @@ "አጋዥ ሥልጠና %1$d/%2$d" "ሁሉም ዝግጁ!" "ወደ መነሻ ለመሄድ በጣት ወደ ላይ ማንሸራተት" - - + "ወደ መነሻ ማያ ገጽዎ ለመሄድ የመነሻ አዝራሩን መታ ያድርጉ" @@ -88,8 +87,7 @@ "ቅጽበታዊ ገጽ እይታ" "ክፈል" "የተከፈለ ማያን ለመጠቀም ሌላ መተግበሪያ መታ ያድርጉ" - - + "የተከፈለ ማያ ገጽን ለመቀበል ሌላ መተግበሪያ ይምረጡ" "ይህ ድርጊት በመተግበሪያው ወይም በእርስዎ ድርጅት አይፈቀድም" "የአሰሳ አጋዥ ሥልጠናን ይዝለሉ?" "ይህን በኋላ በ%1$s መተግበሪያው ውስጥ ማግኘት ይችላሉ" diff --git a/quickstep/res/values-as/strings.xml b/quickstep/res/values-as/strings.xml index 51c3eefe1c..78c20bcd2e 100644 --- a/quickstep/res/values-as/strings.xml +++ b/quickstep/res/values-as/strings.xml @@ -77,27 +77,22 @@ "টিউট’ৰিয়েল %1$d/%2$d" "সকলো সাজু!" "গৃহ স্ক্ৰীনলৈ যাবলৈ ওপৰলৈ ছোৱাইপ কৰক" - - - - - - + "আপোনাৰ গৃহ স্ক্ৰীনলৈ যাবলৈ গৃহপৃষ্ঠা বুটামটো টিপক" + "আপুনি আপোনাৰ %1$sটো ব্যৱহাৰ কৰিবলৈ সাজু" + "ডিভাইচ" "ছিষ্টেম নেভিগেশ্বনৰ ছেটিং" "শ্বেয়াৰ কৰক" "স্ক্ৰীনশ্বট" "বিভাজন কৰক" "বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰিবলৈ অন্য এটা এপত টিপক" - - + "বিভাজিত স্ক্ৰীন ব্যৱহাৰ কৰিবলৈ অন্য এটা এপ্ বাছক" "এপ্‌টোৱে অথবা আপোনাৰ প্ৰতিষ্ঠানে এই কাৰ্যটোৰ অনুমতি নিদিয়ে" "নেভিগেশ্বনৰ টিউট’ৰিয়েল এৰিব বিচাৰে নেকি?" "আপুনি এয়া পাছত %1$s এপ্‌টোত বিচাৰিব পাৰিব" "বাতিল কৰক" "এৰি যাওক" "স্ক্ৰীনখন ঘূৰাওক" - - + "টাস্কবাৰৰ শিক্ষা" "টাস্কবাৰৰ শিক্ষাৰ পেনেলটো প্ৰদর্শিত হৈছে" "টাস্কবাৰৰ শিক্ষাৰ পেনেলটো বন্ধ হৈছে" "এপ্‌ সলনি কৰিবলৈ টাস্কবাৰডাল ব্যৱহাৰ কৰক" @@ -114,10 +109,8 @@ "শেহতীয়া" "জাননী" "ক্ষিপ্ৰ ছেটিং" - - - - + "টাস্কবাৰ" + "নেভিগেশ্বনৰ দণ্ড" "ওপৰৰ বাঁওফাললৈ নিয়ক" "তলৰ সোঁফাললৈ নিয়ক" diff --git a/quickstep/res/values-az/strings.xml b/quickstep/res/values-az/strings.xml index 06cc80e610..585f4cc994 100644 --- a/quickstep/res/values-az/strings.xml +++ b/quickstep/res/values-az/strings.xml @@ -78,10 +78,8 @@ "Hər şey hazırdır!" "Əsas səhifəyə keçmək üçün yuxarı çəkin" "Əsas ekranınıza keçmək üçün əsas düyməyə toxunun" - - - - + "%1$s cihazından istifadəyə başlamağa hazırsınız" + "cihaz" "Sistem naviqasiya ayarları" "Paylaşın" "Skrinşot" @@ -94,8 +92,7 @@ "Ləğv edin" "Ötürün" "Ekranı fırladın" - - + "Tapşırıq panelində təhsil" "Tapşırıq panelindəki təlim bölməsi görünür" "Tapşırıq panelindəki təlim bölməsi bağlanıb" "Tətbiqləri keçirmək üçün tapşırıq panelindən istifadə edin" @@ -112,10 +109,8 @@ "Sonuncular" "Bildirişlər" "Sürətli Ayarlar" - - - - + "Tapşırıq paneli" + "Naviqasiya paneli" "Yuxarı/sola köçürün" "Aşağı/sağa köçürün" diff --git a/quickstep/res/values-b+sr+Latn/strings.xml b/quickstep/res/values-b+sr+Latn/strings.xml index 307d2b2966..26397a28c8 100644 --- a/quickstep/res/values-b+sr+Latn/strings.xml +++ b/quickstep/res/values-b+sr+Latn/strings.xml @@ -78,10 +78,8 @@ "Gotovo!" "Prevucite nagore da biste otvorili početni ekran" "Dodirnite dugme Početak da bisti išli na početni ekran" - - - - + "Spremni ste da počnete da koristite %1$s" + "uređaj" "Podešavanja kretanja kroz sistem" "Deli" "Snimak ekrana" @@ -94,8 +92,7 @@ "Otkaži" "Preskoči" "Rotirajte ekran" - - + "Uputstva na traci zadataka" "Edukativno okno iz trake zadataka se pojavilo" "Edukativno okno iz trake zadataka je zatvoreno" "Koristite traku zadataka da biste menjali aplikacije" @@ -112,10 +109,8 @@ "Nedavno" "Obaveštenja" "Brza podešavanja" - - - - + "Traka zadataka" + "Traka za navigaciju" "Premesti gore levo" "Premesti dole desno" diff --git a/quickstep/res/values-be/strings.xml b/quickstep/res/values-be/strings.xml index a3b55568da..c3d04e938c 100644 --- a/quickstep/res/values-be/strings.xml +++ b/quickstep/res/values-be/strings.xml @@ -78,10 +78,8 @@ "Гатова!" "Каб перайсці на галоўны экран, правядзіце пальцам уверх" "Каб перайсці на галоўны экран, націсніце кнопку галоўнага экрана" - - - - + "Вы можаце пачаць карыстанне прыладай \"%1$s\"" + "прылада" "Налады навігацыі ў сістэме" "Абагуліць" "Здымак экрана" @@ -94,8 +92,7 @@ "Скасаваць" "Прапусціць" "Павярнуць экран" - - + "Інфармацыя пра панэль задач" "З\'явілася панэль навучання на панэлі задач" "Панэль навучання на панэлі задач закрыта" "Выкарыстоўвайце панэль задач для пераключэння праграм" @@ -112,10 +109,8 @@ "Нядаўнія" "Апавяшчэнні" "Хуткія налады" - - - - + "Панэль задач" + "Панэль навігацыі" "Перамясціць уверх/улева" "Перамясціць уніз/управа" diff --git a/quickstep/res/values-bg/strings.xml b/quickstep/res/values-bg/strings.xml index 1d44effe4a..736182ee2d 100644 --- a/quickstep/res/values-bg/strings.xml +++ b/quickstep/res/values-bg/strings.xml @@ -77,27 +77,22 @@ "Урок %1$d/%2$d" "Готово!" "Прекарайте пръст нагоре, за да отворите началния екран" - - - - - - + "Докоснете бутона „Начало“, за да преминете към началния екран" + "Можете да започнете да използвате %1$s" + "устройството" "Настройки за навигиране в системата" "Споделяне" "Екранна снимка" "Разделяне на екрана" "Докоснете друго прил., за да ползвате разд. екран" - - + "За разделен екран изберете още едно приложение" "Това действие не е разрешено от приложението или организацията ви" "Пропускане на урока за навигиране?" "Урокът е налице в приложението %1$s" "Отказ" "Пропускане" "Завъртане на екрана" - - + "Урок за лентата на задачите" "Показва се урокът за лентата на задачите" "Урокът за лентата на задачите бе затворен" "Използвайте лентата на задачите за превключване между прил." @@ -114,10 +109,8 @@ "Скорошни" "Известия" "Бързи настройки" - - - - + "Лента на задачите" + "Лента за навигация" "Преместване горе/вляво" "Преместване долу/вдясно" diff --git a/quickstep/res/values-bn/strings.xml b/quickstep/res/values-bn/strings.xml index 992599e388..5ebd94ce53 100644 --- a/quickstep/res/values-bn/strings.xml +++ b/quickstep/res/values-bn/strings.xml @@ -78,10 +78,8 @@ "সব রেডি!" "হোম স্ক্রিনে যেতে উপরের দিকে সোয়াইপ করুন" "আপনার হোম স্ক্রিনে যাওয়ার জন্য হোম বোতামে ট্যাপ করুন" - - - - + "%1$s ব্যবহার শুরু করার জন্য আপনি রেডি" + "ডিভাইস" "সিস্টেম নেভিগেশন সেটিংস" "শেয়ার করুন" "স্ক্রিনশট নিন" @@ -94,8 +92,7 @@ "বাতিল করুন" "এড়িয়ে যান" "স্ক্রিন ঘোরান" - - + "টাস্কবার এডুকেশন" "টাস্কবার এডুকেশন দেখানো হয়েছে" "টাস্কবার এডুকেশন বন্ধ করা আছে" "অ্যাপ পাল্টানোর জন্য টাস্কবার ব্যবহার করুন" @@ -112,10 +109,8 @@ "সম্প্রতি" "বিজ্ঞপ্তি" "দ্রুত সেটিংস" - - - - + "টাস্কবার" + "নেভিগেশন বার" "উপরে/বাঁদিকে সরান" "নিচে/ডানদিকে সরান" diff --git a/quickstep/res/values-bs/strings.xml b/quickstep/res/values-bs/strings.xml index 18803ded38..7a40c3479c 100644 --- a/quickstep/res/values-bs/strings.xml +++ b/quickstep/res/values-bs/strings.xml @@ -78,10 +78,8 @@ "Sve je spremno!" "Prevucite prema gore da odete na početni ekran" "Dodirnite dugme za početni ekran da odete napočetni ekran" - - - - + "Sve je spremno da počnete koristiti uređaj %1$s" + "uređaj" "Postavke navigiranja sistemom" "Dijeli" "Snimak ekrana" @@ -94,8 +92,7 @@ "Otkaži" "Preskoči" "Rotiranje ekrana" - - + "Edukacija o traci zadataka" "Edukacija o programskoj traci je prikazana" "Edukacija o programskoj traci je zatvorena" "Koristite programsku traku da promijenite aplikacije" @@ -112,10 +109,8 @@ "Nedavno" "Obavještenja" "Brze postavke" - - - - + "Traka zadataka" + "Navigaciona traka" "Premjesti gore lijevo" "Premjesti dolje desno" diff --git a/quickstep/res/values-ca/strings.xml b/quickstep/res/values-ca/strings.xml index 86e16a1432..0c5d742142 100644 --- a/quickstep/res/values-ca/strings.xml +++ b/quickstep/res/values-ca/strings.xml @@ -77,27 +77,22 @@ "Tutorial %1$d/%2$d" "Tot a punt!" "Llisca cap amunt per anar a la pàgina d\'inici" - - - - - - + "Toca el botó d\'inici per anar a la pantalla d\'inici" + "Ja pots començar a utilitzar %1$s" + "dispositiu" "Configuració de navegació del sistema" "Comparteix" "Captura de pantalla" "Divideix" "Toca una altra aplicació per dividir la pantalla" - - + "Tria una altra app per utilitzar pantalla dividida" "L\'aplicació o la teva organització no permeten aquesta acció" "Vols ometre el tutorial de navegació?" "Pots trobar-lo més tard a l\'aplicació %1$s" "Cancel·la" "Omet" "Gira la pantalla" - - + "Informació sobre Barra de tasques" "Ha aparegut el tauler educatiu de la barra de tasques" "S\'ha tancat el tauler educatiu de la barra de tasques" "Utilitza la barra de tasques per canviar d\'aplicació" @@ -114,10 +109,8 @@ "Recents" "Notificacions" "Config. ràpida" - - - - + "Barra de tasques" + "Barra de navegació" "Mou a la part superior o a l\'esquerra" "Mou a la part inferior o a la dreta" diff --git a/quickstep/res/values-cs/strings.xml b/quickstep/res/values-cs/strings.xml index 15f209aace..848f12fb64 100644 --- a/quickstep/res/values-cs/strings.xml +++ b/quickstep/res/values-cs/strings.xml @@ -78,10 +78,8 @@ "Hotovo!" "Přejetím nahoru se vrátíte na plochu" "Klepnutím na tlačítko plochy se vrátíte na plochu" - - - - + "Jste připraveni začít používat %1$s" + "zařízení" "Nastavení navigace v systému" "Sdílet" "Snímek obrazovky" @@ -94,8 +92,7 @@ "Zrušit" "Přeskočit" "Otočit obrazovku" - - + "Informace o panelu aplikací" "Zobrazila se výuka k hlavnímu panelu" "Výuka k hlavnímu panelu byla zavřena" "Aplikace lze přepínat pomocí hlavního panelu" @@ -112,10 +109,8 @@ "Poslední" "Oznámení" "Rychlé nastavení" - - - - + "Panel aplikací" + "Navigační panel" "Přesunout doleva nahoru" "Přesunout doprava dolů" diff --git a/quickstep/res/values-da/strings.xml b/quickstep/res/values-da/strings.xml index 42f7d613db..cb05088c0b 100644 --- a/quickstep/res/values-da/strings.xml +++ b/quickstep/res/values-da/strings.xml @@ -78,10 +78,8 @@ "Alt er parat!" "Stryg opad for at gå til startsiden" "Tryk på knappen Hjem for at gå til din startskærm" - - - - + "Du er klar til at bruge din %1$s" + "enhed" "Indstillinger for systemnavigation" "Del" "Screenshot" @@ -94,8 +92,7 @@ "Annuller" "Spring over" "Roter skærm" - - + "Oplysninger om proceslinjen" "Vejledningen om proceslinjen blev åbnet" "Vejledningen om proceslinjen blev lukket" "Skift mellem apps ved hjælp af proceslinjen" @@ -112,10 +109,8 @@ "Seneste" "Notifikationer" "Kvikmenu" - - - - + "Proceslinje" + "Navigationslinje" "Flyt til toppen eller venstre side" "Flyt til bunden eller højre side" diff --git a/quickstep/res/values-de/strings.xml b/quickstep/res/values-de/strings.xml index 11d7f3dd5f..1857e2a54c 100644 --- a/quickstep/res/values-de/strings.xml +++ b/quickstep/res/values-de/strings.xml @@ -77,27 +77,22 @@ "Anleitung %1$d/%2$d" "Fertig!" "Nach oben wischen, um den Startbildschirm aufzurufen" - - - - - - + "Startbildschirmtaste drücken, um zum Startbildschirm zu gehen" + "Du kannst dein Gerät (%1$s) jetzt verwenden" + "Gerät" "Einstellungen der Systemsteuerung" "Teilen" "Screenshot" "Teilen" "Für „Bildschirm teilen“ auf weitere App tippen" - - + "Für geteilten Bildschirm andere App auswählen" "Die App oder deine Organisation lässt diese Aktion nicht zu" "Navigationstutorial überspringen?" "Du findest es später auch in der %1$s App" "Abbrechen" "Überspringen" "Bildschirm drehen" - - + "Informationen zur Taskleiste" "Anleitung für Taskleiste eingeblendet" "Anleitung für Taskleiste geschlossen" "Über die Taskleiste zwischen Apps wechseln" @@ -114,10 +109,8 @@ "Letzte Apps" "Benachrichtigungen" "Schnelleinstellungen" - - - - + "Taskleiste" + "Navigationsleiste" "Nach oben / Nach links verschieben" "Nach unten / Nach rechts verschieben" diff --git a/quickstep/res/values-el/strings.xml b/quickstep/res/values-el/strings.xml index 95e0a26ec0..b9a70fa2ab 100644 --- a/quickstep/res/values-el/strings.xml +++ b/quickstep/res/values-el/strings.xml @@ -78,10 +78,8 @@ "Όλα έτοιμα!" "Σύρετε προς τα πάνω για μετάβαση στην αρχική οθόνη." "Πατήστε το κουμπί αρχικής οθόνης για να μεταβείτε στην αρχική οθόνη" - - - - + "Είστε έτοιμοι να ξεκινήσετε να χρησιμοποιείτε το/τη %1$s" + "συσκευή" "Ρυθμίσεις πλοήγησης συστήματος" "Κοινοποίηση" "Στιγμιότυπο οθόνης" @@ -94,8 +92,7 @@ "Ακύρωση" "Παράβλεψη" "Περιστροφή οθόνης" - - + "Πληροφορίες χρήσης της Γραμμής εργαλείων" "Η εκπαίδευση για τη γραμμή εργασιών εμφανίστηκε" "Η εκπαίδευση για τη γραμμή εργασιών έκλεισε" "Χρήση της γραμμής εργασιών για εναλλαγή εφαρμογών" @@ -112,10 +109,8 @@ "Πρόσφατα" "Ειδοποιήσεις" "Γρήγορες ρυθμ." - - - - + "Γραμμή εργαλείων" + "Γραμμή πλοήγησης" "Μετακίνηση επάνω/αριστερά" "Μετακίνηση κάτω/δεξιά" diff --git a/quickstep/res/values-en-rAU/strings.xml b/quickstep/res/values-en-rAU/strings.xml index 30fca73df8..9f73e92c50 100644 --- a/quickstep/res/values-en-rAU/strings.xml +++ b/quickstep/res/values-en-rAU/strings.xml @@ -78,10 +78,8 @@ "Ready!" "Swipe up to go home" "Tap the home button to go to your home screen" - - - - + "You’re ready to start using your %1$s" + "device" "System navigation settings" "Share" "Screenshot" @@ -94,8 +92,7 @@ "Cancel" "Skip" "Rotate screen" - - + "Taskbar education" "Taskbar education appeared" "Taskbar education closed" "Use the taskbar to switch apps" @@ -112,10 +109,8 @@ "Recents" "Notifications" "Quick Settings" - - - - + "Taskbar" + "Navigation bar" "Move to top/left" "Move to bottom/right" diff --git a/quickstep/res/values-en-rCA/strings.xml b/quickstep/res/values-en-rCA/strings.xml index d8cd13d8ae..4727ad261c 100644 --- a/quickstep/res/values-en-rCA/strings.xml +++ b/quickstep/res/values-en-rCA/strings.xml @@ -78,10 +78,8 @@ "All set!" "Swipe up to go Home" "Tap the home button to go to your home screen" - - - - + "You’re ready to start using your %1$s" + "device" "System navigation settings" "Share" "Screenshot" @@ -94,8 +92,7 @@ "Cancel" "Skip" "Rotate screen" - - + "Taskbar education" "Taskbar education appeared" "Taskbar education closed" "Use the taskbar to switch apps" @@ -112,10 +109,8 @@ "Recents" "Notifications" "Quick Settings" - - - - + "Taskbar" + "Navigation bar" "Move to top/left" "Move to bottom/right" diff --git a/quickstep/res/values-en-rGB/strings.xml b/quickstep/res/values-en-rGB/strings.xml index 30fca73df8..9f73e92c50 100644 --- a/quickstep/res/values-en-rGB/strings.xml +++ b/quickstep/res/values-en-rGB/strings.xml @@ -78,10 +78,8 @@ "Ready!" "Swipe up to go home" "Tap the home button to go to your home screen" - - - - + "You’re ready to start using your %1$s" + "device" "System navigation settings" "Share" "Screenshot" @@ -94,8 +92,7 @@ "Cancel" "Skip" "Rotate screen" - - + "Taskbar education" "Taskbar education appeared" "Taskbar education closed" "Use the taskbar to switch apps" @@ -112,10 +109,8 @@ "Recents" "Notifications" "Quick Settings" - - - - + "Taskbar" + "Navigation bar" "Move to top/left" "Move to bottom/right" diff --git a/quickstep/res/values-en-rIN/strings.xml b/quickstep/res/values-en-rIN/strings.xml index 30fca73df8..9f73e92c50 100644 --- a/quickstep/res/values-en-rIN/strings.xml +++ b/quickstep/res/values-en-rIN/strings.xml @@ -78,10 +78,8 @@ "Ready!" "Swipe up to go home" "Tap the home button to go to your home screen" - - - - + "You’re ready to start using your %1$s" + "device" "System navigation settings" "Share" "Screenshot" @@ -94,8 +92,7 @@ "Cancel" "Skip" "Rotate screen" - - + "Taskbar education" "Taskbar education appeared" "Taskbar education closed" "Use the taskbar to switch apps" @@ -112,10 +109,8 @@ "Recents" "Notifications" "Quick Settings" - - - - + "Taskbar" + "Navigation bar" "Move to top/left" "Move to bottom/right" diff --git a/quickstep/res/values-en-rXC/strings.xml b/quickstep/res/values-en-rXC/strings.xml index 8394c46ddf..3dedd32b62 100644 --- a/quickstep/res/values-en-rXC/strings.xml +++ b/quickstep/res/values-en-rXC/strings.xml @@ -78,10 +78,8 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‏‎‏‏‏‎‏‎‏‎‎‎‎‎‎‎‎‏‏‎‏‎‎‏‏‎‎‏‎‎‎‏‏‎‏‎‏‎‎‏‎‏‏‎‎‎‏‎‏‏‎‎‏‏‎All set!‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‎‏‎‏‏‏‏‏‏‎‏‎‏‏‎‎‎‏‎‎‏‏‎‎‎‎‏‎‏‏‎‎‎‏‏‏‏‎‎‎‎‎‏‏‏‏‏‎‏‏‏‏‏‏‎Swipe up to go Home‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‎‎‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‏‎‏‏‎‏‎‎‎‏‎‎‎‎‎‎‏‎‎‎‎‎‎‏‎‏‏‏‏‏‎‏‏‏‏‎‎‏‏‎Tap the home button to go to your home screen‎‏‎‎‏‎" - - - - + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‎‏‎‏‏‏‏‎‏‎‎‏‎‎‎‏‏‏‏‎‎‎‏‎‏‏‏‏‎‎‎‎‏‎‏‏‎‎‏‎‏‎‏‎‎‎‎‎‎‎‎‎‎‏‏‏‏‎You’re ready to start using your ‎‏‎‎‏‏‎%1$s‎‏‎‎‏‏‏‎‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‏‎‎‎‏‏‎‏‏‏‏‎‏‏‎‏‎‎‎‎‎‎‎‎‎‎‎‏‏‏‎‏‏‏‏‎‎‏‏‏‏‏‎‏‏‏‏‎‏‏‎‎‎‎‏‎‏‏‏‎device‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‎‎‎‎‏‎‎‎‎‏‎‎‎‎‏‏‎‏‎‏‎‎‎‎‎‏‏‎‎‎‎‏‎‏‏‏‏‎‏‏‏‎‏‏‎‎‏‎‎‏‏‎""‎‏‎‎‏‏‏‎System navigation settings‎‏‎‎‏‏‎""‎‏‎‎‏‏‏‎‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‏‏‎‎‎‎‎‏‎‏‎‎‎‎‏‎‎‎‎‎‎‏‏‎‏‏‎‎‎‎‎‎‎‏‏‏‏‎‏‏‎‎‎‏‏‎‏‎‎‎‎‏‎‏‏‏‎Share‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‏‎‎‎‏‎‏‏‎‎‏‎‏‏‎‏‎‏‎‏‏‏‎‏‎‏‎‏‎‏‎‏‎‎‏‏‎‎‏‏‎‎‏‏‎‎‏‎‎‎‎‏‏‏‏‎‎‎‏‎‏‎Screenshot‎‏‎‎‏‎" @@ -94,8 +92,7 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‎‎‏‏‎‏‏‏‏‏‎‏‎‎‎‏‏‏‏‎‏‎‎‎‎‏‏‎‏‎‎‏‎‎‎‏‎‏‎‏‏‏‏‏‏‏‎‏‏‏‎‏‏‎‏‏‎‎‎Cancel‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‏‏‎‏‎‏‏‏‏‎‎‏‎‏‏‎‎‎‎‎‏‎‏‏‎‎‏‏‎‎‏‎‏‎‎‏‏‏‏‎‎‎‏‎‏‎‎‎‎‎‏‎‏‎‎‏‏‎‎‎‎Skip‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‎‏‎‎‎‏‏‏‎‎‎‏‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‎‎‏‎‎‎‎‎‎‏‏‏‎‏‏‏‏‎‏‏‎‏‎‎‏‏‏‏‏‎Rotate screen‎‏‎‎‏‎" - - + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‎‏‏‎‎‎‎‏‎‎‎‏‏‎‏‏‎‎‏‏‏‎‏‎‎‏‎‏‎‎‏‎‎‏‎‎‏‎‏‏‎‎‎‏‏‎‎‏‏‏‏‏‎‏‏‎Taskbar education‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‏‎‏‏‎‏‏‎‏‎‎‏‎‎‎‎‏‏‏‎‏‏‏‏‏‏‏‎‎‏‎‎‎‎‏‎‎‏‎‏‎‏‎‎‎‎‎‎‏‏‎‎‎‎‎‎‏‏‎‎‏‎Taskbar education appeared‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‏‏‎‏‏‎‏‏‏‎‎‏‏‏‎‎‎‏‏‎‏‏‎‏‎‏‎‎‏‎‎‏‎‏‎‏‏‏‏‎‎‏‏‏‏‏‎‎Taskbar education closed‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‎‎‎‎‏‎‏‏‎‏‎‎‎‎‎‎‎‎‏‎‏‏‎‏‎‎‏‎‏‏‎‏‏‎‎‎‏‎‏‎‏‎‏‏‎‎‏‏‏‎‎‏‏‏‎‏‏‎‏‎Use the taskbar to switch apps‎‏‎‎‏‎" @@ -112,10 +109,8 @@ "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‎‎‏‏‏‏‎‎‎‎‎‎‏‏‏‎‎‏‎‎‎‎‏‏‏‏‎‏‎‏‎‏‎‎‏‏‏‏‏‏‏‎‏‎‎‏‎‎‎‏‎‎‎‎‏‏‏‎‎Recents‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‏‎‎‏‏‏‏‎‏‏‎‎‎‎‏‏‏‏‎‏‎‎‎‏‎‎‎‎‏‏‎‏‎‎‎‎‎‏‏‎‎‎‏‏‎‎‎‏‎‏‏‏‏‎‏‎‎‎‎‏‏‎‎Notifications‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‎‏‎‏‏‎‎‏‎‏‎‎‎‏‏‎‏‎‎‏‎‎‎‏‏‎‎‏‎‎‎‏‏‎‏‏‎‏‏‏‎‎‎‏‎‎‎‎‎‎‎‏‏‎‎‎‎‏‏‏‏‎Quick Settings‎‏‎‎‏‎" - - - - + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‏‏‎‎‏‎‏‎‎‎‎‏‏‏‎‏‎‏‎‎‎‎‏‎‏‏‏‎‎‏‏‏‎‏‎‏‏‎‎‏‏‏‏‎‎‎‎‎‏‏‏‎‎‏‎‏‎‎‏‏‎‎Taskbar‎‏‎‎‏‎" + "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‎‏‎‎‎‏‏‏‎‏‏‎‏‏‎‏‎‎‎‎‏‏‏‏‏‏‏‏‎‏‏‎‎‎‏‏‎‎‏‏‏‏‏‎‎‏‏‎‏‎‎‎‏‏‎‏‎‎‏‏‎Navigation bar‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‎‏‎‏‎‎‏‎‏‏‏‏‎‏‎‎‎‎‎‎‎‎‎‏‏‎‎‏‏‎‏‎‏‏‎‏‏‏‏‎‏‎‏‎‎‎‎‏‎‎‏‏‏‏‏‏‎‎‏‏‏‏‏‎Move to top/left‎‏‎‎‏‎" "‎‏‎‎‎‎‎‏‎‏‏‏‎‎‎‎‎‎‏‎‎‎‏‏‎‏‏‏‏‏‏‏‏‏‎‎‏‎‏‏‎‏‏‎‎‎‎‎‎‎‏‎‏‏‏‏‏‎‎‎‏‎‎‏‏‎‏‎‎‎‏‎‏‏‎‏‎‎‏‏‏‎‎‏‏‎‏‏‏‏‎‎‎‎‏‎‎Move to bottom/right‎‏‎‎‏‎" diff --git a/quickstep/res/values-es-rUS/strings.xml b/quickstep/res/values-es-rUS/strings.xml index 1ab25e65f4..11a1a5217b 100644 --- a/quickstep/res/values-es-rUS/strings.xml +++ b/quickstep/res/values-es-rUS/strings.xml @@ -78,10 +78,8 @@ "Todo listo" "Desliza el dedo hacia arriba para ir a la pantalla principal" "Presiona el botón de inicio para ir a la pantalla principal" - - - - + "Ya puedes comenzar a usar %1$s" + "dispositivo" "Configuración de navegación del sistema" "Compartir" "Captura de pantalla" @@ -94,8 +92,7 @@ "Cancelar" "Omitir" "Girar pantalla" - - + "Información sobre la barra de tareas" "Se abrió la barra de herramientas Educación" "Se cerró la barra de herramientas Educación" "Usa la barra de tareas para cambiar de app" @@ -112,10 +109,8 @@ "Recientes" "Notificaciones" "Config. rápida" - - - - + "Barra de tareas" + "Barra de navegación" "Mover a la parte superior o izquierda" "Mover a la parte inferior o derecha" diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml index 1c73134f0c..6b20800493 100644 --- a/quickstep/res/values-es/strings.xml +++ b/quickstep/res/values-es/strings.xml @@ -77,27 +77,22 @@ "Tutorial %1$d/%2$d" "¡Ya está!" "Desliza el dedo hacia arriba para ir a la pantalla de inicio" - - - - - - + "Toca el botón de inicio para ir a la pantalla de inicio" + "Ya puedes empezar a usar tu %1$s" + "dispositivo" "Ajustes de navegación del sistema" "Compartir" "Hacer captura" "Dividir" "Toca otra aplicación para usar la pantalla dividida" - - + "Elige otra app para usar la pantalla dividida" "No puedes hacerlo porque la aplicación o tu organización no lo permiten" "¿Saltar tutorial de navegación?" "Puedes consultarlo en otro momento en la aplicación %1$s" "Cancelar" "Saltar" "Girar la pantalla" - - + "Información sobre la barra de tareas" "Ha aparecido una nota sobre la barra de tareas" "Nota sobre la barra de tareas cerrada" "Usa la barra de tareas para cambiar de aplicación" @@ -114,10 +109,8 @@ "Recientes" "Notificaciones" "Ajustes rápidos" - - - - + "Barra de tareas" + "Barra de navegación" "Mover arriba/a la izquierda" "Mover abajo/a la derecha" diff --git a/quickstep/res/values-et/strings.xml b/quickstep/res/values-et/strings.xml index 19b3817c7c..be25c930c3 100644 --- a/quickstep/res/values-et/strings.xml +++ b/quickstep/res/values-et/strings.xml @@ -78,10 +78,8 @@ "Valmis!" "Avakuvale liikumiseks pühkige üles" "Avakuvale liikumiseks puudutage avakuva nuppu" - - - - + "Olete valmis oma seadet %1$s kasutama" + "seade" "Süsteemi navigeerimisseaded" "Jaga" "Ekraanipilt" @@ -94,8 +92,7 @@ "Tühista" "Jäta vahele" "Pöörake ekraani" - - + "Tegumiriba tutvustus" "Tegumiriba juhised kuvati" "Tegumiriba juhised on suletud" "Kasutage rakenduste vahetamiseks tegumiriba" @@ -112,10 +109,8 @@ "Hiljutised" "Märguanded" "Kiirseaded" - - - - + "Tegumiriba" + "Navigeerimisriba" "Teisalda üles/vasakule" "Teisalda alla/paremale" diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml index 94a48f93e4..f79d78f1c2 100644 --- a/quickstep/res/values-fa/strings.xml +++ b/quickstep/res/values-fa/strings.xml @@ -78,10 +78,8 @@ "همه چیز آماده است!" "برای رفتن به «صفحه اصلی»، تند به‌بالا بکشید" "برای رفتن به صفحه اصلی، روی دکمه صفحه اصلی ضربه بزنید" - - - - + "آماده‌اید از %1$s خود استفاده کنید" + "دستگاه" "تنظیمات پیمایش سیستم" "هم‌رسانی" "نماگرفت" @@ -94,8 +92,7 @@ "لغو" "رد شدن" "چرخاندن صفحه" - - + "آموزش نوار وظیفه" "پانل آموزشی نوار وظیفه نمایان شد" "پانل آموزشی نوار وظیفه بسته شد" "برای جابه‌جایی بین برنامه‌ها، از نوار وظیفه استفاده کنید" @@ -112,10 +109,8 @@ "موارد اخیر" "اعلان‌ها" "تنظیمات فوری" - - - - + "نوار وظیفه" + "نوار پیمایش" "انتقال به بالا/ چپ" "انتقال به پایین/ راست" diff --git a/quickstep/res/values-fi/strings.xml b/quickstep/res/values-fi/strings.xml index a5c2b9cd96..2af0539561 100644 --- a/quickstep/res/values-fi/strings.xml +++ b/quickstep/res/values-fi/strings.xml @@ -78,10 +78,8 @@ "Valmis" "Siirry aloitusnäytölle pyyhkäisemällä ylös" "Siirry aloitusnäytölle napauttamalla aloitusnäyttöpainiketta" - - - - + "%1$s on nyt valmis käytettäväksi" + "Laite" "Järjestelmän navigointiasetukset" "Jaa" "Kuvakaappaus" @@ -94,8 +92,7 @@ "Peru" "Ohita" "Käännä näyttö" - - + "Tehtäväpalkin ohje" "Tehtäväpalkin ohje näkyvissä" "Tehtäväpalkin ohje suljettu" "Vaihda sovellusta tehtäväpalkin kautta" @@ -112,10 +109,8 @@ "Viimeaikaiset" "Ilmoitukset" "Pika-asetukset" - - - - + "Tehtäväpalkki" + "Navigointipalkki" "Siirrä ylös tai vasemmalle" "Siirrä alas tai oikealle" diff --git a/quickstep/res/values-fr-rCA/strings.xml b/quickstep/res/values-fr-rCA/strings.xml index 261b25561e..54425c0faa 100644 --- a/quickstep/res/values-fr-rCA/strings.xml +++ b/quickstep/res/values-fr-rCA/strings.xml @@ -77,27 +77,22 @@ "Étape %1$d sur %2$d du tutoriel" "Tout est prêt!" "Balayez l\'écran vers le haut pour accéder à l\'écran d\'accueil" - - - - - - + "Toucher le bouton d\'accueil pour passer sur votre écran d\'accueil" + "Vous êtes maintenant prêt à utiliser votre %1$s" + "appareil" "Paramètres de navigation du système" "Partager" "Capture d\'écran" "Séparé" "Touchez une autre appli pour partager l\'écran" - - + "Choisir une autre application pour utiliser l\'écran partagé" "L\'application ou votre organisation n\'autorise pas cette action" "Ignorer le tutoriel sur la navigation?" "Vous trouverez le tutoriel dans l\'application %1$s" "Annuler" "Ignorer" "Faire pivoter l\'écran" - - + "Informations sur la barre des tâches" "La barre des tâches éducatives s\'est affichée" "La barre des tâches éducatives est fermée" "Utilisez la barre des tâches pour changer les applications" @@ -114,10 +109,8 @@ "Récents" "Notifications" "Paramètres rapides" - - - - + "Barre des tâches" + "Barre de navigation" "Déplacer vers le coin supérieur gauche de l\'écran" "Déplacer vers le coin inférieur droit de l\'écran" diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml index 4eb5ebb5eb..4a048b5fcc 100644 --- a/quickstep/res/values-fr/strings.xml +++ b/quickstep/res/values-fr/strings.xml @@ -78,10 +78,8 @@ "Tout est prêt !" "Balayez l\'écran vers le haut pour revenir à l\'accueil" "Appuyez sur le bouton d\'accueil pour accéder à votre écran d\'accueil" - - - - + "Vous pouvez maintenant utiliser votre %1$s" + "appareil" "Paramètres de navigation système" "Partager" "Capture d\'écran" @@ -94,8 +92,7 @@ "Annuler" "Passer" "Faire pivoter l\'écran" - - + "Fonctionnement de la barre des tâches" "Infos sur la barre des tâches affichées" "Infos sur la barre des tâches fermées" "Utilisez la barre des tâches pour changer d\'application" @@ -112,10 +109,8 @@ "Récents" "Notifications" "Réglages rapides" - - - - + "Barre des tâches" + "Barre de navigation" "Déplacer en haut ou à gauche" "Déplacer en bas ou à droite" diff --git a/quickstep/res/values-gl/strings.xml b/quickstep/res/values-gl/strings.xml index e3dacb6b9c..5176674c45 100644 --- a/quickstep/res/values-gl/strings.xml +++ b/quickstep/res/values-gl/strings.xml @@ -78,10 +78,8 @@ "Todo listo" "Pasa o dedo cara arriba para ir á pantalla de inicio" "Toca o botón de inicio para ir á pantalla de inicio" - - - - + "Xa podes comezar a utilizar o teu dispositivo (%1$s)" + "dispositivo" "Configuración da navegación do sistema" "Compartir" "Facer captura" @@ -94,8 +92,7 @@ "Cancelar" "Omitir" "Xira a pantalla" - - + "Información sobre a función Barra de tarefas" "Panel de información de barra de tarefas aberto" "Panel de información de barra de tarefas pechado" "Usa a barra de ferramentas para cambiar de aplicación" @@ -112,10 +109,8 @@ "Recentes" "Notificacións" "Configuración rápida" - - - - + "Barra de tarefas" + "Barra de navegación" "Mover á parte superior ou á esquerda" "Mover á parte inferior ou á dereita" diff --git a/quickstep/res/values-hr/strings.xml b/quickstep/res/values-hr/strings.xml index 5201c24905..1c5504a52e 100644 --- a/quickstep/res/values-hr/strings.xml +++ b/quickstep/res/values-hr/strings.xml @@ -78,10 +78,8 @@ "Sve je spremno!" "Prijeđite prstom prema gore da biste otvorili početni zaslon" "Dodirnite gumb početnog zaslona da biste prešli na početni zaslon" - - - - + "Spremni ste za početak upotrebe uređaja %1$s" + "uređaj" "Postavke navigacije sustavom" "Podijeli" "Snimka zaslona" @@ -94,8 +92,7 @@ "Odustani" "Preskoči" "Zakretanje zaslona" - - + "Upute za traku sa zadacima" "Upute za programsku traku su se pojavile" "Upute za programsku traku su zatvorene" "Upotrijebite program. traku da biste promijenili aplikaciju" @@ -112,10 +109,8 @@ "Najnovije" "Obavijesti" "Brze postavke" - - - - + "Traka sa zadacima" + "Navigacijska traka" "Premjesti gore/lijevo" "Premjesti dolje/desno" diff --git a/quickstep/res/values-hu/strings.xml b/quickstep/res/values-hu/strings.xml index 35ed5a9221..96ac70e168 100644 --- a/quickstep/res/values-hu/strings.xml +++ b/quickstep/res/values-hu/strings.xml @@ -78,10 +78,8 @@ "Kész is!" "Felfelé csúsztatva megjelenik a Kezdőképernyő" "A kezdőképernyőre való lépéshez koppintson a kezdőképernyő gombra" - - - - + "Készen áll a(z) %1$s használatára" + "eszköz" "Rendszer-navigációs beállítások" "Megosztás" "Képernyőkép" @@ -94,8 +92,7 @@ "Mégse" "Kihagyás" "Képernyő elforgatása" - - + "Tálca használatának ismertetése" "Az eszköztár használatát ismertető panel megjelent" "Az eszköztár használatát ismertető panel bezárult" "Az eszköztárral válthat az alkalmazások között" @@ -112,10 +109,8 @@ "Legutóbbiak" "Értesítések" "Gyorsbeállítások" - - - - + "Tálca" + "Navigációs sáv" "Mozgatás felülre vagy a bal oldalra" "Mozgatás alulra vagy a jobb oldalra" diff --git a/quickstep/res/values-hy/strings.xml b/quickstep/res/values-hy/strings.xml index bb27ef24c5..4e20fa4dac 100644 --- a/quickstep/res/values-hy/strings.xml +++ b/quickstep/res/values-hy/strings.xml @@ -78,10 +78,8 @@ "Պատրաստ է" "Մատը սահեցրեք վերև՝ հիմնական էկրան անցնելու համար" "Հիմնական էկրան վերադառնալու համար սեղմեք գլխավոր էկրանի կոճակը" - - - - + "Դուք արդեն կարող եք օգտագործել ձեր %1$s սարքը" + "սարք" "Նավիգացիայի համակարգային կարգավորումներ" "Կիսվել" "Սքրինշոթ անել" @@ -94,8 +92,7 @@ "Չեղարկել" "Բաց թողնել" "Պտտել էկրանը" - - + "Խնդրագոտու «Կրթություն» պատուհան" "Խնդրագոտու «Կրթություն» վահանակը բացվեց" "Խնդրագոտու «Կրթություն» վահանակը փակվեց" "Օգտագործեք խնդրագոտին՝ մի հավելվածից մյուսին անցնելու համար" @@ -112,10 +109,8 @@ "Վերջինները" "Ծանուցումներ" "Արագ կարգավորումներ" - - - - + "Խնդրագոտի" + "Նավիգացիայի գոտի" "Տեղափոխել վերևի ձախ անկյուն" "Տեղափոխել ներքևի աջ անկյուն" diff --git a/quickstep/res/values-in/strings.xml b/quickstep/res/values-in/strings.xml index 68604b96dd..9b8d842822 100644 --- a/quickstep/res/values-in/strings.xml +++ b/quickstep/res/values-in/strings.xml @@ -78,10 +78,8 @@ "Semua siap." "Geser ke atas untuk beralih ke Layar utama" "Ketuk tombol layar utama untuk membuka layar utama" - - - - + "Anda sudah siap untuk mulai menggunakan %1$s" + "perangkat" "Setelan navigasi sistem" "Bagikan" "Screenshot" @@ -94,8 +92,7 @@ "Batal" "Lewati" "Putar layar" - - + "Pengantar Taskbar" "Edukasi taskbar ditampilkan" "Edukasi taskbar ditutup" "Gunakan taskbar untuk beralih aplikasi" @@ -112,10 +109,8 @@ "Terbaru" "Notifikasi" "Setelan Cepat" - - - - + "Taskbar" + "Menu navigasi" "Pindahkan ke atas/kiri" "Pindahkan ke bawah/kanan" diff --git a/quickstep/res/values-is/strings.xml b/quickstep/res/values-is/strings.xml index 39dfbee9fe..73a76a7dfd 100644 --- a/quickstep/res/values-is/strings.xml +++ b/quickstep/res/values-is/strings.xml @@ -78,10 +78,8 @@ "Allt tilbúið!" "Strjúktu upp til að fara á heimaskjáinn" "Ýttu á heimahnappinn til að fara á heimaskjáinn" - - - - + "Þú getur byrjað að nota %1$s" + "tækið" "Stillingar kerfisstjórnunar" "Deila" "Skjámynd" @@ -94,8 +92,7 @@ "Hætta við" "Sleppa" "Snúa skjánum" - - + "Leiðsögn verkefnastiku" "Leiðsögn verkefnastiku sýnileg" "Leiðsögn verkefnastiku lokað" "Notaðu verkefnastikuna til að skipta á milli forrita" @@ -112,10 +109,8 @@ "Nýlegt" "Tilkynningar" "Flýtistillingar" - - - - + "Verkstika" + "Yfirlitsstika" "Færa efst/til vinstri" "Færa neðst/til hægri" diff --git a/quickstep/res/values-it/strings.xml b/quickstep/res/values-it/strings.xml index ad5197e98a..9f7b4e6bf7 100644 --- a/quickstep/res/values-it/strings.xml +++ b/quickstep/res/values-it/strings.xml @@ -78,10 +78,8 @@ "Finito." "Scorri verso l\'alto per andare alla schermata Home" "Tocca il pulsante Home per andare alla schermata Home" - - - - + "Puoi iniziare a usare il tuo %1$s" + "dispositivo" "Impostazioni Navigazione del sistema" "Condividi" "Screenshot" @@ -94,8 +92,7 @@ "Annulla" "Salta" "Ruota lo schermo" - - + "Informazioni sulla barra delle applicazioni" "Riquadro Formazione barra delle applicazioni visualizzato" "Riquadro Formazione barra delle applicazioni chiuso" "Usa la barra delle applicazioni per cambiare app" @@ -112,10 +109,8 @@ "Recenti" "Notifiche" "Impostazioni rapide" - - - - + "Barra delle applicazioni" + "Barra di navigazione" "Sposta in alto/a sinistra" "Sposta in basso/a destra" diff --git a/quickstep/res/values-iw/strings.xml b/quickstep/res/values-iw/strings.xml index be508b9f6c..5663bca0fb 100644 --- a/quickstep/res/values-iw/strings.xml +++ b/quickstep/res/values-iw/strings.xml @@ -78,10 +78,8 @@ "הכול מוכן!" "כדי לעבור לדף הבית, מחליקים כלפי מעלה" "כדי לעבור אל מסך הבית יש להקיש על הלחצן הראשי" - - - - + "הכול מוכן ואפשר להתחיל להשתמש ב%1$s" + "מכשיר" "הגדרות הניווט של המערכת" "שיתוף" "צילום מסך" @@ -94,8 +92,7 @@ "ביטול" "דילוג" "סיבוב המסך" - - + "הסבר על סרגל האפליקציות" "חלונית ההסברים על שורת המשימות מופיעה" "חלונית ההסברים על שורת המשימות נסגרה" "כדי לעבור בין אפליקציות, משתמשים בשורת המשימות" @@ -112,10 +109,8 @@ "לאחרונה" "התראות" "הגדרות מהירות" - - - - + "סרגל האפליקציות" + "סרגל הניווט" "העברה לפינה השמאלית/העליונה" "העברה לפינה הימנית/התחתונה" diff --git a/quickstep/res/values-ja/strings.xml b/quickstep/res/values-ja/strings.xml index 4349d46db5..9716ca06ec 100644 --- a/quickstep/res/values-ja/strings.xml +++ b/quickstep/res/values-ja/strings.xml @@ -78,10 +78,8 @@ "設定完了" "ホームに移動するには上にスワイプします" "ホームボタンをタップすると、ホーム画面に移動します" - - - - + "%1$s を使用する準備ができました" + "デバイス" "システム ナビゲーションの設定" "共有" "スクリーンショット" @@ -94,8 +92,7 @@ "キャンセル" "スキップ" "画面を回転" - - + "タスクバーの説明" "タスクバーの説明を開きました" "タスクバーの説明を閉じました" "アプリを切り替えるには、タスクバーを使用します" @@ -112,10 +109,8 @@ "最近" "通知" "クイック設定" - - - - + "タスクバー" + "ナビゲーション バー" "上 / 左に移動" "下 / 右に移動" diff --git a/quickstep/res/values-ka/strings.xml b/quickstep/res/values-ka/strings.xml index a3895b1ca3..bad68a0556 100644 --- a/quickstep/res/values-ka/strings.xml +++ b/quickstep/res/values-ka/strings.xml @@ -78,10 +78,8 @@ "მზადაა!" "მთავარ გვერდზე გადასასვლელად გადაფურცლეთ ზევით" "შეეხეთ მთავარი ეკრანის ღილაკს მთავარ ეკრანზე გადასასვლელად" - - - - + "მზად ხართ, გამოიყენოთ %1$s" + "მოწყობილობა" "სისტემის ნავიგაციის პარამეტრები" "გაზიარება" "ეკრანის ანაბეჭდი" @@ -94,8 +92,7 @@ "გაუქმება" "გამოტოვება" "ეკრანის შეტრიალება" - - + "ამოცანათა ზოლი: განათლება" "ამოცანების ზოლის სასწავლო არე გამოჩნდა" "ამოცანების ზოლის სასწავლო არე დაიხურა" "აპების გადასართავად გამოიყენეთ ამოცანათა ზოლი" @@ -112,10 +109,8 @@ "ბოლოდროინდელი" "შეტყობინებები" "სწრაფი პარამეტრები" - - - - + "ამოცანათა ზოლი" + "ნავიგაციის ზოლი" "ზემოთ/მარცხნივ გადატანა" "ქვემოთ/მარჯვნივ გადატანა" diff --git a/quickstep/res/values-kk/strings.xml b/quickstep/res/values-kk/strings.xml index 35341760e0..c778ea9c45 100644 --- a/quickstep/res/values-kk/strings.xml +++ b/quickstep/res/values-kk/strings.xml @@ -77,27 +77,22 @@ "Оқулық: %1$d/%2$d" "Бәрі дайын!" "Негізгі экранға өту үшін жоғары қарай сырғытыңыз." - - - - - - + "Негізгі экранға өту үшін негізгі экран түймесін түртіңіз." + "%1$s пайдалануға дайын." + "құрылғы" "Навигацияның жүйелік параметрлері" "Бөлісу" "Скриншот" "Бөлу" "Экранды бөлу режимін пайдалану үшін басқа қолданбаны түртіңіз." - - + "Экранды бөлу үшін басқа қолданбаны таңдаңыз." "Бұл әрекетке қолданба не ұйым рұқсат етпейді." "Қимылдар оқулығын өткізіп жіберу керек пе?" "Мұны кейін %1$s қолданбасынан таба аласыз." "Бас тарту" "Өткізіп жіберу" "Экранды бұру" - - + "Тапсырмалар жолағы: үйрену" "Тапсырмалар тақтасы бойынша нұсқаулық ашылды." "Тапсырмалар тақтасы бойынша нұсқаулық жабылды." "Қолданбаларды ауыстыру үшін тапсырма тақтасын пайдаланыңыз." @@ -114,10 +109,8 @@ "Соңғылары" "Хабарландырулар" "Жылдам параметрлер" - - - - + "Тапсырмалар жолағы" + "Навигация жолағы" "Жоғары/солға жылжыту" "Төмен/оңға жылжыту" diff --git a/quickstep/res/values-km/strings.xml b/quickstep/res/values-km/strings.xml index 4880a30d81..13b4e1d12e 100644 --- a/quickstep/res/values-km/strings.xml +++ b/quickstep/res/values-km/strings.xml @@ -78,10 +78,8 @@ "រួចហើយ!" "អូសឡើងលើ ដើម្បី​ទៅកាន់​អេក្រង់ដើម" "ចុចប៊ូតុងដើម ដើម្បីចូលទៅកាន់អេក្រង់ដើមរបស់អ្នក" - - - - + "អ្នកអាចចាប់ផ្ដើមប្រើ %1$s របស់អ្នកបានហើយ" + "ឧបករណ៍" "ការកំណត់​ការរុករក​ប្រព័ន្ធ" "ចែករំលែក" "រូបថតអេក្រង់" @@ -94,8 +92,7 @@ "បោះបង់" "រំលង" "បង្វិលអេក្រង់" - - + "ការអប់រំលើរបារកិច្ចការ" "ការបង្រៀនអំពីរបារកិច្ចការបានបង្ហាញ" "ការបង្រៀនអំពីរបារកិច្ចការត្រូវបានបិទ" "ប្រើ​របារកិច្ចការ ដើម្បី​ប្ដូរកម្មវិធី" @@ -112,10 +109,8 @@ "ថ្មីៗ" "ការ​ជូនដំណឹង" "ការកំណត់រហ័ស" - - - - + "របារកិច្ចការ" + "របាររុករក" "ផ្លាស់ទីទៅខាងលើ/ឆ្វេង" "ផ្លាស់ទីទៅខាងក្រោម/ស្ដាំ" diff --git a/quickstep/res/values-kn/strings.xml b/quickstep/res/values-kn/strings.xml index 2f308b743e..92340b7161 100644 --- a/quickstep/res/values-kn/strings.xml +++ b/quickstep/res/values-kn/strings.xml @@ -78,10 +78,8 @@ "ಎಲ್ಲವೂ ಸಿದ್ಧವಾಗಿದೆ!" "ಮುಖಪುಟಕ್ಕೆ ಹೋಗಲು ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ" "ನಿಮ್ಮ ಮುಖಪುಟದ ಪರದೆಗೆ ಹೋಗಲು ಮುಖಪುಟ ಬಟನ್ ಅನ್ನು ಟ್ಯಾಪ್ ಮಾಡಿ" - - - - + "ನಿಮ್ಮ %1$s ಬಳಸುವುದನ್ನು ಪ್ರಾರಂಭಿಸಲು ನೀವು ಸಿದ್ಧರಾಗಿರುವಿರಿ" + "ಸಾಧನ" "ಸಿಸ್ಟಂ ನ್ಯಾವಿಗೇಶನ್ ಸೆಟ್ಟಿಂಗ್‌ಗಳು" "ಹಂಚಿಕೊಳ್ಳಿ" "ಸ್ಕ್ರೀನ್‌ಶಾಟ್" @@ -94,8 +92,7 @@ "ರದ್ದುಮಾಡಿ" "ಸ್ಕಿಪ್ ಮಾಡಿ" "ಸ್ಕ್ರೀನ್ ತಿರುಗಿಸಿ" - - + "ಟಾಸ್ಕ್‌ಬಾರ್ ಶಿಕ್ಷಣ" "ಟಾಸ್ಕ್‌ಬಾರ್ ಶಿಕ್ಷಣ ಕಾಣಿಸಿಕೊಂಡಿದೆ" "ಟಾಸ್ಕ್‌ಬಾರ್ ಶಿಕ್ಷಣ ಮುಚ್ಚಿದೆ" "ಆ್ಯಪ್‌ಗಳನ್ನು ಬದಲಾಯಿಸಲು ಟಾಸ್ಕ್ ಬಾರ್ ಬಳಸಿ" @@ -112,10 +109,8 @@ "ಇತ್ತೀಚಿನವು" "ಅಧಿಸೂಚನೆಗಳು" "ತ್ವರಿತ ಸೆಟ್ಟಿಂಗ್‍ಗಳು" - - - - + "ಟಾಸ್ಕ್‌ಬಾರ್" + "ನ್ಯಾವಿಗೇಷನ್ ಬಾರ್" "ಮೇಲಿನ/ಎಡಭಾಗಕ್ಕೆ ಸರಿಸಿ" "ಕೆಳಗಿನ/ಬಲಭಾಗಕ್ಕೆ ಸರಿಸಿ" diff --git a/quickstep/res/values-ko/strings.xml b/quickstep/res/values-ko/strings.xml index bf7727e17b..19d3128618 100644 --- a/quickstep/res/values-ko/strings.xml +++ b/quickstep/res/values-ko/strings.xml @@ -78,10 +78,8 @@ "설정 완료" "위로 스와이프하여 홈으로 이동" "홈 화면으로 이동하려면 홈 버튼을 탭하세요." - - - - + "%1$s 기기를 사용할 준비가 되었습니다." + "기기" "시스템 탐색 설정" "공유" "스크린샷" @@ -94,8 +92,7 @@ "취소" "건너뛰기" "화면 회전" - - + "태스크 바 정보" "작업 표시줄 튜토리얼 패널 표시됨" "작업 표시줄 튜토리얼 패널 닫힘" "작업 표시줄을 사용하여 앱 전환" @@ -112,10 +109,8 @@ "최근 항목" "알림" "빠른 설정" - - - - + "태스크 바" + "탐색 메뉴" "상단/왼쪽으로 이동" "하단/오른쪽으로 이동" diff --git a/quickstep/res/values-ky/strings.xml b/quickstep/res/values-ky/strings.xml index 95c569f31b..f8b4c78e4b 100644 --- a/quickstep/res/values-ky/strings.xml +++ b/quickstep/res/values-ky/strings.xml @@ -77,27 +77,22 @@ "Үйрөткүч: %1$d/%2$d" "Бүттү!" "Башкы бетке өтүү үчүн экранды өйдө сүрүңүз" - - - - - - + "Башкы экранга өтүү үчүн башкы бет баскычын таптап коюңуз" + "%1$s түзмөгүн колдоно берсеңиз болот" + "түзмөк" "Өтүү аракетинин системалык параметрлери" "Бөлүшүү" "Скриншот" "Бөлүү" "Экранды бөлүү үчүн башка колдонмону таптап коюңуз" - - + "Экранды бөлүү үчүн башка колдонмону тандаңыз" "Бул аракетти аткарууга колдонмо же ишканаңыз тыюу салган" "Жаңсоолор үйрөткүчүн өткөрүп жибересизби?" "Аны кийин %1$s колдонмосунан табасыз" "Жокко чыгаруу" "Өткрп жиберүү" "Экранды буруу" - - + "Тапшырмалар панели жөнүндө маалымат" "Тапшырмалар тактасынын окутуу панели көрсөтүлдү" "Тапшырмалар тактасынын окутуу панели жабылды" "Тапшырмалар тактасы аркылуу башка колдонмого которула аласыз" @@ -114,10 +109,8 @@ "Акыркылар" "Билдирмелер" "Ыкчам жөндөөлөр" - - - - + "Тапшырмалар панели" + "Чабыттоо тилкеси" "Жогорку/сол бурчка жылдыруу" "Төмөнкү/оң бурчка жылдыруу" diff --git a/quickstep/res/values-lo/strings.xml b/quickstep/res/values-lo/strings.xml index 8e857b2c16..a5074cb172 100644 --- a/quickstep/res/values-lo/strings.xml +++ b/quickstep/res/values-lo/strings.xml @@ -78,10 +78,8 @@ "ຮຽບຮ້ອຍໝົດແລ້ວ!" "ປັດຂຶ້ນເພື່ອໄປຫາໜ້າຫຼັກ" "ແຕະປຸ່ມໜ້າທຳອິດເພື່ອໄປຫາໂຮມສະກຣີນຂອງທ່ານ" - - - - + "ທ່ານເລີ່ມໃຊ້ແທັບເລັດ %1$s ຂອງທ່ານໄດ້ແລ້ວ" + "ອຸປະກອນ" "ການຕັ້ງຄ່າການນຳທາງລະບົບ" "ແບ່ງປັນ" "ຮູບໜ້າຈໍ" @@ -94,8 +92,7 @@ "ຍົກເລີກ" "ຂ້າມ" "ໝຸນໜ້າຈໍ" - - + "ແຖບໜ້າວຽກ Education" "ສະແດງການສຶກສາແຖບໜ້າວຽກແລ້ວ" "ປິດການສຶກສາແຖບໜ້າວຽກແລ້ວ" "ໃຊ້ແຖບໜ້າວຽກເພື່ອສະຫຼັບແອັບ" @@ -112,10 +109,8 @@ "ຫຼ້າສຸດ" "ການແຈ້ງເຕືອນ" "ການຕັ້ງຄ່າດ່ວນ" - - - - + "ແຖບໜ້າວຽກ" + "ແຖບການນຳທາງ" "ຍ້າຍໄປຊ້າຍ/ເທິງ" "ຍ້າຍໄປຂວາ/ລຸ່ມ" diff --git a/quickstep/res/values-lt/strings.xml b/quickstep/res/values-lt/strings.xml index 2e1958bc9b..cf42a386cb 100644 --- a/quickstep/res/values-lt/strings.xml +++ b/quickstep/res/values-lt/strings.xml @@ -78,10 +78,8 @@ "Paruošta!" "Perbraukite aukštyn, kad grįžtumėte į pagrindinį ekraną" "Norėdami eiti į pagrindinį ekraną, palieskite pagrindinio ekrano mygtuką" - - - - + "Esate pasirengę pradėti naudoti %1$s" + "įrenginys" "Sistemos naršymo nustatymai" "Bendrinti" "Ekrano kopija" @@ -94,8 +92,7 @@ "Atšaukti" "Praleisti" "Pasukti ekraną" - - + "Užduočių juostos mokomoji informacija" "Užduočių juostos patarimai rodomi" "Užduočių juostos patarimai uždaryti" "Naudokite užduočių juostą, kad gal. perjungti programas" @@ -112,10 +109,8 @@ "Naujausi" "Pranešimai" "Spartieji nustatymai" - - - - + "Užduočių juosta" + "Naršymo juosta" "Perkelti aukštyn, kairėn" "Perkelti žemyn, dešinėn" diff --git a/quickstep/res/values-lv/strings.xml b/quickstep/res/values-lv/strings.xml index 3b7029ee62..ed25347d14 100644 --- a/quickstep/res/values-lv/strings.xml +++ b/quickstep/res/values-lv/strings.xml @@ -78,10 +78,8 @@ "Gatavs!" "Velciet augšup, lai pārietu uz sākuma ekrānu." "Pieskarieties pogai Sākums, lai dotos uz sākuma ekrānu" - - - - + "Varat sākt izmantot savu ierīci (%1$s)" + "ierīce" "Sistēmas navigācijas iestatījumi" "Kopīgot" "Veikt ekrānuzņēmumu" @@ -94,8 +92,7 @@ "Atcelt" "Izlaist" "Pagriezt ekrānu" - - + "Informācija par uzdevumu joslu" "Tika atvērta uzdevumjoslas apmācība" "Tika aizvērta uzdevumjoslas apmācība" "Izmantojiet uzdevumjoslu, lai pārslēgtu lietotnes." @@ -112,10 +109,8 @@ "Nesenie" "Paziņojumi" "Ātrie iestatīj." - - - - + "Uzdevumu josla" + "Navigācijas josla" "Pārvietot uz augšējo/kreiso stūri" "Pārvietot uz apakšējo/labo stūri" diff --git a/quickstep/res/values-mk/strings.xml b/quickstep/res/values-mk/strings.xml index fa96161015..894da61372 100644 --- a/quickstep/res/values-mk/strings.xml +++ b/quickstep/res/values-mk/strings.xml @@ -78,10 +78,8 @@ "Готово!" "Повлечете нагоре за да појдете на почетниот екран" "Допрете го копчето за почетен екран за да одите на почетниот екран" - - - - + "Подготвени сте да почнете да го користите вашиот %1$s" + "уред" "Поставки за системска навигација" "Сподели" "Слика од екранот" @@ -94,8 +92,7 @@ "Откажи" "Прескокни" "Ротирајте го екранот" - - + "Обука за лентата со задачи" "Се појави лентата за задачи за образование" "Затворена е лентата за задачи за образование" "Префрлувајте се меѓу апликации преку лентата за задачи" @@ -112,10 +109,8 @@ "Неодамнешни" "Известувања" "Брзи поставки" - - - - + "Лента со задачи" + "Лента за навигација" "Премести горе лево" "Премести долу десно" diff --git a/quickstep/res/values-mn/strings.xml b/quickstep/res/values-mn/strings.xml index 027a343037..2ce38208b8 100644 --- a/quickstep/res/values-mn/strings.xml +++ b/quickstep/res/values-mn/strings.xml @@ -78,10 +78,8 @@ "Тохируулж дууслаа!" "Нүүр хуудас руу очихын тулд дээш шударна уу" "Үндсэн нүүр лүүгээ очихын тулд нүүр хуудасны товчлуурыг товшино уу" - - - - + "Та %1$s-г ашиглаж эхлэхэд бэлэн боллоо" + "төхөөрөмж" "Системийн навигацын тохиргоо" "Хуваалцах" "Дэлгэцийн агшин дарах" @@ -94,8 +92,7 @@ "Цуцлах" "Алгасах" "Дэлгэцийг эргүүлэх" - - + "Ажлын хэсгийн боловсрол" "Боловсролын ажлын талбар гарч ирсэн" "Боловсролын ажлын талбарыг хаасан" "Аппуудыг сэлгэхийн тулд талбарыг ашиглана уу" @@ -112,10 +109,8 @@ "Саяхны" "Мэдэгдэл" "Шуурхай тохиргоо" - - - - + "Ажлын хэсэг" + "Навигацын самбар" "Зүүн дээд хэсэг рүү зөөх" "Баруун доод хэсэг рүү зөөх" diff --git a/quickstep/res/values-mr/strings.xml b/quickstep/res/values-mr/strings.xml index 2fcf758890..e1fb2519c9 100644 --- a/quickstep/res/values-mr/strings.xml +++ b/quickstep/res/values-mr/strings.xml @@ -78,10 +78,8 @@ "सर्व तयार आहे!" "होम वर जाण्यासाठी वरती स्वाइप करा" "तुमच्या होम स्क्रीनवर जाण्यासाठी होम बटणावर टॅप करा" - - - - + "तुम्ही तुमचे %1$s वापरण्यास सुरुवात करू शकता" + "डिव्हाइस" "सिस्टीम नेव्हिगेशन सेटिंग्ज" "शेअर करा" "स्क्रीनशॉट" @@ -94,8 +92,7 @@ "रद्द करा" "वगळा" "स्क्रीन फिरवा" - - + "टास्कबारशी संबंधित माहिती" "टास्कबारशी संबंधित माहिती देणारे पॅनल उघडले आहे" "टास्कबारशी संबंधित माहिती देणारे पॅनल बंद केले आहे" "ॲप्स स्विच करण्यासाठी टास्कबार वापरा" @@ -112,10 +109,8 @@ "अलीकडील" "सूचना" "क्विक सेटिंग्ज" - - - - + "टास्कबार" + "नेव्हिगेशन बार" "सर्वात वरती/डावीकडे हलवा" "तळाशी/उजवीकडे हलवा" diff --git a/quickstep/res/values-ms/strings.xml b/quickstep/res/values-ms/strings.xml index 3f49c1253c..f614532f9d 100644 --- a/quickstep/res/values-ms/strings.xml +++ b/quickstep/res/values-ms/strings.xml @@ -78,10 +78,8 @@ "Siap!" "Leret ke atas untuk kembali ke Laman Utama" "Ketik butang skrin utama untuk pergi ke skrin utama anda" - - - - + "Anda sudah sedia untuk mula menggunakan %1$s anda" + "peranti" "Tetapan navigasi sistem" "Kongsi" "Tangkapan skrin" @@ -94,8 +92,7 @@ "Batal" "Langkau" "Putar skrin" - - + "Pendidikan bar tugas" "Pendidikan bar tugas muncul" "Pendidikan bar tugas ditutup" "Gunakan bar tugas untuk menukar apl" @@ -112,10 +109,8 @@ "Terbaharu" "Pemberitahuan" "Tetapan Pantas" - - - - + "Bar Tugas" + "Bar navigasi" "Alihkan ke atas/kiri" "Alihkan ke bawah/kanan" diff --git a/quickstep/res/values-nb/strings.xml b/quickstep/res/values-nb/strings.xml index bf4daa7fd1..63286c1df4 100644 --- a/quickstep/res/values-nb/strings.xml +++ b/quickstep/res/values-nb/strings.xml @@ -78,10 +78,8 @@ "Alt er klart!" "Sveip opp for å gå til startskjermen" "Trykk på hjemknappen for å gå til startskjermen" - - - - + "Nå kan du bruke %1$s" + "enheten" "Innstillinger for systemnavigasjon" "Del" "Skjermdump" @@ -94,8 +92,7 @@ "Avbryt" "Hopp over" "Rotér skjermen" - - + "Veiledning for oppgavelinjen" "Opplæringen for oppgavelinjen vises" "Opplæringen for oppgavelinjen er lukket" "Bruk oppgavelinjen for å bytte app" @@ -112,10 +109,8 @@ "Nylige" "Varsler" "Hurtiginnst." - - - - + "Oppgavelinje" + "Navigasjonsrad" "Flytt til øverst/venstre" "Flytt til nederst/høyre" diff --git a/quickstep/res/values-nl/strings.xml b/quickstep/res/values-nl/strings.xml index 4887930cef..40ef9b5254 100644 --- a/quickstep/res/values-nl/strings.xml +++ b/quickstep/res/values-nl/strings.xml @@ -78,10 +78,8 @@ "Klaar" "Swipe omhoog om naar het startscherm te gaan" "Tik op de startknop om naar je startscherm te gaan" - - - - + "Je bent klaar om je %1$s te gebruiken" + "apparaat" "Navigatie-instellingen van systeem" "Delen" "Screenshot" @@ -94,8 +92,7 @@ "Annuleren" "Overslaan" "Scherm draaien" - - + "Taakbalk Onderwijs" "Uitleg van taakbalk geopend" "Uitleg van taakbalk gesloten" "Gebruik de taakbalk om van app te wisselen" @@ -112,10 +109,8 @@ "Recent" "Meldingen" "Snelle instellingen" - - - - + "Taakbalk" + "Navigatiebalk" "Naar boven/links verplaatsen" "Naar beneden/rechts verplaatsen" diff --git a/quickstep/res/values-or/strings.xml b/quickstep/res/values-or/strings.xml index 9a0681f68b..475d0a1a48 100644 --- a/quickstep/res/values-or/strings.xml +++ b/quickstep/res/values-or/strings.xml @@ -78,10 +78,8 @@ "ସମ୍ପୂର୍ଣ୍ଣ ଭାବେ ପ୍ରସ୍ତୁତ!" "ହୋମକୁ ଯିବା ପାଇଁ ଉପରକୁ ସ୍ୱାଇପ କରନ୍ତୁ" "ଆପଣଙ୍କ ହୋମ ସ୍କ୍ରିନକୁ ଯିବା ପାଇଁ ହୋମ ବଟନରେ ଟାପ କରନ୍ତୁ" - - - - + "ଆପଣ ଆପଣଙ୍କ %1$s ବ୍ୟବହାର କରିବା ଆରମ୍ଭ କରିବାକୁ ପ୍ରସ୍ତୁତ ଅଛନ୍ତି" + "ଡିଭାଇସ" "ସିଷ୍ଟମ ନାଭିଗେସନ ସେଟିଂସ" "ସେୟାର୍ କରନ୍ତୁ" "ସ୍କ୍ରିନସଟ୍" @@ -94,8 +92,7 @@ "ବାତିଲ କରନ୍ତୁ" "ବାଦ୍ ଦିଅନ୍ତୁ" "ସ୍କ୍ରିନ ଘୂରାନ୍ତୁ" - - + "ଟାସ୍କବାର ଶିକ୍ଷା" "ଟାସ୍କବାର୍ ଶିକ୍ଷା ଦେଖାଯାଇଛି" "ଟାସ୍କବାର୍ ଶିକ୍ଷା ବନ୍ଦ ହୋଇଯାଇଛି" "ଆପଗୁଡ଼ିକୁ ସ୍ୱିଚ କରିବା ପାଇଁ ଟାସ୍କବାର ବ୍ୟବହାର କରନ୍ତୁ" @@ -112,10 +109,8 @@ "ବର୍ତ୍ତମାନର" "ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ" "କ୍ୱିକ ସେଟିଂସ" - - - - + "ଟାସ୍କବାର" + "ନାଭିଗେସନ ବାର" "ଶୀର୍ଷ/ବାମକୁ ମୁଭ କରନ୍ତୁ" "ନିମ୍ନ/ଡାହାଣକୁ ମୁଭ କରନ୍ତୁ" diff --git a/quickstep/res/values-pa/strings.xml b/quickstep/res/values-pa/strings.xml index f217d32835..706fc5112f 100644 --- a/quickstep/res/values-pa/strings.xml +++ b/quickstep/res/values-pa/strings.xml @@ -78,10 +78,8 @@ "ਪੂਰੀ ਤਰ੍ਹਾਂ ਤਿਆਰ!" "ਹੋਮ \'ਤੇ ਜਾਣ ਲਈ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ" "ਆਪਣੀ ਹੋਮ ਸਕ੍ਰੀਨ \'ਤੇ ਜਾਣ ਲਈ ਹੋਮ ਬਟਨ \'ਤੇ ਟੈਪ ਕਰੋ" - - - - + "ਤੁਸੀਂ ਆਪਣਾ %1$s ਵਰਤਣ ਲਈ ਤਿਆਰ ਹੋ" + "ਡੀਵਾਈਸ" "ਸਿਸਟਮ ਨੈਵੀਗੇਸ਼ਨ ਸੈਟਿੰਗਾਂ" "ਸਾਂਝਾ ਕਰੋ" "ਸਕ੍ਰੀਨਸ਼ਾਟ" @@ -94,8 +92,7 @@ "ਰੱਦ ਕਰੋ" "ਛੱਡੋ" "ਸਕ੍ਰੀਨ ਘੁਮਾਓ" - - + "ਟਾਸਕਬਾਰ ਸਿੱਖਿਆ" "ਟਾਸਕਵਾਰ ਸਿੱਖਿਆ ਪੈਨਲ ਦਿਖਾਇਆ ਗਿਆ" "ਟਾਸਕਵਾਰ ਸਿੱਖਿਆ ਪੈਨਲ ਬੰਦ ਕੀਤਾ ਗਿਆ" "ਐਪਾਂ ਸਵਿੱਚ ਕਰਨ ਲਈ ਟਾਸਕਬਾਰ ਵਰਤੋ" @@ -112,10 +109,8 @@ "ਹਾਲੀਆ" "ਸੂਚਨਾਵਾਂ" "ਤਤਕਾਲ ਸੈਟਿੰਗਾਂ" - - - - + "ਟਾਸਕਬਾਰ" + "ਨੈਵੀਗੇਸ਼ਨ ਵਾਲੀ ਪੱਟੀ" "ਸਿਖਰਲੇ/ਖੱਬੇ ਪਾਸੇ ਲੈ ਕੇ ਜਾਓ" "ਹੇਠਾਂ/ਸੱਜੇ ਪਾਸੇ ਲੈ ਕੇ ਜਾਓ" diff --git a/quickstep/res/values-pl/strings.xml b/quickstep/res/values-pl/strings.xml index 99aae6f9d7..8a23000d79 100644 --- a/quickstep/res/values-pl/strings.xml +++ b/quickstep/res/values-pl/strings.xml @@ -77,27 +77,22 @@ "Samouczek %1$d/%2$d" "Wszystko gotowe" "Aby przejść na ekran główny, przesuń palcem w górę" - - - - - - + "Kliknij przycisk ekranu głównego, aby otworzyć ekran główny" + "Teraz możesz zacząć używać urządzenia %1$s" + "urządzenie" "Ustawienia nawigacji w systemie" "Udostępnij" "Zrzut ekranu" "Podziel" "Kliknij drugą aplikację, aby podzielić ekran" - - + "Wybierz drugą aplikację, aby podzielić ekran" "Nie możesz wykonać tego działania, bo nie zezwala na to aplikacja lub Twoja organizacja" "Pominąć samouczek nawigacji?" "Znajdziesz to później w aplikacji %1$s" "Anuluj" "Pomiń" "Obróć ekran" - - + "Informacje o pasku aplikacji" "Wskazówki na temat paska zadań zostały wyświetlone" "Wskazówki na temat paska zadań zostały zamknięte" "Używaj paska zadań, aby przełączać aplikacje" @@ -114,10 +109,8 @@ "Ostatnie" "Powiadomienia" "Szybkie ustawienia" - - - - + "Pasek aplikacji" + "Pasek nawigacyjny" "Przesuń w górny lewy róg" "Przesuń w dolny prawy róg" diff --git a/quickstep/res/values-pt-rPT/strings.xml b/quickstep/res/values-pt-rPT/strings.xml index 8aadb338c6..9ab0df1798 100644 --- a/quickstep/res/values-pt-rPT/strings.xml +++ b/quickstep/res/values-pt-rPT/strings.xml @@ -78,10 +78,8 @@ "Tudo pronto!" "Deslize rapidamente para cima para aceder ao ecrã principal" "Toque no botão página inicial para aceder ao ecrã principal" - - - - + "Já pode começar a usar o seu %1$s" + "dispositivo" "Definições de navegação do sistema" "Partilhar" "Fazer captura de ecrã" @@ -94,8 +92,7 @@ "Cancelar" "Ignorar" "Rodar ecrã" - - + "Educação da Barra de tarefas" "Informação da barra de tarefas apresentada" "Informação da barra de tarefas fechada" "Utilize a barra de ferramentas para alternar entre apps" @@ -112,10 +109,8 @@ "Recentes" "Notificações" "Definiç. rápidas" - - - - + "Barra de tarefas" + "Barra de navegação" "Mover para a parte superior esquerda" "Mover para a part superior direita" diff --git a/quickstep/res/values-ro/strings.xml b/quickstep/res/values-ro/strings.xml index 33d1fef59f..63fed8919b 100644 --- a/quickstep/res/values-ro/strings.xml +++ b/quickstep/res/values-ro/strings.xml @@ -78,10 +78,8 @@ "Gata!" "Glisează în sus pentru a accesa ecranul de pornire" "Atinge butonul ecran de pornire ca să accesezi ecranul de pornire" - - - - + "Ești gata să folosești %1$s" + "dispozitivul" "Setările de navigare ale sistemului" "Distribuie" "Captură de ecran" @@ -94,8 +92,7 @@ "Anulează" "Omite" "Rotește ecranul" - - + "Informații despre bara de activități" "Panoul cu informații despre bara de activități s-a afișat" "Panoul cu informații despre bara de activități s-a închis" "Folosește bara de activități ca să comuți între aplicații" @@ -112,10 +109,8 @@ "Recente" "Notificări" "Setări rapide" - - - - + "Bară de activități" + "Bară de navigare" "Mută în stânga sus" "Mută în dreapta jos" diff --git a/quickstep/res/values-ru/strings.xml b/quickstep/res/values-ru/strings.xml index 23528fde76..55eef44f8d 100644 --- a/quickstep/res/values-ru/strings.xml +++ b/quickstep/res/values-ru/strings.xml @@ -78,10 +78,8 @@ "Готово!" "Чтобы перейти на главный экран, проведите вверх." "Нажмите кнопку главного экрана, чтобы открыть его." - - - - + "Теперь вы можете использовать %1$s." + "устройство" "Системные настройки навигации" "Поделиться" "Скриншот" @@ -94,8 +92,7 @@ "Отмена" "Пропустить" "Повернуть экран" - - + "Обучение по работе с панелью задач" "Обучение по работе с панелью задач показано" "Обучение по работе с панелью задач скрыто" "Используйте панель задач, чтобы переключать приложения." @@ -112,10 +109,8 @@ "Недавние" "Уведомления" "Быстрые настройки" - - - - + "Панель задач" + "Панель навигации" "Переместить вверх или влево" "Переместить вниз или вправо" diff --git a/quickstep/res/values-si/strings.xml b/quickstep/res/values-si/strings.xml index e18f512045..7486e1c0c1 100644 --- a/quickstep/res/values-si/strings.xml +++ b/quickstep/res/values-si/strings.xml @@ -78,10 +78,8 @@ "සියල්ල සූදානම්!" "මුල් පිටුවට යාමට ඉහළට ස්වයිප් කරන්න" "ඔබේ මුල් තිරය වෙත යාමට මුල් පිටුව බොත්තම තට්ටු කරන්න" - - - - + "ඔබ ඔබේ %1$s භාවිත කිරීම පටන් ගැනීමට සූදානම්" + "උපාංගය" "පද්ධති සංචාලන සැකසීම්" "බෙදා ගන්න" "තිර රුව" @@ -94,8 +92,7 @@ "අවලංගු කරන්න" "මඟ හරින්න" "තිරය කරකවන්න" - - + "කාර්ය තීරු අධ්‍යාපනය" "කාර්ය තීරු අධ්‍යාපනය දිස් විය" "කාර්ය තීරු අධ්‍යාපනය වසා ඇත" "යෙදුම් මාරු කිරීමට කාර්ය තීරුව භාවිත කරන්න" @@ -112,10 +109,8 @@ "මෑත" "දැනුම්දීම්" "ඉක්මන් සැකසීම්" - - - - + "කාර්ය තීරුව" + "සංචලන තීරුව" "ඉහළ/වම වෙත ගෙන යන්න" "පහළ/දකුණ වෙත ගෙන යන්න" diff --git a/quickstep/res/values-sk/strings.xml b/quickstep/res/values-sk/strings.xml index 523080d96c..6746d35410 100644 --- a/quickstep/res/values-sk/strings.xml +++ b/quickstep/res/values-sk/strings.xml @@ -78,10 +78,8 @@ "Hotovo" "Potiahnutím nahor prejdete na plochu" "Na plochu prejdete klepnutím na tlačidlo plochy" - - - - + "%1$s môžete začať používať" + "zariadenie" "Nastavenia navigácie systémom" "Zdieľať" "Snímka obrazovky" @@ -94,8 +92,7 @@ "Zrušiť" "Preskočiť" "Otočiť obrazovku" - - + "Panel vzdelávacích aplikácií" "Zobrazila sa výuka k hlavnému panelu" "Výuka k hlavnému panelu bola zatvorená" "Aplikácie je možné prepínať pomocou panela úloh" @@ -112,10 +109,8 @@ "Nedávne" "Upozornenia" "Rýchle nastavenia" - - - - + "Panel aplikácií" + "Navigačný panel" "Presunúť hore alebo doľava" "Presunúť dole alebo doprava" diff --git a/quickstep/res/values-sl/strings.xml b/quickstep/res/values-sl/strings.xml index c80a899480..af0ecec94b 100644 --- a/quickstep/res/values-sl/strings.xml +++ b/quickstep/res/values-sl/strings.xml @@ -78,10 +78,8 @@ "Končano" "Povlecite navzgor za začetni zaslon" "Za pomik na začetni zaslon se dotaknite gumba za začetni zaslon." - - - - + "Pripravljeni ste, da začnete uporabljati %1$s" + "napravo" "Nastavitve krmarjenja po sistemu" "Deli" "Posnetek zaslona" @@ -94,8 +92,7 @@ "Prekliči" "Preskoči" "Sukanje zaslona" - - + "Poučni nasveti o opravilni vrstici" "Poučni nasveti o opravilni vrstici so prikazani." "Poučni nasveti o opravilni vrstici so zaprti." "Za preklop aplikacij uporabite opravilno vrstico." @@ -112,10 +109,8 @@ "Nedavno" "Obvestila" "Hitre nastavitve" - - - - + "Opravilna vrstica" + "Vrstica za krmarjenje" "Premakni na vrh/levo" "Premakni na dno/desno" diff --git a/quickstep/res/values-sq/strings.xml b/quickstep/res/values-sq/strings.xml index 33a8f9f2f5..d90c1e11ff 100644 --- a/quickstep/res/values-sq/strings.xml +++ b/quickstep/res/values-sq/strings.xml @@ -77,27 +77,22 @@ "Udhëzuesi %1$d/%2$d" "Plotësisht gati!" "Rrëshqit shpejt lart për të shkuar tek \"Ekrani bazë\"" - - - - - - + "Trokit te butoni \"kreu\" për të shkuar tek ekrani bazë" + "Je gati që të fillosh të përdorësh %1$s" + "pajisje" "Cilësimet e navigimit të sistemit" "Ndaj" "Pamja e ekranit" "Ndaj" "Trokit aplikacion tjetër e përdor ekranin e ndarë" - - + "Zgjidh një aplikacion tjetër për të përdorur ekranin e ndarë" "Ky veprim nuk lejohet nga aplikacioni ose organizata jote" "Të kapërcehet udhëzuesi i navigimit?" "Këtë mund ta gjesh më vonë tek aplikacioni \"%1$s\"" "Anulo" "Kapërce" "Rrotullo ekranin" - - + "Edukimi për shiritin e detyrave" "Edukimi i shiritit të detyrave u shfaq" "Edukimi nga shiriti i detyrave u mbyll" "Përdor shiritin e detyrave për të ndryshuar aplikacionet" @@ -114,10 +109,8 @@ "Të fundit" "Njoftimet" "Cilësimet shpejt" - - - - + "Shiriti i detyrave" + "Shiriti i navigimit" "Lëviz në krye/majtas" "Lëviz në fund/djathtas" diff --git a/quickstep/res/values-sr/strings.xml b/quickstep/res/values-sr/strings.xml index e53a5a45ac..8452b2ff81 100644 --- a/quickstep/res/values-sr/strings.xml +++ b/quickstep/res/values-sr/strings.xml @@ -78,10 +78,8 @@ "Готово!" "Превуците нагоре да бисте отворили почетни екран" "Додирните дугме Почетак да бисти ишли на почетни екран" - - - - + "Спремни сте да почнете да користите %1$s" + "уређај" "Подешавања кретања кроз систем" "Дели" "Снимак екрана" @@ -94,8 +92,7 @@ "Откажи" "Прескочи" "Ротирајте екран" - - + "Упутства на траци задатака" "Едукативно окно из траке задатака се појавило" "Едукативно окно из траке задатака је затворено" "Користите траку задатака да бисте мењали апликације" @@ -112,10 +109,8 @@ "Недавно" "Обавештења" "Брза подешавања" - - - - + "Трака задатака" + "Трака за навигацију" "Премести горе лево" "Премести доле десно" diff --git a/quickstep/res/values-sv/strings.xml b/quickstep/res/values-sv/strings.xml index 8c3ea532a2..14ff945138 100644 --- a/quickstep/res/values-sv/strings.xml +++ b/quickstep/res/values-sv/strings.xml @@ -78,10 +78,8 @@ "Klart!" "Svep uppåt för att öppna startskärmen" "Tryck på hemknappen för att öppna startskärmen" - - - - + "Nu kan du börja använda din %1$s" + "enhet" "Systemnavigeringsinställningar" "Dela" "Skärmbild" @@ -94,8 +92,7 @@ "Avbryt" "Hoppa över" "Rotera skärmen" - - + "Aktivitetsfältsutbildning" "Information om aktivitetsfältet visades" "Information om aktivitetsfältet stängdes" "Använd aktivitetsfältet för att byta mellan appar" @@ -112,10 +109,8 @@ "Senaste" "Aviseringar" "Snabbinställn." - - - - + "Aktivitetsfält" + "Navigeringsfält" "Flytta högst upp/till vänster" "Flytta längst ned/till höger" diff --git a/quickstep/res/values-sw/strings.xml b/quickstep/res/values-sw/strings.xml index 5bba2c5b3d..09263ea9c9 100644 --- a/quickstep/res/values-sw/strings.xml +++ b/quickstep/res/values-sw/strings.xml @@ -77,8 +77,7 @@ "Mafunzo ya %1$d kati ya %2$d" "Tayari!" "Telezesha kidole juu ili uende kwenye skrini ya kwanza" - - + "Gusa kitufe cha ukurasa wa mwanzo ili uende kwenye skrini ya kwanza" @@ -88,8 +87,7 @@ "Picha ya skrini" "Iliyogawanywa" "Gusa programu nyingine ili utumie skrini iliyogawanywa" - - + "Chagua programu nyingine ili utumie hali ya kugawa skrini" "Kitendo hiki hakiruhusiwi na programu au shirika lako" "Ungependa kuruka mafunzo ya usogezaji?" "Utapata mafunzo haya baadaye katika programu ya %1$s" diff --git a/quickstep/res/values-ta/strings.xml b/quickstep/res/values-ta/strings.xml index 58bcf80919..cb3f69a82e 100644 --- a/quickstep/res/values-ta/strings.xml +++ b/quickstep/res/values-ta/strings.xml @@ -77,8 +77,7 @@ "பயிற்சி %1$d/%2$d" "அனைத்தையும் அமைத்துவிட்டீர்கள்!" "முகப்புத் திரைக்குச் செல்ல மேல்நோக்கி ஸ்வைப் செய்யுங்கள்" - - + "முகப்புத் திரைக்குச் செல்வதற்கு முகப்பு பட்டனைத் தட்டவும்" @@ -88,8 +87,7 @@ "ஸ்கிரீன்ஷாட்" "பிரி" "ஸ்பிளிட் ஸ்கிரீனுக்கு மற்றொரு ஆப்ஸைத் தட்டவும்" - - + "திரைப் பிரிப்பை பயன்படுத்த வேறு ஆப்ஸை தேர்வுசெய்க" "ஆப்ஸோ உங்கள் நிறுவனமோ இந்த செயலை அனுமதிப்பதில்லை" "வழிகாட்டுதல் பயிற்சியைத் தவிர்க்கவா?" "%1$s ஆப்ஸில் பிறகு இதைக் கண்டறியலாம்" diff --git a/quickstep/res/values-te/strings.xml b/quickstep/res/values-te/strings.xml index 313fa4c002..1e481d96e9 100644 --- a/quickstep/res/values-te/strings.xml +++ b/quickstep/res/values-te/strings.xml @@ -78,10 +78,8 @@ "అంతా సెట్ అయింది!" "మొదటి స్క్రీన్‌కు వెళ్లడానికి పైకి స్వైప్ చేయండి" "మీ మొదటి స్క్రీన్‌కు వెళ్లడానికి హోమ్ బటన్‌ను ట్యాప్ చేయండి" - - - - + "మీరు ఇప్పుడు మీ %1$s‌ను ఉపయోగించడం ప్రారంభించవచ్చు" + "పరికరం" "సిస్టమ్ నావిగేషన్ సెట్టింగ్‌లు" "షేర్ చేయండి" "స్క్రీన్‌షాట్" @@ -94,8 +92,7 @@ "రద్దు చేయి" "స్కిప్ చేయండి" "స్క్రీన్‌ను తిప్పండి" - - + "టాస్క్‌బార్ ఎడ్యుకేషన్" "టాస్క్‌బార్ శిక్షణకు సంబంధించిన ప్యానెల్ కనిపించింది" "టాస్క్‌బార్ శిక్షణకు సంబంధించిన ప్యానెల్ మూసివేయబడింది" "యాప్‌లను స్విచ్ చేయడానికి టాస్క్‌బార్‌ను ఉపయోగించండి" @@ -112,10 +109,8 @@ "ఇటీవలివి" "నోటిఫికేషన్‌లు" "క్విక్ సెట్టింగ్‌లు" - - - - + "టాస్క్‌బార్" + "నావిగేషన్ బార్" "ఎగువ/ఎడమ వైపునకు తరలించండి" "దిగువ/కుడి వైపునకు తరలించండి" diff --git a/quickstep/res/values-th/strings.xml b/quickstep/res/values-th/strings.xml index d338c50d1e..159083cd3d 100644 --- a/quickstep/res/values-th/strings.xml +++ b/quickstep/res/values-th/strings.xml @@ -78,10 +78,8 @@ "เรียบร้อยแล้ว" "ปัดขึ้นเพื่อไปที่หน้าแรก" "แตะปุ่มหน้าแรกเพื่อไปที่หน้าจอหลัก" - - - - + "คุณเริ่มใช้%1$sได้แล้ว" + "อุปกรณ์" "การตั้งค่าการนำทางของระบบ" "แชร์" "ภาพหน้าจอ" @@ -94,8 +92,7 @@ "ยกเลิก" "ข้าม" "หมุนหน้าจอ" - - + "แถบงาน Education" "แถบงาน Education ปรากฎขึ้น" "ปิดแถบงาน Education แล้ว" "ใช้แถบงานเพื่อเปลี่ยนแอป" @@ -112,10 +109,8 @@ "ล่าสุด" "การแจ้งเตือน" "การตั้งค่าด่วน" - - - - + "แถบงาน" + "แถบนำทาง" "ย้ายไปที่ด้านบนหรือด้านซ้าย" "ย้ายไปที่ด้านล่างหรือด้านขวา" diff --git a/quickstep/res/values-tl/strings.xml b/quickstep/res/values-tl/strings.xml index 2efb9beae9..4e95f74db8 100644 --- a/quickstep/res/values-tl/strings.xml +++ b/quickstep/res/values-tl/strings.xml @@ -78,10 +78,8 @@ "Handa na ang lahat!" "Mag-swipe pataas para pumunta sa Home" "I-tap ang button ng home para pumunta sa iyong home screen" - - - - + "Handa mo nang simulan ang paggamit sa iyong %1$s" + "device" "Mga setting ng navigation ng system" "Ibahagi" "Screenshot" @@ -94,8 +92,7 @@ "Kanselahin" "Laktawan" "I-rotate ang screen" - - + "Impormasyon sa taskbar" "Lumabas ang edukasyon sa taskbar" "Sarado ang edukasyon sa taskbar" "Gamitin ang taskbar para magpalipat-lipat sa mga app" @@ -112,10 +109,8 @@ "Mga Kamakailan" "Mga Notification" "Quick Settings" - - - - + "Taskbar" + "Navigation bar" "Ilipat sa itaas/kaliwa" "Ilipat sa ibaba/kanan" diff --git a/quickstep/res/values-tr/strings.xml b/quickstep/res/values-tr/strings.xml index c3ebde3f32..341b091c0c 100644 --- a/quickstep/res/values-tr/strings.xml +++ b/quickstep/res/values-tr/strings.xml @@ -78,10 +78,8 @@ "İşlem tamam!" "Ana ekrana gitmek için yukarı kaydırın" "Ana ekranınıza gitmek için ana sayfa düğmesine dokunun" - - - - + "%1$s cihazınızı kullanmaya hazırsınız" + "cihaz" "Sistem gezinme ayarları" "Paylaş" "Ekran görüntüsü" @@ -94,8 +92,7 @@ "İptal" "Atla" "Ekranı döndür" - - + "Görev çubuğu eğitimi" "Görev çubuğu eğitimi görüntülendi" "Görev çubuğu eğitimi kapatıldı" "Görev çubuğundan uygulamalar arasında geçiş yapabilirsiniz" @@ -112,10 +109,8 @@ "Son Kullanılanlar" "Bildirimler" "Hızlı Ayarlar" - - - - + "Görev çubuğu." + "Gezinme çubuğu" "Sol üste taşı" "Sağ alta taşı" diff --git a/quickstep/res/values-uk/strings.xml b/quickstep/res/values-uk/strings.xml index f47ea648e1..76422a4698 100644 --- a/quickstep/res/values-uk/strings.xml +++ b/quickstep/res/values-uk/strings.xml @@ -77,8 +77,7 @@ "Навчальний посібник %1$d/%2$d" "Готово." "Щоб перейти на головний екран, проведіть пальцем угору" - - + "Натисніть кнопку головного екрана, щоб відкрити його" @@ -88,8 +87,7 @@ "Знімок екрана" "Розділити" "Щоб розділити екран, виберіть ще один додаток" - - + "Щоб розділити екран, виберіть ще один додаток" "Ця дія заборонена додатком або адміністратором організації" "Пропустити посібник із навігації?" "Ви знайдете його пізніше в додатку %1$s" diff --git a/quickstep/res/values-ur/strings.xml b/quickstep/res/values-ur/strings.xml index aaf35ff783..e2e4a1209d 100644 --- a/quickstep/res/values-ur/strings.xml +++ b/quickstep/res/values-ur/strings.xml @@ -78,10 +78,8 @@ "سب کچھ تیار ہے!" "ہوم پر جانے کے لیے اوپر سوائپ کریں" "اپنی ہوم اسکرین پر جانے کے لیے ہوم بٹن پر تھپتھپائیں" - - - - + "آپ اپنے %1$s کا استعمال شروع کرنے کے لیے تیار ہیں" + "آلہ" "سسٹم نیویگیشن کی ترتیبات" "اشتراک کریں" "اسکرین شاٹ" @@ -94,8 +92,7 @@ "منسوخ کریں" "نظر انداز کریں" "اسکرین کو گھمائیں" - - + "ٹاسک بار کی تعلیم" "ٹاکس بار کا تعلیمی پینل ظاہر ہو گیا" "ٹاسک بار کا تعلیمی پینل بند ہو گیا" "ایپس کو سوئچ کرنے کیلئے ٹاسک بار کا استعمال کریں" @@ -112,10 +109,8 @@ "حالیہ" "اطلاعات" "فوری ترتیبات" - - - - + "ٹاسک بار" + "نیویگیشن بار" "اوپر/بائیں طرف منتقل کریں" "نیچے/دائیں طرف منتقل کریں" diff --git a/quickstep/res/values-uz/strings.xml b/quickstep/res/values-uz/strings.xml index 5af96eb57e..7bb5df7aa5 100644 --- a/quickstep/res/values-uz/strings.xml +++ b/quickstep/res/values-uz/strings.xml @@ -78,10 +78,8 @@ "Hammasi tayyor!" "Boshiga qaytish uchun tepaga suring" "Bosh ekranga oʻtish uchun bosh ekran tugmasini bosing" - - - - + "%1$s xizmatga tayyor" + "qurilma" "Tizim navigatsiya sozlamalari" "Ulashish" "Skrinshot" @@ -94,8 +92,7 @@ "Bekor qilish" "Tashlab ketish" "Ekranni burish" - - + "Vazifalar paneli qoʻllanmasi" "Taʼlim vazifalar paneli chiqdi" "Taʼlim vazifalar paneli yopildi" "Ilovalarni vazifalar panelida almashtirish mumkin" @@ -112,10 +109,8 @@ "Oxirgilar" "Bildirishnomalar" "Tezkor sozlamalar" - - - - + "Vazifalar paneli" + "Navigatsiya paneli" "Yuqoriga yoki chapga oʻtkazish" "Pastga yoki oʻngga oʻtkazish" diff --git a/quickstep/res/values-vi/strings.xml b/quickstep/res/values-vi/strings.xml index 948ec2031b..8a7cbf41b8 100644 --- a/quickstep/res/values-vi/strings.xml +++ b/quickstep/res/values-vi/strings.xml @@ -78,10 +78,8 @@ "Đã hoàn tất!" "Vuốt lên để chuyển đến Màn hình chính" "Nhấn vào nút màn hình chính để chuyển đến màn hình chính" - - - - + "Bạn có thể bắt đầu sử dụng %1$s" + "thiết bị" "Chế độ cài đặt di chuyển trên hệ thống" "Chia sẻ" "Chụp ảnh màn hình" @@ -94,8 +92,7 @@ "Hủy" "Bỏ qua" "Xoay màn hình" - - + "Cách sử dụng thanh tác vụ" "Đã hiện bảng hướng dẫn trên thanh tác vụ" "Đã đóng bảng hướng dẫn trên thanh tác vụ" "Dùng thanh tác vụ để chuyển đổi ứng dụng" @@ -112,10 +109,8 @@ "Gần đây" "Thông báo" "Cài đặt nhanh" - - - - + "Thanh tác vụ" + "Thanh điều hướng" "Chuyển lên trên cùng/sang bên trái" "Chuyển xuống dưới cùng/sang bên phải" diff --git a/quickstep/res/values-zh-rCN/strings.xml b/quickstep/res/values-zh-rCN/strings.xml index 576ae3a64e..ae204704a3 100644 --- a/quickstep/res/values-zh-rCN/strings.xml +++ b/quickstep/res/values-zh-rCN/strings.xml @@ -78,10 +78,8 @@ "大功告成!" "向上滑动即可转到主屏幕" "点按主屏幕按钮即可前往主屏幕" - - - - + "您可以开始使用%1$s了" + "设备" "系统导航设置" "分享" "屏幕截图" @@ -94,8 +92,7 @@ "取消" "跳过" "旋转屏幕" - - + "任务栏教程" "任务栏教程已显示" "任务栏教程已关闭" "使用任务栏切换应用" @@ -112,10 +109,8 @@ "最近用过" "通知" "快捷设置" - - - - + "任务栏" + "导航栏" "移到顶部/左侧" "移到底部/右侧" diff --git a/quickstep/res/values-zh-rHK/strings.xml b/quickstep/res/values-zh-rHK/strings.xml index 83337a26a9..707195ec29 100644 --- a/quickstep/res/values-zh-rHK/strings.xml +++ b/quickstep/res/values-zh-rHK/strings.xml @@ -78,10 +78,8 @@ "設定完成!" "向上滑動即可前往主畫面" "輕按主按鈕即可前往主畫面" - - - - + "您可以開始使用 %1$s 了" + "裝置" "系統導覽設定" "分享" "螢幕截圖" @@ -94,8 +92,7 @@ "取消" "略過" "旋轉螢幕" - - + "工作列教學" "顯示咗工作列教學" "閂咗工作列教學" "使用工作列即可切換應用程式" @@ -112,10 +109,8 @@ "最近" "通知" "快速設定" - - - - + "工作列" + "導覽列" "移至上方/左側" "移至底部/右側" diff --git a/quickstep/res/values-zh-rTW/strings.xml b/quickstep/res/values-zh-rTW/strings.xml index b6961a194f..8159a2ea35 100644 --- a/quickstep/res/values-zh-rTW/strings.xml +++ b/quickstep/res/values-zh-rTW/strings.xml @@ -78,10 +78,8 @@ "設定完成!" "向上滑動即可前往主畫面" "輕觸主畫面按鈕即可前往主畫面" - - - - + "你可以開始使用「%1$s」了" + "裝置" "系統操作機制設定" "分享" "螢幕截圖" @@ -94,8 +92,7 @@ "取消" "略過" "旋轉螢幕" - - + "工作列教學課程" "工作列教學課程已顯示" "工作列教學課程已關閉" "使用工作列即可切換應用程式" @@ -112,10 +109,8 @@ "最近使用" "通知" "快速設定" - - - - + "工作列" + "導覽列" "移到上方/左側" "移到底部/右側" diff --git a/quickstep/res/values-zu/strings.xml b/quickstep/res/values-zu/strings.xml index 1e6df97a0d..25c6e0ee0e 100644 --- a/quickstep/res/values-zu/strings.xml +++ b/quickstep/res/values-zu/strings.xml @@ -78,10 +78,8 @@ "Konke kusethiwe!" "Swayiphela phezulu ukuze uye Ekhaya" "Thepha inkinobho yasekhaya ukuze uye kusikrini sasekhaya" - - - - + "Usulungele ukuqala ukusebenzisa i-%1$s yakho" + "idivayisi" "Amasethingi wokuzulazula isistimu" "Yabelana" "Isithombe-skrini" @@ -94,8 +92,7 @@ "Khansela" "Yeqa" "Zungezisa isikrini" - - + "Imfundo ye-taskbar" "Imfuno yebha yomsebenzi ivelile" "Imfundo yebha yomsebenzi ivaliwe" "Sebenzisa ibha yomsebenzi ukushintsha ama-app" @@ -112,10 +109,8 @@ "Okwakamuva" "Izaziso" "Amasethingi Asheshayo" - - - - + "I-Taskbar" + "Ibha yokufuna" "Hamba phezulu/kwesokunxele" "Hamba phansi/kwesokudla" From 9a616213e11138510f62b3fab3f381fe479403fd Mon Sep 17 00:00:00 2001 From: Sunny Goyal Date: Mon, 21 Nov 2022 16:20:48 -0800 Subject: [PATCH 303/429] Removing SearchActionItemInfo > Instead introducing an interface for handling click events > Linking this interface to other UI which handle clicks Bug: 259733681 Test: Presubmit and verified manually Change-Id: I9cbf2d009d64254f513deb909a151e46e860d039 --- .../taskbar/TaskbarActivityContext.java | 3 + src/com/android/launcher3/Utilities.java | 5 +- .../model/data/SearchActionItemInfo.java | 189 ------------------ .../SecondaryDisplayLauncher.java | 5 +- .../launcher3/touch/ItemClickHandler.java | 63 ++---- 5 files changed, 22 insertions(+), 243 deletions(-) delete mode 100644 src/com/android/launcher3/model/data/SearchActionItemInfo.java diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index d9d46d4f38..1e29cac248 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -85,6 +85,7 @@ import com.android.launcher3.taskbar.overlay.TaskbarOverlayController; import com.android.launcher3.testing.TestLogging; import com.android.launcher3.testing.shared.TestProtocol; import com.android.launcher3.touch.ItemClickHandler; +import com.android.launcher3.touch.ItemClickHandler.ItemClickProxy; import com.android.launcher3.util.DisplayController; import com.android.launcher3.util.NavigationMode; import com.android.launcher3.util.PackageManagerHelper; @@ -828,6 +829,8 @@ public class TaskbarActivityContext extends BaseTaskbarContext { mControllers.uiController.onTaskbarIconLaunched((AppInfo) tag); } mControllers.taskbarStashController.updateAndAnimateTransientTaskbar(true); + } else if (tag instanceof ItemClickProxy) { + ((ItemClickProxy) tag).onItemClicked(view); } else { Log.e(TAG, "Unknown type clicked: " + tag); } diff --git a/src/com/android/launcher3/Utilities.java b/src/com/android/launcher3/Utilities.java index ce009a1375..b10256e53d 100644 --- a/src/com/android/launcher3/Utilities.java +++ b/src/com/android/launcher3/Utilities.java @@ -73,7 +73,6 @@ import com.android.launcher3.icons.ShortcutCachingLogic; import com.android.launcher3.icons.ThemedIconDrawable; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfoWithIcon; -import com.android.launcher3.model.data.SearchActionItemInfo; import com.android.launcher3.pm.ShortcutConfigActivityInfo; import com.android.launcher3.shortcuts.ShortcutKey; import com.android.launcher3.shortcuts.ShortcutRequest; @@ -591,8 +590,8 @@ public final class Utilities { outObj[0] = icon; return icon; } else if (info.itemType == LauncherSettings.Favorites.ITEM_TYPE_SEARCH_ACTION - && info instanceof SearchActionItemInfo) { - return ((SearchActionItemInfo) info).bitmap.newIcon(context); + && info instanceof ItemInfoWithIcon) { + return ((ItemInfoWithIcon) info).bitmap.newIcon(context); } else { return null; } diff --git a/src/com/android/launcher3/model/data/SearchActionItemInfo.java b/src/com/android/launcher3/model/data/SearchActionItemInfo.java deleted file mode 100644 index 04042ea6fa..0000000000 --- a/src/com/android/launcher3/model/data/SearchActionItemInfo.java +++ /dev/null @@ -1,189 +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.launcher3.model.data; - -import static com.android.launcher3.LauncherSettings.Favorites.EXTENDED_CONTAINERS; - -import android.app.PendingIntent; -import android.content.Context; -import android.content.Intent; -import android.graphics.drawable.Icon; -import android.os.Process; -import android.os.UserHandle; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; - -import com.android.launcher3.LauncherAppState; -import com.android.launcher3.LauncherSettings; -import com.android.launcher3.logger.LauncherAtom.ItemInfo; -import com.android.launcher3.logger.LauncherAtom.SearchActionItem; - -/** - * Represents a SearchAction with in launcher - */ -public class SearchActionItemInfo extends ItemInfoWithIcon implements WorkspaceItemFactory { - - public static final int FLAG_SHOULD_START = 1 << 1; - public static final int FLAG_SHOULD_START_FOR_RESULT = FLAG_SHOULD_START | 1 << 2; - public static final int FLAG_BADGE_WITH_PACKAGE = 1 << 3; - public static final int FLAG_PRIMARY_ICON_FROM_TITLE = 1 << 4; - public static final int FLAG_BADGE_WITH_COMPONENT_NAME = 1 << 5; - public static final int FLAG_ALLOW_PINNING = 1 << 6; - public static final int FLAG_SEARCH_IN_APP = 1 << 7; - - private String mFallbackPackageName; - private int mFlags = 0; - private Icon mIcon; - - // If true title does not contain any personal info and eligible for logging. - private boolean mIsPersonalTitle; - private Intent mIntent; - - private PendingIntent mPendingIntent; - - public SearchActionItemInfo(Icon icon, String packageName, UserHandle user, - CharSequence title, boolean isPersonalTitle) { - mIsPersonalTitle = isPersonalTitle; - this.itemType = LauncherSettings.Favorites.ITEM_TYPE_SEARCH_ACTION; - this.user = user == null ? Process.myUserHandle() : user; - this.title = title; - this.container = EXTENDED_CONTAINERS; - mFallbackPackageName = packageName; - mIcon = icon; - } - - private SearchActionItemInfo(SearchActionItemInfo info) { - super(info); - } - - @Override - public void copyFrom(@NonNull com.android.launcher3.model.data.ItemInfo info) { - super.copyFrom(info); - SearchActionItemInfo itemInfo = (SearchActionItemInfo) info; - this.mFallbackPackageName = itemInfo.mFallbackPackageName; - this.mIcon = itemInfo.mIcon; - this.mFlags = itemInfo.mFlags; - this.mIsPersonalTitle = itemInfo.mIsPersonalTitle; - } - - /** - * Returns if multiple flags are all available. - */ - public boolean hasFlags(int flags) { - return (mFlags & flags) != 0; - } - - public void setFlags(int flags) { - mFlags |= flags; - } - - @Override - @Nullable - public Intent getIntent() { - return mIntent; - } - - /** - * Setter for mIntent with assertion for null value mPendingIntent - */ - public void setIntent(Intent intent) { - if (mPendingIntent != null && intent != null) { - throw new RuntimeException( - "SearchActionItemInfo can only have either an Intent or a PendingIntent"); - } - mIntent = intent; - } - - public PendingIntent getPendingIntent() { - return mPendingIntent; - } - - /** - * Setter of mPendingIntent with assertion for null value mIntent - */ - public void setPendingIntent(PendingIntent pendingIntent) { - if (mIntent != null && pendingIntent != null) { - throw new RuntimeException( - "SearchActionItemInfo can only have either an Intent or a PendingIntent"); - } - mPendingIntent = pendingIntent; - } - - @Nullable - public Icon getIcon() { - return mIcon; - } - - @Override - public ItemInfoWithIcon clone() { - return new SearchActionItemInfo(this); - } - - @NonNull - @Override - public ItemInfo buildProto(@Nullable FolderInfo fInfo) { - SearchActionItem.Builder itemBuilder = SearchActionItem.newBuilder() - .setPackageName(mFallbackPackageName); - - if (!mIsPersonalTitle) { - itemBuilder.setTitle(title.toString()); - } - return getDefaultItemInfoBuilder() - .setSearchActionItem(itemBuilder) - .setContainerInfo(getContainerInfo()) - .build(); - } - - /** - * Returns true if result supports drag/drop to home screen - */ - public boolean supportsPinning() { - return hasFlags(FLAG_ALLOW_PINNING) && getIntentPackageName() != null; - } - - /** - * Creates a {@link WorkspaceItemInfo} coorsponding to search action to be stored in launcher db - */ - @Override - public WorkspaceItemInfo makeWorkspaceItem(Context context) { - WorkspaceItemInfo info = new WorkspaceItemInfo(); - info.title = title; - info.bitmap = bitmap; - info.intent = mIntent; - - if (hasFlags(FLAG_SHOULD_START_FOR_RESULT)) { - info.options |= WorkspaceItemInfo.FLAG_START_FOR_RESULT; - } - LauncherAppState app = LauncherAppState.getInstance(context); - app.getModel().updateAndBindWorkspaceItem(() -> { - PackageItemInfo pkgInfo = new PackageItemInfo(getIntentPackageName(), user); - app.getIconCache().getTitleAndIconForApp(pkgInfo, false); - info.bitmap = info.bitmap.withBadgeInfo(pkgInfo.bitmap); - return info; - }); - return info; - } - - @Nullable - private String getIntentPackageName() { - if (mIntent != null) { - if (mIntent.getPackage() != null) return mIntent.getPackage(); - return mFallbackPackageName; - } - return null; - } -} diff --git a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java index dbab700a87..a2353d8259 100644 --- a/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java +++ b/src/com/android/launcher3/secondarydisplay/SecondaryDisplayLauncher.java @@ -51,6 +51,7 @@ import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.popup.PopupContainerWithArrow; import com.android.launcher3.popup.PopupDataProvider; +import com.android.launcher3.touch.ItemClickHandler.ItemClickProxy; import com.android.launcher3.util.ComponentKey; import com.android.launcher3.util.IntSet; import com.android.launcher3.util.OnboardingPrefs; @@ -332,7 +333,9 @@ public class SecondaryDisplayLauncher extends BaseDraggingActivity if (v.getWindowToken() == null) return; Object tag = v.getTag(); - if (tag instanceof ItemInfo) { + if (tag instanceof ItemClickProxy) { + ((ItemClickProxy) tag).onItemClicked(v); + } else if (tag instanceof ItemInfo) { ItemInfo item = (ItemInfo) tag; Intent intent; if (item instanceof ItemInfoWithIcon diff --git a/src/com/android/launcher3/touch/ItemClickHandler.java b/src/com/android/launcher3/touch/ItemClickHandler.java index 098cf80a3a..b7e01057b9 100644 --- a/src/com/android/launcher3/touch/ItemClickHandler.java +++ b/src/com/android/launcher3/touch/ItemClickHandler.java @@ -17,8 +17,6 @@ package com.android.launcher3.touch; import static com.android.launcher3.Launcher.REQUEST_BIND_PENDING_APPWIDGET; import static com.android.launcher3.Launcher.REQUEST_RECONFIGURE_APPWIDGET; -import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ALLAPPS_SEARCHINAPP_LAUNCH; -import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_APP_LAUNCH_TAP; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_FOLDER_OPEN; import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_BY_PUBLISHER; import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_LOCKED_USER; @@ -27,11 +25,8 @@ import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_SA import static com.android.launcher3.model.data.ItemInfoWithIcon.FLAG_DISABLED_SUSPENDED; import android.app.AlertDialog; -import android.app.PendingIntent; -import android.content.ActivityNotFoundException; import android.content.Context; import android.content.Intent; -import android.content.IntentSender; import android.content.pm.LauncherApps; import android.content.pm.PackageInstaller.SessionInfo; import android.os.Process; @@ -57,7 +52,6 @@ import com.android.launcher3.model.data.FolderInfo; import com.android.launcher3.model.data.ItemInfo; import com.android.launcher3.model.data.ItemInfoWithIcon; import com.android.launcher3.model.data.LauncherAppWidgetInfo; -import com.android.launcher3.model.data.SearchActionItemInfo; import com.android.launcher3.model.data.WorkspaceItemInfo; import com.android.launcher3.pm.InstallSessionHelper; import com.android.launcher3.shortcuts.ShortcutKey; @@ -106,8 +100,8 @@ public class ItemClickHandler { if (v instanceof PendingAppWidgetHostView) { onClickPendingWidget((PendingAppWidgetHostView) v, launcher); } - } else if (tag instanceof SearchActionItemInfo) { - onClickSearchAction(launcher, (SearchActionItemInfo) tag); + } else if (tag instanceof ItemClickProxy) { + ((ItemClickProxy) tag).onItemClicked(v); } } @@ -311,48 +305,6 @@ public class ItemClickHandler { startAppShortcutOrInfoActivity(v, shortcut, launcher); } - /** - * Event handler for a {@link SearchActionItemInfo} click - */ - public static void onClickSearchAction(Launcher launcher, SearchActionItemInfo itemInfo) { - if (itemInfo.getIntent() != null) { - try { - if (itemInfo.hasFlags(SearchActionItemInfo.FLAG_SHOULD_START_FOR_RESULT)) { - launcher.startActivityForResult(itemInfo.getIntent(), 0); - } else { - launcher.startActivity(itemInfo.getIntent()); - } - } catch (ActivityNotFoundException e) { - Toast.makeText(launcher, - launcher.getResources().getText(R.string.shortcut_not_available), - Toast.LENGTH_SHORT).show(); - } - } else if (itemInfo.getPendingIntent() != null) { - try { - PendingIntent pendingIntent = itemInfo.getPendingIntent(); - if (!itemInfo.hasFlags(SearchActionItemInfo.FLAG_SHOULD_START)) { - pendingIntent.send(); - } else if (itemInfo.hasFlags(SearchActionItemInfo.FLAG_SHOULD_START_FOR_RESULT)) { - launcher.startIntentSenderForResult(pendingIntent.getIntentSender(), 0, null, 0, - 0, 0); - } else { - launcher.startIntentSender(pendingIntent.getIntentSender(), null, 0, 0, 0); - } - } catch (PendingIntent.CanceledException | IntentSender.SendIntentException e) { - Toast.makeText(launcher, - launcher.getResources().getText(R.string.shortcut_not_available), - Toast.LENGTH_SHORT).show(); - } - } - if (itemInfo.hasFlags(SearchActionItemInfo.FLAG_SEARCH_IN_APP)) { - launcher.getStatsLogManager().logger().withItemInfo(itemInfo).log( - LAUNCHER_ALLAPPS_SEARCHINAPP_LAUNCH); - } else { - launcher.getStatsLogManager().logger().withItemInfo(itemInfo).log( - LAUNCHER_APP_LAUNCH_TAP); - } - } - private static void startAppShortcutOrInfoActivity(View v, ItemInfo item, Launcher launcher) { TestLogging.recordEvent( TestProtocol.SEQUENCE_MAIN, "start: startAppShortcutOrInfoActivity"); @@ -393,4 +345,15 @@ public class ItemClickHandler { } launcher.startActivitySafely(v, intent, item); } + + /** + * Interface to indicate that an item will handle the click itself. + */ + public interface ItemClickProxy { + + /** + * Called when the item is clicked + */ + void onItemClicked(View view); + } } From 3b1f5849ce8edb67a3f86356a92e552f440d42dd Mon Sep 17 00:00:00 2001 From: Vinit Nayak Date: Mon, 14 Nov 2022 21:10:11 -0800 Subject: [PATCH 304/429] Update for stashed taskbar animation * Strangely if you swipe up with a split pair and then tap on the live tile to go back to fullscreen this animates fairly correctly. However, if you drag the focused pair back to fullscreen the bottom app does not unclip as expected Bug: 219411750 Test: Swipe up w/ stashed taskbar in portrait. Thumbnail cutout doesn't appear when dragging to fullscreen Change-Id: Ia6e7aae10389d9fefa4adbfce540171bbe0a9180 --- .../quickstep/util/TaskViewSimulator.java | 1 + .../quickstep/views/TaskThumbnailView.java | 3 +- .../quickstep/FullscreenDrawParamsTest.kt | 28 +++++++++++++++++++ 3 files changed, 31 insertions(+), 1 deletion(-) diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java index b476c12a51..1515c5b4f8 100644 --- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java +++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java @@ -320,6 +320,7 @@ public class TaskViewSimulator implements TransformParams.BuilderProxy { // mIsRecentsRtl is the inverse of TaskView RTL. boolean isRtlEnabled = !mIsRecentsRtl; + mPositionHelper.setTaskbarInApp(mDp.isTaskbarPresentInApps); mPositionHelper.updateThumbnailMatrix( mThumbnailPosition, mThumbnailData, mTaskRect.width(), mTaskRect.height(), mDp.widthPx, mDp.heightPx, mDp.taskbarSize, mDp.isTablet, diff --git a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java index 904c944c1a..ab1198ab7d 100644 --- a/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java +++ b/quickstep/src/com/android/quickstep/views/TaskThumbnailView.java @@ -464,6 +464,8 @@ public class TaskThumbnailView extends View { } private void updateThumbnailMatrix() { + DeviceProfile dp = mActivity.getDeviceProfile(); + mPreviewPositionHelper.setTaskbarInApp(dp.isTaskbarPresentInApps); mPreviewPositionHelper.setOrientationChanged(false); if (mBitmapShader != null && mThumbnailData != null) { mPreviewRect.set(0, 0, mThumbnailData.thumbnail.getWidth(), @@ -471,7 +473,6 @@ public class TaskThumbnailView extends View { int currentRotation = getTaskView().getRecentsView().getPagedViewOrientedState() .getRecentsActivityRotation(); boolean isRtl = getLayoutDirection() == LAYOUT_DIRECTION_RTL; - DeviceProfile dp = mActivity.getDeviceProfile(); mPreviewPositionHelper.updateThumbnailMatrix(mPreviewRect, mThumbnailData, getMeasuredWidth(), getMeasuredHeight(), dp.widthPx, dp.heightPx, dp.taskbarSize, dp.isTablet, currentRotation, isRtl); diff --git a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt index 0c96539762..7f5881833d 100644 --- a/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt +++ b/quickstep/tests/src/com/android/quickstep/FullscreenDrawParamsTest.kt @@ -21,6 +21,7 @@ import androidx.test.ext.junit.runners.AndroidJUnit4 import androidx.test.filters.SmallTest import com.android.launcher3.DeviceProfileBaseTest import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_BOTTOM_OR_RIGHT +import com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT import com.android.quickstep.views.TaskView.FullscreenDrawParams import com.android.systemui.shared.recents.model.ThumbnailData import com.android.systemui.shared.recents.utilities.PreviewPositionHelper @@ -103,6 +104,33 @@ class FullscreenDrawParamsTest : DeviceProfileBaseTest() { .isWithin(1f).of(expectedBottomHint) } + @Test + fun setFullProgress_currentDrawnInsets_clipTaskbarSizeFromTopForTablets_splitPortrait() { + initializeVarsForTablet() + val dp = newDP() + val previewRect = Rect(0, 0, 100, 100) + val canvasWidth = (dp.widthPx * TASK_SCALE).roundToInt() + val canvasHeight = (dp.heightPx * TASK_SCALE / 2).roundToInt() + val currentRotation = 0 + val isRtl = false + // portrait/vertical split apps + val dividerSize = 10 + val splitBounds = SplitBounds( + Rect(0, 0, dp.widthPx, (dp.heightPx - dividerSize) / 2), + Rect(0, (dp.heightPx + dividerSize) / 2, dp.widthPx, dp.heightPx), + 0 /*lefTopTaskId*/, 0 /*rightBottomTaskId*/) + mPreviewPositionHelper.setSplitBounds(splitBounds, STAGE_POSITION_TOP_OR_LEFT) + + mPreviewPositionHelper.updateThumbnailMatrix(previewRect, mThumbnailData, canvasWidth, + canvasHeight, dp.widthPx, dp.heightPx, dp.taskbarSize, dp.isTablet, currentRotation, + isRtl) + params.setProgress(/* fullscreenProgress= */ 1.0f, /* parentScale= */ 1.0f, + /* taskViewScale= */ 1.0f, /* previewWidth= */ 0, dp, mPreviewPositionHelper) + + assertThat(params.mCurrentDrawnInsets.bottom) + .isWithin(1f).of((0f)) + } + @Test fun setFullProgress_currentDrawnInsets_clipTaskbarSizeFromBottomForTablets_splitLandscape() { initializeVarsForTablet(isLandscape = true) From deac0d529add6b9f4a7bd6cc1387a6698bbaddf1 Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Mon, 28 Nov 2022 20:53:25 +0000 Subject: [PATCH 305/429] Reduce top padding of Taskbar's All Apps tray. The top padding looks too high because the code is assuming we have a search bar at the top of the bottom sheet. Until we implement search, we should temporarily reduce padding for the taskbar implementation. Before: - No tabs: https://screenshot.googleplex.com/AAPdR5nbwepWQ82.png - Tabs: https://screenshot.googleplex.com/3DnQp6PKhqXyRag.png After: - No tabs: https://screenshot.googleplex.com/A8enwnSs8r78ccj.png - Tabs: https://screenshot.googleplex.com/A3fAy2bXgmSPrG9.png Test: Manual Bug: 216683257 Change-Id: Ie0837acc3aed162b9428a209962be2a102c515c8 --- quickstep/res/layout/taskbar_all_apps.xml | 1 - .../allapps/TaskbarAllAppsContainerView.java | 5 +++++ .../allapps/ActivityAllAppsContainerView.java | 21 ++++++++++++++++++- .../allapps/AllAppsRecyclerView.java | 4 +++- 4 files changed, 28 insertions(+), 3 deletions(-) diff --git a/quickstep/res/layout/taskbar_all_apps.xml b/quickstep/res/layout/taskbar_all_apps.xml index a0dce65a45..c7679beb23 100644 --- a/quickstep/res/layout/taskbar_all_apps.xml +++ b/quickstep/res/layout/taskbar_all_apps.xml @@ -48,7 +48,6 @@ android:layout_height="wrap_content" android:layout_below="@id/search_container_all_apps" android:clipToPadding="false" - android:paddingTop="@dimen/all_apps_header_top_padding" android:orientation="vertical"> diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java index e41c75fea0..f8d9d11d39 100644 --- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java +++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsContainerView.java @@ -39,4 +39,9 @@ public class TaskbarAllAppsContainerView extends setInsets(insets.getInsets(WindowInsets.Type.systemBars()).toRect()); return super.onApplyWindowInsets(insets); } + + @Override + protected boolean isSearchSupported() { + return false; + } } diff --git a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java index c86f08d1fb..e4e56a904e 100644 --- a/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java +++ b/src/com/android/launcher3/allapps/ActivityAllAppsContainerView.java @@ -228,7 +228,9 @@ public class ActivityAllAppsContainerView(mActivityContext, getLayoutInflater(), appsList, adapterProviders); } + + // TODO(b/216683257): Remove when Taskbar All Apps supports search. + protected boolean isSearchSupported() { + return true; + } + + private void layoutWithoutSearchContainer(View v, boolean includeTabsMargin) { + if (!(v.getLayoutParams() instanceof RelativeLayout.LayoutParams)) { + return; + } + + RelativeLayout.LayoutParams layoutParams = (LayoutParams) v.getLayoutParams(); + layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP); + layoutParams.topMargin = getContext().getResources().getDimensionPixelSize(includeTabsMargin + ? R.dimen.all_apps_header_pill_height + : R.dimen.all_apps_header_top_margin); + } } diff --git a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java index ac10892ece..d308fcb3b8 100644 --- a/src/com/android/launcher3/allapps/AllAppsRecyclerView.java +++ b/src/com/android/launcher3/allapps/AllAppsRecyclerView.java @@ -258,7 +258,9 @@ public class AllAppsRecyclerView extends FastScrollRecyclerView { } public int getScrollBarTop() { - return getResources().getDimensionPixelOffset(R.dimen.all_apps_header_top_padding); + return ActivityContext.lookupContext(getContext()).getAppsView().isSearchSupported() + ? getResources().getDimensionPixelOffset(R.dimen.all_apps_header_top_padding) + : 0; } public RecyclerViewFastScroller getScrollbar() { From cd76ac24b682575410a07a26939ea22a8dd904b7 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Tue, 8 Nov 2022 15:43:29 +0000 Subject: [PATCH 306/429] Fade in/out taskbar when launching apps from or back to AllApps/-1 - Added isHotseatIconTopWhenAligned to control both iconAlignment and stash animation to just fade in if hotseat icon isn't on top of the screen in the aligned state Fix: 257355864 Fix: 213455090 Test: Launch apps from/back to home, taskbar animate from/to hotseat Test: Launch apps from/back to AllApps/-1, taskbar fade in/out Test: Repeat aboth with transient or persistent taskbar Change-Id: I6bdae615ff9e199d23cbfe2d26c8d46a08fbc436 --- .../launcher3/QuickstepTransitionManager.java | 4 + .../taskbar/LauncherTaskbarUIController.java | 6 ++ .../TaskbarLauncherStateController.java | 15 +++- .../taskbar/TaskbarStashController.java | 27 +++++- .../taskbar/TaskbarUIController.java | 7 ++ .../taskbar/TaskbarViewController.java | 88 ++++++++++++------- 6 files changed, 110 insertions(+), 37 deletions(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 59dbd4b9e5..2aa0af4113 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -482,6 +482,10 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener final View appsView = mLauncher.getAppsView(); final float startAlpha = appsView.getAlpha(); final float startScale = SCALE_PROPERTY.get(appsView); + if (mDeviceProfile.isTablet) { + // AllApps should not fade at all in tablets. + alphas = new float[]{1, 1}; + } appsView.setAlpha(alphas[0]); ObjectAnimator alpha = ObjectAnimator.ofFloat(appsView, View.ALPHA, alphas); diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index 87753594fe..02206cea74 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -355,6 +355,12 @@ public class LauncherTaskbarUIController extends TaskbarUIController { return mTaskbarLauncherStateController.isIconAlignedWithHotseat(); } + @Override + public boolean isHotseatIconOnTopWhenAligned() { + return mTaskbarLauncherStateController.isInHotseatOnTopStates() + && getInAppDisplayProgress(MINUS_ONE_PAGE_PROGRESS_INDEX) == 0; + } + @Override public void dumpLogs(String prefix, PrintWriter pw) { super.dumpLogs(prefix, pw); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index d790b4b663..b74dd21d03 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -385,6 +385,13 @@ import java.util.StringJoiner; } } + /** + * Returns if the current Launcher state has hotseat on top of other elemnets. + */ + public boolean isInHotseatOnTopStates() { + return mLauncherState != LauncherState.ALL_APPS; + } + private void playStateTransitionAnim(AnimatorSet animatorSet, long duration, boolean committed) { boolean isInStashedState = mLauncherState.isTaskbarStashed(mLauncher); @@ -438,14 +445,16 @@ import java.util.StringJoiner; private void updateIconAlphaForHome(float alpha) { mIconAlphaForHome.setValue(alpha); - + boolean hotseatVisible = alpha == 0 + || (!mControllers.uiController.isHotseatIconOnTopWhenAligned() + && mIconAlignment.value > 0); /* * Hide Launcher Hotseat icons when Taskbar icons have opacity. Both icon sets * should not be visible at the same time. */ - mLauncher.getHotseat().setIconsAlpha(alpha > 0 ? 0 : 1); + mLauncher.getHotseat().setIconsAlpha(hotseatVisible ? 1 : 0); mLauncher.getHotseat().setQsbAlpha( - mLauncher.getDeviceProfile().isQsbInline && alpha > 0 ? 0 : 1); + mLauncher.getDeviceProfile().isQsbInline && !hotseatVisible ? 0 : 1); } private final class TaskBarRecentsAnimationListener implements diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index e62e533fc1..a7e45d1623 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -17,6 +17,8 @@ package com.android.launcher3.taskbar; import static android.view.HapticFeedbackConstants.LONG_PRESS; +import static com.android.launcher3.anim.Interpolators.FINAL_FRAME; +import static com.android.launcher3.anim.Interpolators.INSTANT; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_HIDE; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_LONGPRESS_SHOW; import static com.android.launcher3.taskbar.Utilities.appendFlag; @@ -535,6 +537,8 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba final float firstHalfDurationScale; final float secondHalfDurationScale; + boolean isHotseatIconOnTopWhenAligned = + mControllers.uiController.isHotseatIconOnTopWhenAligned(); if (isStashed) { firstHalfDurationScale = 0.75f; secondHalfDurationScale = 0.5f; @@ -555,6 +559,12 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba secondHalfAnimatorSet.playTogether( mTaskbarStashedHandleAlpha.animateToValue(1) ); + + // If Hotseat is not the top element, an already stashed Taskbar should fade in. + if (!isHotseatIconOnTopWhenAligned) { + fullLengthAnimatorSet.setInterpolator(INSTANT); + firstHalfAnimatorSet.setInterpolator(INSTANT); + } } else { firstHalfDurationScale = 0.5f; secondHalfDurationScale = 0.75f; @@ -575,6 +585,13 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba secondHalfAnimatorSet.playTogether( mIconAlphaForStash.animateToValue(1) ); + + // If Hotseat is not the top element, the stashed Taskbar should fade out without + // unstashing. + if (!isHotseatIconOnTopWhenAligned) { + fullLengthAnimatorSet.setInterpolator(FINAL_FRAME); + secondHalfAnimatorSet.setInterpolator(FINAL_FRAME); + } } fullLengthAnimatorSet.play(mControllers.stashedHandleViewController @@ -916,6 +933,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba private final IntPredicate mStashCondition; private boolean mIsStashed; + private boolean mIsHotseatIconOnTopWhenAligned; private int mPrevFlags; StatePropertyHolder(IntPredicate stashCondition) { @@ -945,7 +963,13 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba mPrevFlags = flags; } boolean isStashed = mStashCondition.test(flags); - if (mIsStashed != isStashed) { + boolean isHotseatIconOnTopWhenAligned = + mControllers.uiController.isHotseatIconOnTopWhenAligned(); + // If an animation has started and mIsHotseatIconOnTopWhenAligned is changed, we need + // to restart the animation with new parameters. + if (mIsStashed != isStashed + || (mIsHotseatIconOnTopWhenAligned != isHotseatIconOnTopWhenAligned + && mAnimator != null && mAnimator.isStarted())) { if (TestProtocol.sDebugTracing) { Log.d(TestProtocol.TASKBAR_IN_APP_STATE, String.format( "setState: mIsStashed=%b, isStashed=%b, duration=%d, start=:%b", @@ -955,6 +979,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba start)); } mIsStashed = isStashed; + mIsHotseatIconOnTopWhenAligned = isHotseatIconOnTopWhenAligned; // This sets mAnimator. createAnimToIsStashed(mIsStashed, duration, startDelay, /* animateBg= */ true); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java index 6c6b002959..a059295bfc 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java @@ -128,6 +128,13 @@ public class TaskbarUIController { return false; } + /** + * Returns true if hotseat icons are on top of view hierarchy when aligned in the current state. + */ + public boolean isHotseatIconOnTopWhenAligned() { + return true; + } + @CallSuper protected void dumpLogs(String prefix, PrintWriter pw) { pw.println(String.format( diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index b5e6fac5bb..d14eeab295 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -19,6 +19,7 @@ import static com.android.launcher3.LauncherAnimUtils.SCALE_PROPERTY; import static com.android.launcher3.LauncherAnimUtils.VIEW_ALPHA; import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_Y; import static com.android.launcher3.Utilities.squaredHypot; +import static com.android.launcher3.anim.Interpolators.FINAL_FRAME; import static com.android.launcher3.anim.Interpolators.LINEAR; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP; import static com.android.launcher3.taskbar.TaskbarManager.isPhoneMode; @@ -32,6 +33,7 @@ import android.util.FloatProperty; import android.util.Log; import android.view.MotionEvent; import android.view.View; +import android.view.animation.Interpolator; import androidx.annotation.Nullable; import androidx.core.graphics.ColorUtils; @@ -112,6 +114,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar private Runnable mOnControllerPreCreateCallback = NO_OP; private int mThemeIconsColor; + private boolean mIsHotseatIconOnTopWhenAligned; private final DeviceProfile.OnDeviceProfileChangeListener mDeviceProfileChangeListener = dp -> commitRunningAppsToUI(); @@ -293,7 +296,12 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar * 1 => fully aligned */ public void setLauncherIconAlignment(float alignmentRatio, DeviceProfile launcherDp) { - if (mIconAlignControllerLazy == null) { + boolean isHotseatIconOnTopWhenAligned = + mControllers.uiController.isHotseatIconOnTopWhenAligned(); + // When mIsHotseatIconOnTopWhenAligned changes, animation needs to be re-created. + if (mIconAlignControllerLazy == null + || mIsHotseatIconOnTopWhenAligned != isHotseatIconOnTopWhenAligned) { + mIsHotseatIconOnTopWhenAligned = isHotseatIconOnTopWhenAligned; mIconAlignControllerLazy = createIconAlignmentController(launcherDp); } mIconAlignControllerLazy.setPlayFraction(alignmentRatio); @@ -318,10 +326,15 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar borderSpacing, launcherDp.numShownHotseatIcons); + boolean isToHome = mControllers.uiController.isIconAlignedWithHotseat(); + // If Hotseat is not the top element, Taskbar should maintain in-app state as it fades out, + // or fade in while already in in-app state. + Interpolator interpolator = mIsHotseatIconOnTopWhenAligned ? LINEAR : FINAL_FRAME; + int offsetY = launcherDp.getTaskbarOffsetY(); - setter.setFloat(mTaskbarIconTranslationYForHome, VALUE, -offsetY, LINEAR); - setter.setFloat(mTaskbarNavButtonTranslationY, VALUE, -offsetY, LINEAR); - setter.setFloat(mTaskbarNavButtonTranslationYForInAppDisplay, VALUE, offsetY, LINEAR); + setter.setFloat(mTaskbarIconTranslationYForHome, VALUE, -offsetY, interpolator); + setter.setFloat(mTaskbarNavButtonTranslationY, VALUE, -offsetY, interpolator); + setter.setFloat(mTaskbarNavButtonTranslationYForInAppDisplay, VALUE, offsetY, interpolator); if (Utilities.isDarkTheme(mTaskbarView.getContext())) { setter.addFloat(mThemeIconsBackground, VALUE, 0f, 1f, LINEAR); @@ -332,27 +345,24 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar setter.addOnFrameListener(anim -> mActivity.setTaskbarWindowHeight( anim.getAnimatedFraction() > 0 ? expandedHeight : collapsedHeight)); - boolean isToHome = mControllers.uiController.isIconAlignedWithHotseat(); for (int i = 0; i < mTaskbarView.getChildCount(); i++) { View child = mTaskbarView.getChildAt(i); int positionInHotseat; - if (FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get() - && child == mTaskbarView.getAllAppsButtonView()) { - // Note that there is no All Apps button in the hotseat, this position is only used - // as its convenient for animation purposes. - positionInHotseat = Utilities.isRtl(child.getResources()) - ? -1 - : taskbarDp.numShownHotseatIcons; + boolean isAllAppsButton = FeatureFlags.ENABLE_ALL_APPS_IN_TASKBAR.get() + && child == mTaskbarView.getAllAppsButtonView(); + if (!mIsHotseatIconOnTopWhenAligned) { + // When going to home, the EMPHASIZED interpolator in TaskbarLauncherStateController + // plays iconAlignment to 1 really fast, therefore moving the fading towards the end + // to avoid icons disappearing rather than fading out visually. + setter.setViewAlpha(child, 0, Interpolators.clampToProgress(LINEAR, 0.8f, 1f)); + } else if ((isAllAppsButton && !FeatureFlags.ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT.get())) { + setter.setViewAlpha(child, 0, + isToHome + ? Interpolators.clampToProgress(LINEAR, 0f, 0.17f) + : Interpolators.clampToProgress(LINEAR, 0.72f, 0.84f)); + } - if (!FeatureFlags.ENABLE_ALL_APPS_BUTTON_IN_HOTSEAT.get()) { - setter.setViewAlpha(child, 0, - isToHome - ? Interpolators.clampToProgress(LINEAR, 0f, 0.17f) - : Interpolators.clampToProgress(LINEAR, 0.72f, 0.84f)); - } - } else if (child.getTag() instanceof ItemInfo) { - positionInHotseat = ((ItemInfo) child.getTag()).screenId; - } else if (child == mTaskbarView.getQsb()) { + if (child == mTaskbarView.getQsb()) { boolean isRtl = Utilities.isRtl(child.getResources()); float hotseatIconCenter = isRtl ? launcherDp.widthPx - hotseatPadding.right + borderSpacing @@ -363,26 +373,38 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar (launcherDp.hotseatQsbWidth - taskbarDp.iconSizePx) / 2f; setter.addFloat(child, ICON_TRANSLATE_X, isRtl ? -halfQsbIconWidthDiff : halfQsbIconWidthDiff, - hotseatIconCenter - childCenter, LINEAR); + hotseatIconCenter - childCenter, interpolator); float scale = ((float) taskbarDp.iconSizePx) / launcherDp.hotseatQsbVisualHeight; - setter.addFloat(child, SCALE_PROPERTY, scale, 1f, LINEAR); + setter.addFloat(child, SCALE_PROPERTY, scale, 1f, interpolator); - setter.setFloat(child, VIEW_TRANSLATE_Y, mTaskbarBottomMargin, LINEAR); + setter.setFloat(child, VIEW_TRANSLATE_Y, mTaskbarBottomMargin, interpolator); - setter.addFloat(child, VIEW_ALPHA, 0f, 1f, - isToHome - ? Interpolators.clampToProgress(LINEAR, 0f, 0.35f) - : Interpolators.clampToProgress(LINEAR, 0.84f, 1f)); + if (mIsHotseatIconOnTopWhenAligned) { + setter.addFloat(child, VIEW_ALPHA, 0f, 1f, + isToHome + ? Interpolators.clampToProgress(LINEAR, 0f, 0.35f) + : Interpolators.clampToProgress(LINEAR, 0.84f, 1f)); + } setter.addOnFrameListener(animator -> AlphaUpdateListener.updateVisibility(child)); float qsbInsetFraction = halfQsbIconWidthDiff / launcherDp.hotseatQsbWidth; - if (child instanceof HorizontalInsettableView) { + if (child instanceof HorizontalInsettableView) { setter.addFloat((HorizontalInsettableView) child, HorizontalInsettableView.HORIZONTAL_INSETS, qsbInsetFraction, 0, - LINEAR); + interpolator); } continue; + } + + if (isAllAppsButton) { + // Note that there is no All Apps button in the hotseat, this position is only used + // as its convenient for animation purposes. + positionInHotseat = Utilities.isRtl(child.getResources()) + ? -1 + : taskbarDp.numShownHotseatIcons; + } else if (child.getTag() instanceof ItemInfo) { + positionInHotseat = ((ItemInfo) child.getTag()).screenId; } else { Log.w(TAG, "Unsupported view found in createIconAlignmentController, v=" + child); continue; @@ -393,11 +415,11 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar + hotseatCellSize / 2f; float childCenter = (child.getLeft() + child.getRight()) / 2f; - setter.setFloat(child, ICON_TRANSLATE_X, hotseatIconCenter - childCenter, LINEAR); + setter.setFloat(child, ICON_TRANSLATE_X, hotseatIconCenter - childCenter, interpolator); - setter.setFloat(child, VIEW_TRANSLATE_Y, mTaskbarBottomMargin, LINEAR); + setter.setFloat(child, VIEW_TRANSLATE_Y, mTaskbarBottomMargin, interpolator); - setter.setFloat(child, SCALE_PROPERTY, scaleUp, LINEAR); + setter.setFloat(child, SCALE_PROPERTY, scaleUp, interpolator); } AnimatorPlaybackController controller = setter.createPlaybackController(); From 8121e0d8b1d861bea3de068fba28931e9ccd2fab Mon Sep 17 00:00:00 2001 From: Ats Jenk Date: Thu, 1 Dec 2022 11:34:43 -0800 Subject: [PATCH 307/429] Add a flag to not disable back gesture in launcher Desktop mode prototypes enable freeform tasks on top of launcher. Launcher is still partially visible in the back which means that launcher will disable back gesture for the freeform tasks. When desktop mode prototype 1 or 2 is enabled, skip disabling the back gesture on launcher. Bug: 259280363 Test: manual, enable desktop mode and launch an app, try back gesture from edge Change-Id: I1d5eb81c7b28fb452c9566e358d77a5b2c19d450 --- src/com/android/launcher3/Launcher.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index 5cce407d0b..1a6c68dd6a 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -313,6 +313,12 @@ public class Launcher extends StatefulActivity private static final FloatProperty HOTSEAT_WIDGET_SCALE = HOTSEAT_SCALE_PROPERTY_FACTORY.get(SCALE_INDEX_WIDGET_TRANSITION); + private static final boolean DESKTOP_MODE_1_SUPPORTED = + "1".equals(Utilities.getSystemProperty("persist.wm.debug.desktop_mode", "0")); + + private static final boolean DESKTOP_MODE_2_SUPPORTED = + "1".equals(Utilities.getSystemProperty("persist.wm.debug.desktop_mode_2", "0")); + @Thunk Workspace mWorkspace; @Thunk @@ -3154,6 +3160,10 @@ public class Launcher extends StatefulActivity } private void updateDisallowBack() { + if (DESKTOP_MODE_1_SUPPORTED || DESKTOP_MODE_2_SUPPORTED) { + // Do not disable back in launcher when prototype behavior is enabled + return; + } LauncherRootView rv = getRootView(); if (rv != null) { boolean disableBack = getStateManager().getState() == NORMAL From 8820a2181b9368c8446856c4f968d75c91c041dd Mon Sep 17 00:00:00 2001 From: Sihua Ma Date: Tue, 29 Nov 2022 14:50:53 -0800 Subject: [PATCH 308/429] Replace title of system services with more specific ones Before: https://screenshot.googleplex.com/8f5tGuw8c8zi6nX Now: https://screenshot.googleplex.com/4SXGMoiZmYJ3auF Fix: 258307358 Test: Manual Change-Id: I549cbdbb99f0168c87cc1c122cad9aceb3231591 --- .../launcher3/dragndrop/AddItemActivity.java | 29 ++++++++++++------- 1 file changed, 19 insertions(+), 10 deletions(-) diff --git a/src/com/android/launcher3/dragndrop/AddItemActivity.java b/src/com/android/launcher3/dragndrop/AddItemActivity.java index 5a49f4ad41..a610548560 100644 --- a/src/com/android/launcher3/dragndrop/AddItemActivity.java +++ b/src/com/android/launcher3/dragndrop/AddItemActivity.java @@ -23,6 +23,7 @@ import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCH import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ADD_EXTERNAL_ITEM_PLACED_AUTOMATICALLY; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_ADD_EXTERNAL_ITEM_START; import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; +import static com.android.launcher3.widget.WidgetSections.NO_CATEGORY; import android.annotation.TargetApi; import android.app.ActivityOptions; @@ -63,10 +64,11 @@ import com.android.launcher3.R; import com.android.launcher3.logging.StatsLogManager; import com.android.launcher3.model.ItemInstallQueue; import com.android.launcher3.model.WidgetItem; +import com.android.launcher3.model.WidgetsModel; import com.android.launcher3.model.data.ItemInfo; +import com.android.launcher3.model.data.PackageItemInfo; import com.android.launcher3.pm.PinRequestHelper; import com.android.launcher3.util.PackageManagerHelper; -import com.android.launcher3.util.PackageUserKey; import com.android.launcher3.util.SystemUiController; import com.android.launcher3.views.AbstractSlideInView; import com.android.launcher3.views.BaseDragLayer; @@ -80,6 +82,7 @@ import com.android.launcher3.widget.WidgetCell; import com.android.launcher3.widget.WidgetCellPreview; import com.android.launcher3.widget.WidgetImageView; import com.android.launcher3.widget.WidgetManagerHelper; +import com.android.launcher3.widget.WidgetSections; import java.util.function.Supplier; @@ -142,7 +145,7 @@ public class AddItemActivity extends BaseActivity mAccessibilityManager = getApplicationContext().getSystemService(AccessibilityManager.class); - PackageUserKey targetApp = null; + final PackageItemInfo targetApp; switch (mRequest.getRequestType()) { case PinItemRequest.REQUEST_TYPE_SHORTCUT: targetApp = setupShortcut(); @@ -150,6 +153,9 @@ public class AddItemActivity extends BaseActivity case PinItemRequest.REQUEST_TYPE_APPWIDGET: targetApp = setupWidget(); break; + default: + targetApp = null; + break; } if (targetApp == null) { // TODO: show error toast? @@ -157,7 +163,7 @@ public class AddItemActivity extends BaseActivity return; } ApplicationInfo info = new PackageManagerHelper(this) - .getApplicationInfo(targetApp.mPackageName, targetApp.mUser, 0); + .getApplicationInfo(targetApp.packageName, targetApp.user, 0); if (info == null) { finish(); return; @@ -177,7 +183,10 @@ public class AddItemActivity extends BaseActivity // Set the label synchronously instead of via IconCache as this is the first thing // user sees TextView widgetAppName = findViewById(R.id.widget_appName); - widgetAppName.setText(info.loadLabel(getPackageManager())); + WidgetSections.WidgetSection section = targetApp.widgetCategory == NO_CATEGORY ? null + : WidgetSections.getWidgetSections(this).get(targetApp.widgetCategory); + widgetAppName.setText(section == null ? info.loadLabel(getPackageManager()) + : getString(section.mSectionTitle)); mSlideInView = findViewById(R.id.add_item_bottom_sheet); mSlideInView.addOnCloseListener(this); @@ -266,19 +275,18 @@ public class AddItemActivity extends BaseActivity } } - private PackageUserKey setupShortcut() { + private PackageItemInfo setupShortcut() { PinShortcutRequestActivityInfo shortcutInfo = new PinShortcutRequestActivityInfo(mRequest, this); mWidgetCell.getWidgetView().setTag(new PendingAddShortcutInfo(shortcutInfo)); applyWidgetItemAsync( () -> new WidgetItem(shortcutInfo, mApp.getIconCache(), getPackageManager())); - return new PackageUserKey( - mRequest.getShortcutInfo().getPackage(), + return new PackageItemInfo(mRequest.getShortcutInfo().getPackage(), mRequest.getShortcutInfo().getUserHandle()); } - private PackageUserKey setupWidget() { - LauncherAppWidgetProviderInfo widgetInfo = LauncherAppWidgetProviderInfo + private PackageItemInfo setupWidget() { + final LauncherAppWidgetProviderInfo widgetInfo = LauncherAppWidgetProviderInfo .fromProviderInfo(this, mRequest.getAppWidgetProviderInfo(this)); if (widgetInfo.minSpanX > mIdp.numColumns || widgetInfo.minSpanY > mIdp.numRows) { // Cannot add widget @@ -297,7 +305,8 @@ public class AddItemActivity extends BaseActivity mWidgetCell.getWidgetView().setTag(pendingInfo); applyWidgetItemAsync(() -> new WidgetItem(widgetInfo, mIdp, mApp.getIconCache())); - return new PackageUserKey(widgetInfo.provider.getPackageName(), widgetInfo.getUser()); + return WidgetsModel.newPendingItemInfo(this, widgetInfo.getComponent(), + widgetInfo.getUser()); } private void applyWidgetItemAsync(final Supplier itemProvider) { From 030f2fc7b75461aee64df3eed174a622d479dd32 Mon Sep 17 00:00:00 2001 From: Saumya Prakash Date: Thu, 1 Dec 2022 22:45:47 +0000 Subject: [PATCH 309/429] Updated fonts to Google Sans in Setup screens. This change migrates the "All set" and Gesture Nav Tutorial screens to use Google Sans fonts as aligned with SUW's design. Before: "All set" screen: https://screenshot.googleplex.com/7ptWroSfRiZLcRT.png Gesture Nav Tutorial screen: https://screenshot.googleplex.com/6SuYs67NSD2WRkU.png After: "All set" screen: https://screenshot.googleplex.com/6UGrdR43h8aDJzU.png Gesture Nav Tutorial screen: https://screenshot.googleplex.com/45NxPH2ezQsHxL4.png Fix: 258241930 Test: Manual Change-Id: I21cc19383f78e3d9e84b0d892cbd977f20b91e86 --- quickstep/res/values/styles.xml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml index 4f0fdf182d..eb75084697 100644 --- a/quickstep/res/values/styles.xml +++ b/quickstep/res/values/styles.xml @@ -41,7 +41,7 @@ parent="TextAppearance.GestureTutorial"> start ?android:attr/textColorPrimary - google-sans-regular + google-sans 0.03 36sp 44sp @@ -106,6 +106,7 @@ 0.02 16sp false + google-sans-text-medium - + - + - - - -