From 88972311a2d0c337c90815cb4de52a107a125c80 Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Fri, 8 Mar 2024 03:42:02 +0000 Subject: [PATCH 01/14] Consolidate settings for Assist. Now there is just 1 toggle for all entrypoints. Bug: 324036308 Test: Manual and unit tests Flag: NA Change-Id: Id4463345c44fa4daba4eac67b5ad00aff7f3a606 Merged-In: Id4463345c44fa4daba4eac67b5ad00aff7f3a606 --- .../src/com/android/quickstep/util/AssistStateManager.java | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/quickstep/src/com/android/quickstep/util/AssistStateManager.java b/quickstep/src/com/android/quickstep/util/AssistStateManager.java index f7437eb075..96731a2fa8 100644 --- a/quickstep/src/com/android/quickstep/util/AssistStateManager.java +++ b/quickstep/src/com/android/quickstep/util/AssistStateManager.java @@ -57,12 +57,7 @@ public class AssistStateManager implements ResourceBasedOverride { } /** Return {@code true} if the Settings toggle is enabled. */ - public boolean isSettingsNavHandleEnabled() { - return false; - } - - /** Return {@code true} if the Settings toggle is enabled. */ - public boolean isSettingsHomeButtonEnabled() { + public boolean isSettingsAllEntrypointsEnabled() { return false; } From a5d55fe5efad4db1678dfe7960f82df68b664b7d Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Fri, 22 Mar 2024 22:13:08 +0000 Subject: [PATCH 02/14] Revert "Log split button visibility to debug spacing issue" This reverts commit 2d55c9c6796788b40ac9381b5cdb5347f6c3f6d3. Reason for revert: Logs not helpful in figuring out the issue and is too spammy Bug: 321291049 Change-Id: I88a4350277ea3e965493da6386cf4c83c5c564e4 --- .../quickstep/views/OverviewActionsView.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java index e0091a5ae2..b03b89f0b3 100644 --- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java +++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java @@ -20,7 +20,6 @@ import android.content.Context; import android.content.res.Configuration; import android.graphics.Rect; import android.util.AttributeSet; -import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; @@ -43,8 +42,6 @@ import com.android.quickstep.util.LayoutUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.Arrays; -import java.util.stream.Collectors; /** * View for showing action buttons in Overview @@ -297,17 +294,6 @@ public class OverviewActionsView extends FrameLayo int desiredVisibility = mSplitButtonHiddenFlags == 0 ? VISIBLE : GONE; mSplitButton.setVisibility(desiredVisibility); findViewById(R.id.action_split_space).setVisibility(desiredVisibility); - - String callStack = Arrays.stream( - Log.getStackTraceString(new Exception("thread stacktrace")) - .split("\\n")) - .limit(5) - .skip(1) // Removes the line "java.lang.Exception: thread stacktrace" - .collect(Collectors.joining("\n")); - Log.d("b/321291049", "updateSplitButtonHiddenFlags called with flag: " + flag - + " enabled: " + enable - + " visibility: " + desiredVisibility - + " partial trace: \n" + callStack); } /** From b02811f1d3a35326ccf2662410189a6c2ffc35e4 Mon Sep 17 00:00:00 2001 From: Brian Isganitis Date: Mon, 25 Mar 2024 22:37:26 -0400 Subject: [PATCH 03/14] Force refresh AllAppsActionManager for tests. Flag: NONE Test: Manual Fix: 330514236 Change-Id: I32990fe115c79963f9635eabacccd89e2815f098 --- quickstep/src/com/android/quickstep/AllAppsActionManager.kt | 1 + .../src/com/android/quickstep/TouchInteractionService.java | 6 ++++-- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/quickstep/src/com/android/quickstep/AllAppsActionManager.kt b/quickstep/src/com/android/quickstep/AllAppsActionManager.kt index fd2ed3ac18..6fd68d551e 100644 --- a/quickstep/src/com/android/quickstep/AllAppsActionManager.kt +++ b/quickstep/src/com/android/quickstep/AllAppsActionManager.kt @@ -81,6 +81,7 @@ class AllAppsActionManager( } fun onDestroy() { + isActionRegistered = false context .getSystemService(AccessibilityManager::class.java) ?.unregisterSystemAction( diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index b43c5201ce..af0d2094e2 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -442,8 +442,10 @@ public class TouchInteractionService extends Service { /** Refreshes the current overview target. */ public void refreshOverviewTarget() { - executeForTouchInteractionService(tis -> tis.onOverviewTargetChange( - tis.mOverviewComponentObserver.isHomeAndOverviewSame())); + executeForTouchInteractionService(tis -> { + tis.mAllAppsActionManager.onDestroy(); + tis.onOverviewTargetChange(tis.mOverviewComponentObserver.isHomeAndOverviewSame()); + }); } } From 8fe1d9c8ae2962f9bcf74cba559e11a5770eb22e Mon Sep 17 00:00:00 2001 From: Luca Zuccarini Date: Fri, 15 Mar 2024 13:13:52 +0000 Subject: [PATCH 04/14] Move interfaces to the shared library. Bug: 323863002 Flag: NA Test: NA, just a move Change-Id: I8390bdbc226f53da2cbdf2c4321a67e7b7223bec --- .../src/com/android/launcher3/HomeTransitionController.java | 2 +- quickstep/src/com/android/quickstep/SystemUiProxy.java | 4 ++-- .../src/com/android/quickstep/TouchInteractionService.java | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/quickstep/src/com/android/launcher3/HomeTransitionController.java b/quickstep/src/com/android/launcher3/HomeTransitionController.java index 2b50283acd..c4a2e9e17e 100644 --- a/quickstep/src/com/android/launcher3/HomeTransitionController.java +++ b/quickstep/src/com/android/launcher3/HomeTransitionController.java @@ -21,7 +21,7 @@ import androidx.annotation.Nullable; import com.android.launcher3.uioverrides.QuickstepLauncher; import com.android.quickstep.SystemUiProxy; -import com.android.wm.shell.transition.IHomeTransitionListener; +import com.android.wm.shell.shared.IHomeTransitionListener; /** * Controls launcher response to home activity visibility changing. diff --git a/quickstep/src/com/android/quickstep/SystemUiProxy.java b/quickstep/src/com/android/quickstep/SystemUiProxy.java index 72f67fc544..b6272dad87 100644 --- a/quickstep/src/com/android/quickstep/SystemUiProxy.java +++ b/quickstep/src/com/android/quickstep/SystemUiProxy.java @@ -91,13 +91,13 @@ import com.android.wm.shell.draganddrop.IDragAndDrop; import com.android.wm.shell.onehanded.IOneHanded; import com.android.wm.shell.recents.IRecentTasks; import com.android.wm.shell.recents.IRecentTasksListener; +import com.android.wm.shell.shared.IHomeTransitionListener; +import com.android.wm.shell.shared.IShellTransitions; import com.android.wm.shell.splitscreen.ISplitScreen; import com.android.wm.shell.splitscreen.ISplitScreenListener; import com.android.wm.shell.splitscreen.ISplitSelectListener; import com.android.wm.shell.startingsurface.IStartingWindow; import com.android.wm.shell.startingsurface.IStartingWindowListener; -import com.android.wm.shell.transition.IHomeTransitionListener; -import com.android.wm.shell.transition.IShellTransitions; import com.android.wm.shell.util.GroupedRecentTaskInfo; import java.io.PrintWriter; diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index b43c5201ce..e931d874b1 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -135,9 +135,9 @@ import com.android.wm.shell.desktopmode.IDesktopMode; import com.android.wm.shell.draganddrop.IDragAndDrop; import com.android.wm.shell.onehanded.IOneHanded; import com.android.wm.shell.recents.IRecentTasks; +import com.android.wm.shell.shared.IShellTransitions; import com.android.wm.shell.splitscreen.ISplitScreen; import com.android.wm.shell.startingsurface.IStartingWindow; -import com.android.wm.shell.transition.IShellTransitions; import java.io.FileDescriptor; import java.io.PrintWriter; From 6867b18db207958f5b08d53819f76d6bdf70caa7 Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Tue, 26 Mar 2024 21:44:02 -0700 Subject: [PATCH 05/14] Fix bug with long strings not aligning left on menu items This CL sets gravity="start" and ellipsize="end" so that longer strings in the Overview app dropdown menu are still left-aligned and ellipsized when they are longer than the container. Fixes: 330426535 Flag: N/A Test: Manual Change-Id: I1e62412c9b8be41a8dbb6b0597a69a283a56e3f0 --- quickstep/res/layout/task_view_menu_option.xml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/quickstep/res/layout/task_view_menu_option.xml b/quickstep/res/layout/task_view_menu_option.xml index 30ab4b102e..ffe240180e 100644 --- a/quickstep/res/layout/task_view_menu_option.xml +++ b/quickstep/res/layout/task_view_menu_option.xml @@ -41,6 +41,8 @@ android:layout_marginStart="@dimen/task_menu_option_text_start_margin" android:textSize="14sp" android:textColor="?androidprv:attr/materialColorOnSurface" - android:focusable="false" /> + android:focusable="false" + android:gravity="start" + android:ellipsize="end" /> From 6e9927e61f47056103820ab2641175712279fb7c Mon Sep 17 00:00:00 2001 From: Uwais Ashraf Date: Mon, 25 Mar 2024 10:53:06 +0000 Subject: [PATCH 06/14] Add test and android lifecycle coroutine libs Fix: 330128421 Bug: 330127493 Test: Presubmit build passes Flag: NA Change-Id: I87cf3b5faaee6bcdb99c5afbe1999a11d031d98e --- Android.bp | 5 +++++ tests/Android.bp | 1 + 2 files changed, 6 insertions(+) diff --git a/Android.bp b/Android.bp index 79c1b9fc6d..877f7bbbef 100644 --- a/Android.bp +++ b/Android.bp @@ -155,6 +155,11 @@ android_library { "animationlib", "SystemUI-statsd", "launcher-testing-shared", + "androidx.lifecycle_lifecycle-common-java8", + "androidx.lifecycle_lifecycle-extensions", + "androidx.lifecycle_lifecycle-runtime-ktx", + "kotlinx_coroutines_android", + "kotlinx_coroutines", "com_android_launcher3_flags_lib", "com_android_wm_shell_flags_lib", "android.appwidget.flags-aconfig-java", diff --git a/tests/Android.bp b/tests/Android.bp index c1d41802cc..13a1cbb2ae 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -86,6 +86,7 @@ android_library { "mockito-target-extended-minus-junit4", "launcher_log_protos_lite", "truth", + "kotlinx_coroutines_test", "platform-test-rules", "testables", "com_android_launcher3_flags_lib", From 6431d6e87910bc7c7767c40d42f51961dc462134 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Wed, 27 Mar 2024 16:05:50 +0000 Subject: [PATCH 07/14] Align action_buttons at bottom of OverviewActionsView - http://ag/q/topic:%22b/329255757%22 caused a regression that in landscape, action_buttons shifted up when ShareTarget become visible, because OverviewActionsView become taller when this happens, and the topMargin is no longer valid to put actions_button at the position we want - Bring back layout_gravity="bottom" solves the issue, as bottomMarign is always correct Fix: 331517987 Test: manual as ShareTarget requires AiAi interaction and cannot easily be mocked Flag: None Change-Id: Iadcdf5731485f42f9586703e34e55ed9b4121bf9 --- quickstep/res/layout/overview_actions_container.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/quickstep/res/layout/overview_actions_container.xml b/quickstep/res/layout/overview_actions_container.xml index 758622b64b..5d489f5f34 100644 --- a/quickstep/res/layout/overview_actions_container.xml +++ b/quickstep/res/layout/overview_actions_container.xml @@ -23,6 +23,7 @@ android:id="@+id/action_buttons" android:layout_width="match_parent" android:layout_height="@dimen/overview_actions_height" + android:layout_gravity="bottom" android:gravity="center_horizontal" android:orientation="horizontal"> From 2725da5dd12d60baa6a5d550ba2c3227cff2e445 Mon Sep 17 00:00:00 2001 From: Uwais Ashraf Date: Wed, 27 Mar 2024 16:17:07 +0000 Subject: [PATCH 08/14] Remove unused code and fix warnings Bug: 330326121 Test: Presubmit - change is a no-op Flag: NA Change-Id: If656113fce6bae82466d9482a92a15f689da00b6 --- .../com/android/quickstep/views/TaskView.java | 45 +++++-------------- 1 file changed, 12 insertions(+), 33 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/TaskView.java b/quickstep/src/com/android/quickstep/views/TaskView.java index abd4ec4eae..79bd107b92 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.java +++ b/quickstep/src/com/android/quickstep/views/TaskView.java @@ -135,8 +135,6 @@ import java.util.stream.Stream; public class TaskView extends FrameLayout implements Reusable { private static final String TAG = TaskView.class.getSimpleName(); - private static final boolean DEBUG = false; - public static final int FLAG_UPDATE_ICON = 1; public static final int FLAG_UPDATE_THUMBNAIL = FLAG_UPDATE_ICON << 1; public static final int FLAG_UPDATE_CORNER_RADIUS = FLAG_UPDATE_THUMBNAIL << 1; @@ -184,7 +182,7 @@ public class TaskView extends FrameLayout implements Reusable { Collections.singletonList(new Rect()); public static final FloatProperty FOCUS_TRANSITION = - new FloatProperty("focusTransition") { + new FloatProperty<>("focusTransition") { @Override public void setValue(TaskView taskView, float v) { taskView.setIconsAndBannersTransitionProgress(v, false /* invert */); @@ -197,7 +195,7 @@ public class TaskView extends FrameLayout implements Reusable { }; private static final FloatProperty SPLIT_SELECT_TRANSLATION_X = - new FloatProperty("splitSelectTranslationX") { + new FloatProperty<>("splitSelectTranslationX") { @Override public void setValue(TaskView taskView, float v) { taskView.setSplitSelectTranslationX(v); @@ -210,7 +208,7 @@ public class TaskView extends FrameLayout implements Reusable { }; private static final FloatProperty SPLIT_SELECT_TRANSLATION_Y = - new FloatProperty("splitSelectTranslationY") { + new FloatProperty<>("splitSelectTranslationY") { @Override public void setValue(TaskView taskView, float v) { taskView.setSplitSelectTranslationY(v); @@ -223,7 +221,7 @@ public class TaskView extends FrameLayout implements Reusable { }; private static final FloatProperty DISMISS_TRANSLATION_X = - new FloatProperty("dismissTranslationX") { + new FloatProperty<>("dismissTranslationX") { @Override public void setValue(TaskView taskView, float v) { taskView.setDismissTranslationX(v); @@ -236,7 +234,7 @@ public class TaskView extends FrameLayout implements Reusable { }; private static final FloatProperty DISMISS_TRANSLATION_Y = - new FloatProperty("dismissTranslationY") { + new FloatProperty<>("dismissTranslationY") { @Override public void setValue(TaskView taskView, float v) { taskView.setDismissTranslationY(v); @@ -249,7 +247,7 @@ public class TaskView extends FrameLayout implements Reusable { }; private static final FloatProperty TASK_OFFSET_TRANSLATION_X = - new FloatProperty("taskOffsetTranslationX") { + new FloatProperty<>("taskOffsetTranslationX") { @Override public void setValue(TaskView taskView, float v) { taskView.setTaskOffsetTranslationX(v); @@ -262,7 +260,7 @@ public class TaskView extends FrameLayout implements Reusable { }; private static final FloatProperty TASK_OFFSET_TRANSLATION_Y = - new FloatProperty("taskOffsetTranslationY") { + new FloatProperty<>("taskOffsetTranslationY") { @Override public void setValue(TaskView taskView, float v) { taskView.setTaskOffsetTranslationY(v); @@ -275,7 +273,7 @@ public class TaskView extends FrameLayout implements Reusable { }; private static final FloatProperty TASK_RESISTANCE_TRANSLATION_X = - new FloatProperty("taskResistanceTranslationX") { + new FloatProperty<>("taskResistanceTranslationX") { @Override public void setValue(TaskView taskView, float v) { taskView.setTaskResistanceTranslationX(v); @@ -288,7 +286,7 @@ public class TaskView extends FrameLayout implements Reusable { }; private static final FloatProperty TASK_RESISTANCE_TRANSLATION_Y = - new FloatProperty("taskResistanceTranslationY") { + new FloatProperty<>("taskResistanceTranslationY") { @Override public void setValue(TaskView taskView, float v) { taskView.setTaskResistanceTranslationY(v); @@ -301,7 +299,7 @@ public class TaskView extends FrameLayout implements Reusable { }; public static final FloatProperty GRID_END_TRANSLATION_X = - new FloatProperty("gridEndTranslationX") { + new FloatProperty<>("gridEndTranslationX") { @Override public void setValue(TaskView taskView, float v) { taskView.setGridEndTranslationX(v); @@ -314,7 +312,7 @@ public class TaskView extends FrameLayout implements Reusable { }; public static final FloatProperty SNAPSHOT_SCALE = - new FloatProperty("snapshotScale") { + new FloatProperty<>("snapshotScale") { @Override public void setValue(TaskView taskView, float v) { taskView.setSnapshotScale(v); @@ -602,10 +600,7 @@ public class TaskView extends FrameLayout implements Reusable { if (event.getAction() == MotionEvent.ACTION_DOWN) { computeAndSetIconTouchDelegate(mIconView, mIconCenterCoords, mIconTouchDelegate); } - if (mIconTouchDelegate != null && mIconTouchDelegate.onTouchEvent(event)) { - return true; - } - return false; + return mIconTouchDelegate != null && mIconTouchDelegate.onTouchEvent(event); } protected void computeAndSetIconTouchDelegate(TaskViewIcon view, float[] tempCenterCoords, @@ -647,9 +642,6 @@ public class TaskView extends FrameLayout implements Reusable { /** * Updates this task view to the given {@param task}. - * - * TODO(b/142282126) Re-evaluate if we need to pass in isMultiWindowMode after - * that issue is fixed */ public void bind(Task task, RecentsOrientedState orientedState) { cancelPendingLoadTasks(); @@ -1594,19 +1586,6 @@ public class TaskView extends FrameLayout implements Reusable { mEndQuickswitchCuj = endQuickswitchCuj; } - private int getExpectedViewHeight(View view) { - int expectedHeight; - int h = view.getLayoutParams().height; - if (h > 0) { - expectedHeight = h; - } else { - int m = MeasureSpec.makeMeasureSpec(MeasureSpec.EXACTLY - 1, MeasureSpec.AT_MOST); - view.measure(m, m); - expectedHeight = view.getMeasuredHeight(); - } - return expectedHeight; - } - @Override public void onInitializeAccessibilityNodeInfo(AccessibilityNodeInfo info) { super.onInitializeAccessibilityNodeInfo(info); From 50f9dbd0a57d02aa6d5c0ae30b78947cdd91b682 Mon Sep 17 00:00:00 2001 From: Brandon Dayauon Date: Thu, 7 Mar 2024 10:14:44 -0800 Subject: [PATCH 09/14] Disable two line text legacy flag. Will now repurpose the twolinetoggle flag to be the flag that will make twoline text enabled/disabled. bug: 316027081 Test: presubmit manually: https://screenshot.googleplex.com/BsZGCm7DrTZLwG4 Flag: com.android.launcher3.enable_twoline_toggle Staging Merged-In: Idef427bad6551ae56b13e35393e076b8e000af5a Change-Id: Idef427bad6551ae56b13e35393e076b8e000af5a --- .../appprediction/PredictionRowView.java | 6 +- src/com/android/launcher3/BubbleTextView.java | 11 +- src/com/android/launcher3/DeviceProfile.java | 5 +- .../launcher3/allapps/BaseAllAppsAdapter.java | 7 +- .../launcher3/config/FeatureFlags.java | 7 +- .../launcher3/AbstractDeviceProfileTest.kt | 13 +- .../launcher3/ui/BubbleTextViewTest.java | 295 ++++++++---------- 7 files changed, 147 insertions(+), 197 deletions(-) diff --git a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java index e1443d0987..b36fd662fe 100644 --- a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java +++ b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java @@ -138,9 +138,9 @@ public class PredictionRowView int totalHeight = iconHeight + iconPadding + textHeight + mVerticalPadding * 2; // Prediction row height will be 4dp bigger than the regular apps in A-Z list when two line // is not enabled. Otherwise, the extra height will increase by just the textHeight. - int extraHeight = (FeatureFlags.enableTwolineAllapps() && (!Flags.enableTwolineToggle() - || (Flags.enableTwolineToggle() && LauncherPrefs.ENABLE_TWOLINE_ALLAPPS_TOGGLE.get( - getContext())))) ? textHeight : mTopRowExtraHeight; + int extraHeight = (Flags.enableTwolineToggle() && + LauncherPrefs.ENABLE_TWOLINE_ALLAPPS_TOGGLE.get(getContext())) + ? textHeight : mTopRowExtraHeight; totalHeight += extraHeight; return getVisibility() == GONE ? 0 : totalHeight + getPaddingTop() + getPaddingBottom(); } diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java index 4f071fe500..3ae1ce117b 100644 --- a/src/com/android/launcher3/BubbleTextView.java +++ b/src/com/android/launcher3/BubbleTextView.java @@ -285,9 +285,6 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, mDotParams.scale = 0f; mForceHideDot = false; setBackground(null); - if (FeatureFlags.enableTwolineAllapps() || FeatureFlags.ENABLE_TWOLINE_DEVICESEARCH.get()) { - setMaxLines(1); - } setTag(null); if (mIconLoadRequest != null) { @@ -299,6 +296,7 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, setAlpha(1); setScaleY(1); setTranslationY(0); + setMaxLines(1); setVisibility(VISIBLE); } @@ -428,10 +426,9 @@ public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver, * Only if actual text can be displayed in two line, the {@code true} value will be effective. */ protected boolean shouldUseTwoLine() { - return FeatureFlags.enableTwolineAllapps() && isCurrentLanguageEnglish() - && (mDisplay == DISPLAY_ALL_APPS || mDisplay == DISPLAY_PREDICTION_ROW) - && (!Flags.enableTwolineToggle() || (Flags.enableTwolineToggle() - && LauncherPrefs.ENABLE_TWOLINE_ALLAPPS_TOGGLE.get(getContext()))); + return isCurrentLanguageEnglish() && (mDisplay == DISPLAY_ALL_APPS + || mDisplay == DISPLAY_PREDICTION_ROW) && (Flags.enableTwolineToggle() + && LauncherPrefs.ENABLE_TWOLINE_ALLAPPS_TOGGLE.get(getContext())); } protected boolean isCurrentLanguageEnglish() { diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java index 4b4bdc2ecf..f96d59ebba 100644 --- a/src/com/android/launcher3/DeviceProfile.java +++ b/src/com/android/launcher3/DeviceProfile.java @@ -1233,9 +1233,8 @@ public class DeviceProfile { if (isVerticalLayout && !mIsResponsiveGrid) { hideWorkspaceLabelsIfNotEnoughSpace(); } - if (FeatureFlags.enableTwolineAllapps() - && (!Flags.enableTwolineToggle() || (Flags.enableTwolineToggle() - && LauncherPrefs.ENABLE_TWOLINE_ALLAPPS_TOGGLE.get(context)))) { + if ((Flags.enableTwolineToggle() + && LauncherPrefs.ENABLE_TWOLINE_ALLAPPS_TOGGLE.get(context))) { // Add extra textHeight to the existing allAppsCellHeight. allAppsCellHeightPx += Utilities.calculateTextHeight(allAppsIconTextSizePx); } diff --git a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java index ca587c16f0..5e5795d4e1 100644 --- a/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java +++ b/src/com/android/launcher3/allapps/BaseAllAppsAdapter.java @@ -223,10 +223,9 @@ public abstract class BaseAllAppsAdapter ex public ViewHolder onCreateViewHolder(ViewGroup parent, int viewType) { switch (viewType) { case VIEW_TYPE_ICON: - int layout = (FeatureFlags.enableTwolineAllapps() && - (!Flags.enableTwolineToggle() || (Flags.enableTwolineToggle() - && LauncherPrefs.ENABLE_TWOLINE_ALLAPPS_TOGGLE.get( - mActivityContext.getApplicationContext())))) + int layout = (Flags.enableTwolineToggle() + && LauncherPrefs.ENABLE_TWOLINE_ALLAPPS_TOGGLE.get( + mActivityContext.getApplicationContext())) ? R.layout.all_apps_icon_twoline : R.layout.all_apps_icon; BubbleTextView icon = (BubbleTextView) mLayoutInflater.inflate( layout, parent, false); diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index bcdf9970bb..262b2a1e43 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -158,7 +158,7 @@ public final class FeatureFlags { // TODO(Block 5): Clean up flags public static final BooleanFlag ENABLE_TWOLINE_DEVICESEARCH = getDebugFlag(201388851, - "ENABLE_TWOLINE_DEVICESEARCH", ENABLED, + "ENABLE_TWOLINE_DEVICESEARCH", DISABLED, "Enable two line label for icons with labels on device search."); public static final BooleanFlag ENABLE_ICON_IN_TEXT_HEADER = getDebugFlag(270395143, @@ -274,10 +274,7 @@ public final class FeatureFlags { // Aconfig migration complete for ENABLE_TWOLINE_ALLAPPS. public static final BooleanFlag ENABLE_TWOLINE_ALLAPPS = getDebugFlag(270390937, - "ENABLE_TWOLINE_ALLAPPS", ENABLED, "Enables two line label inside all apps."); - public static boolean enableTwolineAllapps() { - return ENABLE_TWOLINE_ALLAPPS.get() || Flags.enableTwolineAllapps(); - } + "ENABLE_TWOLINE_ALLAPPS", DISABLED, "Enables two line label inside all apps."); public static final BooleanFlag IME_STICKY_SNACKBAR_EDU = getDebugFlag(270391693, "IME_STICKY_SNACKBAR_EDU", ENABLED, "Show sticky IME edu in AllApps"); diff --git a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt b/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt index 3ba563d0df..ffcf83f303 100644 --- a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt +++ b/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt @@ -38,17 +38,17 @@ import com.android.launcher3.util.rule.setFlags import com.android.launcher3.util.window.CachedDisplayInfo import com.android.launcher3.util.window.WindowManagerProxy import com.google.common.truth.Truth +import org.junit.Rule +import org.mockito.kotlin.any +import org.mockito.kotlin.mock +import org.mockito.kotlin.spy +import org.mockito.kotlin.whenever import java.io.BufferedReader import java.io.File import java.io.PrintWriter import java.io.StringWriter import kotlin.math.max import kotlin.math.min -import org.junit.Rule -import org.mockito.kotlin.any -import org.mockito.kotlin.mock -import org.mockito.kotlin.spy -import org.mockito.kotlin.whenever /** * This is an abstract class for DeviceProfile tests that create an InvariantDeviceProfile based on @@ -274,7 +274,8 @@ abstract class AbstractDeviceProfileTest { isGestureMode: Boolean = true, densityDpi: Int ) { - setFlagsRule.setFlags(false, Flags.FLAG_ENABLE_TWOLINE_TOGGLE) + setFlagsRule.setFlags(true, Flags.FLAG_ENABLE_TWOLINE_TOGGLE) + LauncherPrefs.get(testContext).put(LauncherPrefs.ENABLE_TWOLINE_ALLAPPS_TOGGLE, true) val windowsBounds = perDisplayBoundsCache[displayInfo]!! val realBounds = windowsBounds[rotation] whenever(windowManagerProxy.getDisplayInfo(any())).thenReturn(displayInfo) diff --git a/tests/src/com/android/launcher3/ui/BubbleTextViewTest.java b/tests/src/com/android/launcher3/ui/BubbleTextViewTest.java index 6df3ecd078..90ded100fe 100644 --- a/tests/src/com/android/launcher3/ui/BubbleTextViewTest.java +++ b/tests/src/com/android/launcher3/ui/BubbleTextViewTest.java @@ -22,7 +22,7 @@ import static com.android.launcher3.BubbleTextView.DISPLAY_ALL_APPS; import static com.android.launcher3.BubbleTextView.DISPLAY_PREDICTION_ROW; import static com.android.launcher3.BubbleTextView.DISPLAY_SEARCH_RESULT; import static com.android.launcher3.BubbleTextView.DISPLAY_SEARCH_RESULT_SMALL; -import static com.android.launcher3.config.FeatureFlags.ENABLE_TWOLINE_ALLAPPS; +import static com.android.launcher3.LauncherPrefs.ENABLE_TWOLINE_ALLAPPS_TOGGLE; import static com.google.common.truth.Truth.assertThat; @@ -39,6 +39,7 @@ import android.view.ViewGroup; import com.android.launcher3.BubbleTextView; import com.android.launcher3.Flags; +import com.android.launcher3.LauncherPrefs; import com.android.launcher3.Utilities; import com.android.launcher3.model.data.AppInfo; import com.android.launcher3.model.data.ItemInfoWithIcon; @@ -46,7 +47,6 @@ import com.android.launcher3.search.StringMatcherUtility; import com.android.launcher3.util.ActivityContextWrapper; import com.android.launcher3.util.FlagOp; import com.android.launcher3.util.IntArray; -import com.android.launcher3.util.TestUtil; import com.android.launcher3.views.BaseDragLayer; import org.junit.Before; @@ -96,13 +96,14 @@ public class BubbleTextViewTest { private Context mContext; private int mLimitedWidth; private AppInfo mGmailAppInfo; + private LauncherPrefs mLauncherPrefs; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); Utilities.enableRunningInTestHarnessForTests(); - mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_TOGGLE); mContext = new ActivityContextWrapper(getApplicationContext()); + mLauncherPrefs = LauncherPrefs.get(mContext); mBubbleTextView = new BubbleTextView(mContext); mBubbleTextView.reset(); @@ -130,190 +131,155 @@ public class BubbleTextViewTest { @Test public void testEmptyString_flagOn() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS); - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) { - mItemInfoWithIcon.title = EMPTY_STRING; - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_TOGGLE); + mLauncherPrefs.put(ENABLE_TWOLINE_ALLAPPS_TOGGLE, true); + mItemInfoWithIcon.title = EMPTY_STRING; + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); - mBubbleTextView.onPreDraw(); + mBubbleTextView.onPreDraw(); - assertNotEquals(TWO_LINE, mBubbleTextView.getMaxLines()); - } catch (Exception e) { - throw new RuntimeException(e); - } + assertNotEquals(TWO_LINE, mBubbleTextView.getMaxLines()); } @Test public void testEmptyString_flagOff() { - mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS); - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, false)) { - mItemInfoWithIcon.title = EMPTY_STRING; - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_TOGGLE); + mItemInfoWithIcon.title = EMPTY_STRING; + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); - mBubbleTextView.onPreDraw(); + mBubbleTextView.onPreDraw(); - assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); } @Test public void testStringWithSpaceLongerThanCharLimit_flagOn() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS); - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) { - // test string: "Battery Stats" - mItemInfoWithIcon.title = TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_TOGGLE); + mLauncherPrefs.put(ENABLE_TWOLINE_ALLAPPS_TOGGLE, true); + // test string: "Battery Stats" + mItemInfoWithIcon.title = TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT); - mBubbleTextView.onPreDraw(); + mBubbleTextView.onPreDraw(); - assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); } @Test public void testStringWithSpaceLongerThanCharLimit_flagOff() { - mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS); - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, false)) { - // test string: "Battery Stats" - mItemInfoWithIcon.title = TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_TOGGLE); + // test string: "Battery Stats" + mItemInfoWithIcon.title = TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); - mBubbleTextView.onPreDraw(); + mBubbleTextView.onPreDraw(); - assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); } @Test public void testLongStringNoSpaceLongerThanCharLimit_flagOn() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS); - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) { - // test string: "flutterappflorafy" - mItemInfoWithIcon.title = TEST_LONG_STRING_NO_SPACE_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_TOGGLE); + mLauncherPrefs.put(ENABLE_TWOLINE_ALLAPPS_TOGGLE, true); + // test string: "flutterappflorafy" + mItemInfoWithIcon.title = TEST_LONG_STRING_NO_SPACE_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); - mBubbleTextView.onPreDraw(); + mBubbleTextView.onPreDraw(); - assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); } @Test public void testLongStringNoSpaceLongerThanCharLimit_flagOff() { - mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS); - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, false)) { - // test string: "flutterappflorafy" - mItemInfoWithIcon.title = TEST_LONG_STRING_NO_SPACE_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_TOGGLE); + // test string: "flutterappflorafy" + mItemInfoWithIcon.title = TEST_LONG_STRING_NO_SPACE_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); - mBubbleTextView.onPreDraw(); + mBubbleTextView.onPreDraw(); - assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); } @Test public void testLongStringWithSpaceLongerThanCharLimit_flagOn() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS); - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) { - // test string: "System UWB Field Test" - mItemInfoWithIcon.title = TEST_LONG_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_TOGGLE); + mLauncherPrefs.put(ENABLE_TWOLINE_ALLAPPS_TOGGLE, true); + // test string: "System UWB Field Test" + mItemInfoWithIcon.title = TEST_LONG_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT); - mBubbleTextView.onPreDraw(); + mBubbleTextView.onPreDraw(); - assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); } @Test public void testLongStringWithSpaceLongerThanCharLimit_flagOff() { - mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS); - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, false)) { - // test string: "System UWB Field Test" - mItemInfoWithIcon.title = TEST_LONG_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_TOGGLE); + // test string: "System UWB Field Test" + mItemInfoWithIcon.title = TEST_LONG_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); - mBubbleTextView.onPreDraw(); + mBubbleTextView.onPreDraw(); - assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); } @Test public void testLongStringSymbolLongerThanCharLimit_flagOn() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS); - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) { - // test string: "LEGO®Builder" - mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_TOGGLE); + mLauncherPrefs.put(ENABLE_TWOLINE_ALLAPPS_TOGGLE, true); + // test string: "LEGO®Builder" + mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT); - mBubbleTextView.onPreDraw(); + mBubbleTextView.onPreDraw(); - assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); } @Test public void testLongStringSymbolLongerThanCharLimit_flagOff() { - mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS); - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, false)) { - // test string: "LEGO®Builder" - mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + mSetFlagsRule.disableFlags(Flags.FLAG_ENABLE_TWOLINE_TOGGLE); + // test string: "LEGO®Builder" + mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); - mBubbleTextView.onPreDraw(); + mBubbleTextView.onPreDraw(); - assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); } @Test @@ -374,58 +340,49 @@ public class BubbleTextViewTest { @Test public void testEnsurePredictionRowIsTwoLine() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS); - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) { - // test string: "Battery Stats" - mItemInfoWithIcon.title = TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.setDisplay(DISPLAY_PREDICTION_ROW); - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_TOGGLE); + mLauncherPrefs.put(ENABLE_TWOLINE_ALLAPPS_TOGGLE, true); + // test string: "Battery Stats" + mItemInfoWithIcon.title = TEST_STRING_WITH_SPACE_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.setDisplay(DISPLAY_PREDICTION_ROW); + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT); - mBubbleTextView.onPreDraw(); + mBubbleTextView.onPreDraw(); - assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); } @Test public void modifyTitleToSupportMultiLine_whenLimitedHeight_shouldBeOneLine() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS); - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) { - // test string: "LEGO®Builder" - mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_TOGGLE); + mLauncherPrefs.put(ENABLE_TWOLINE_ALLAPPS_TOGGLE, true); + // test string: "LEGO®Builder" + mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, LIMITED_HEIGHT); - mBubbleTextView.onPreDraw(); + mBubbleTextView.onPreDraw(); - assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + assertEquals(ONE_LINE, mBubbleTextView.getLineCount()); } @Test public void modifyTitleToSupportMultiLine_whenUnlimitedHeight_shouldBeTwoLine() { - mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_ALLAPPS); - try (AutoCloseable flag = TestUtil.overrideFlag(ENABLE_TWOLINE_ALLAPPS, true)) { - // test string: "LEGO®Builder" - mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT; - mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); - mBubbleTextView.applyLabel(mItemInfoWithIcon); - mBubbleTextView.setTypeface(Typeface.MONOSPACE); - mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT); + mSetFlagsRule.enableFlags(Flags.FLAG_ENABLE_TWOLINE_TOGGLE); + mLauncherPrefs.put(ENABLE_TWOLINE_ALLAPPS_TOGGLE, true); + // test string: "LEGO®Builder" + mItemInfoWithIcon.title = TEST_LONG_STRING_SYMBOL_LONGER_THAN_CHAR_LIMIT; + mBubbleTextView.setDisplay(DISPLAY_ALL_APPS); + mBubbleTextView.applyLabel(mItemInfoWithIcon); + mBubbleTextView.setTypeface(Typeface.MONOSPACE); + mBubbleTextView.measure(mLimitedWidth, MAX_HEIGHT); - mBubbleTextView.onPreDraw(); + mBubbleTextView.onPreDraw(); - assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); - } catch (Exception e) { - throw new RuntimeException(e); - } + assertEquals(TWO_LINE, mBubbleTextView.getLineCount()); } @Test From 1d48159bd5efc5f0c13bd7e6fad08e6583b5207b Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Tue, 26 Mar 2024 23:09:35 -0700 Subject: [PATCH 10/14] Update save app pair icon This CL changes the save app pair menu icon to the latest spec. It looks good! Fixes: 331525186 Flag: N/A Test: Manual Change-Id: Ic73f78a27372aca565fce2e3be3e9f3b8ef1d942 --- .../res/layout/overview_actions_container.xml | 2 +- quickstep/res/drawable/ic_save_app_pair.xml | 28 ------------------- .../drawable/ic_save_app_pair_left_right.xml | 28 +++++++++++++++++++ .../res/drawable/ic_save_app_pair_up_down.xml | 28 +++++++++++++++++++ .../quickstep/TaskShortcutFactory.java | 11 ++++++-- .../quickstep/views/OverviewActionsView.java | 6 +++- 6 files changed, 70 insertions(+), 33 deletions(-) delete mode 100644 quickstep/res/drawable/ic_save_app_pair.xml create mode 100644 quickstep/res/drawable/ic_save_app_pair_left_right.xml create mode 100644 quickstep/res/drawable/ic_save_app_pair_up_down.xml diff --git a/go/quickstep/res/layout/overview_actions_container.xml b/go/quickstep/res/layout/overview_actions_container.xml index 077cfaee19..df0912478b 100644 --- a/go/quickstep/res/layout/overview_actions_container.xml +++ b/go/quickstep/res/layout/overview_actions_container.xml @@ -126,7 +126,7 @@ style="@style/GoOverviewActionButton" android:layout_width="wrap_content" android:layout_height="wrap_content" - android:drawableStart="@drawable/ic_save_app_pair" + android:drawableStart="@drawable/ic_save_app_pair_up_down" android:text="@string/action_save_app_pair" android:theme="@style/ThemeControlHighlightWorkspaceColor" android:visibility="gone" /> diff --git a/quickstep/res/drawable/ic_save_app_pair.xml b/quickstep/res/drawable/ic_save_app_pair.xml deleted file mode 100644 index 4a7ee1ac70..0000000000 --- a/quickstep/res/drawable/ic_save_app_pair.xml +++ /dev/null @@ -1,28 +0,0 @@ - - - - - - - diff --git a/quickstep/res/drawable/ic_save_app_pair_left_right.xml b/quickstep/res/drawable/ic_save_app_pair_left_right.xml new file mode 100644 index 0000000000..b104f44b76 --- /dev/null +++ b/quickstep/res/drawable/ic_save_app_pair_left_right.xml @@ -0,0 +1,28 @@ + + + + + + + diff --git a/quickstep/res/drawable/ic_save_app_pair_up_down.xml b/quickstep/res/drawable/ic_save_app_pair_up_down.xml new file mode 100644 index 0000000000..86f110ce5e --- /dev/null +++ b/quickstep/res/drawable/ic_save_app_pair_up_down.xml @@ -0,0 +1,28 @@ + + + + + + + diff --git a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java index c97e62a60a..38d11327e7 100644 --- a/quickstep/src/com/android/quickstep/TaskShortcutFactory.java +++ b/quickstep/src/com/android/quickstep/TaskShortcutFactory.java @@ -136,8 +136,9 @@ public interface TaskShortcutFactory { class SaveAppPairSystemShortcut extends SystemShortcut { private final GroupedTaskView mTaskView; - public SaveAppPairSystemShortcut(BaseDraggingActivity activity, GroupedTaskView taskView) { - super(R.drawable.ic_save_app_pair, R.string.save_app_pair, activity, + public SaveAppPairSystemShortcut(BaseDraggingActivity activity, GroupedTaskView taskView, + int iconResId) { + super(iconResId, R.string.save_app_pair, activity, taskView.getItemInfo(), taskView); mTaskView = taskView; } @@ -340,8 +341,12 @@ public interface TaskShortcutFactory { return null; } + int iconResId = deviceProfile.isLeftRightSplit + ? R.drawable.ic_save_app_pair_left_right + : R.drawable.ic_save_app_pair_up_down; + return Collections.singletonList( - new SaveAppPairSystemShortcut(activity, (GroupedTaskView) taskView)); + new SaveAppPairSystemShortcut(activity, (GroupedTaskView) taskView, iconResId)); } @Override diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java index e0091a5ae2..afee706e37 100644 --- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java +++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java @@ -407,7 +407,11 @@ public class OverviewActionsView extends FrameLayo ? R.drawable.ic_split_horizontal : R.drawable.ic_split_vertical; mSplitButton.setCompoundDrawablesRelativeWithIntrinsicBounds(splitIconRes, 0, 0, 0); + + int appPairIconRes = dp.isLeftRightSplit + ? R.drawable.ic_save_app_pair_left_right + : R.drawable.ic_save_app_pair_up_down; mSaveAppPairButton.setCompoundDrawablesRelativeWithIntrinsicBounds( - R.drawable.ic_save_app_pair, 0, 0, 0); + appPairIconRes, 0, 0, 0); } } From efab2489d6a959a5ff90d7ef14d502d78223edb9 Mon Sep 17 00:00:00 2001 From: Sebastian Franco Date: Thu, 14 Dec 2023 10:58:21 -0600 Subject: [PATCH 11/14] Generate grid migration cases and test if they are valid This makes sure the grid migration logic always produces valid results. Bug: 313900847 Bug: 323525592 Flag: NA Test: ValidGridMigrationUnitTest.kt Change-Id: I76b19e1fa315f8a997afad34e5a4df7cc465b0c2 --- .../launcher3/config/FeatureFlags.java | 5 - .../launcher3/model/DeviceGridState.java | 4 +- .../model/GridSizeMigrationUtil.java | 21 +-- .../testgenerator/RandomBoardGenerator.kt | 22 ++- .../ValidGridMigrationTestCaseGenerator.kt | 160 ++++++++++++++++ .../model/GridSizeMigrationUtilTest.kt | 73 +------- .../model/gridmigration/GridMigrationUtils.kt | 114 ++++++++++++ .../ValidGridMigrationUnitTest.kt | 173 ++++++++++++++++++ 8 files changed, 476 insertions(+), 96 deletions(-) create mode 100644 tests/src/com/android/launcher3/celllayout/testgenerator/ValidGridMigrationTestCaseGenerator.kt create mode 100644 tests/src/com/android/launcher3/model/gridmigration/GridMigrationUtils.kt create mode 100644 tests/src/com/android/launcher3/model/gridmigration/ValidGridMigrationUnitTest.kt diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 6d64c22547..1c34c72d21 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -397,11 +397,6 @@ public final class FeatureFlags { + "waiting for SystemUI and then merging the SystemUI progress whenever we " + "start receiving the events"); - // TODO(Block 24): Clean up flags - public static final BooleanFlag ENABLE_NEW_MIGRATION_LOGIC = getDebugFlag(270393455, - "ENABLE_NEW_MIGRATION_LOGIC", ENABLED, - "Enable the new grid migration logic, keeping pages when src < dest"); - // TODO(Block 25): Clean up flags public static final BooleanFlag ENABLE_NEW_GESTURE_NAV_TUTORIAL = getDebugFlag(270396257, "ENABLE_NEW_GESTURE_NAV_TUTORIAL", ENABLED, diff --git a/src/com/android/launcher3/model/DeviceGridState.java b/src/com/android/launcher3/model/DeviceGridState.java index 8c68eb84ec..729b3814a4 100644 --- a/src/com/android/launcher3/model/DeviceGridState.java +++ b/src/com/android/launcher3/model/DeviceGridState.java @@ -156,11 +156,11 @@ public class DeviceGridState implements Comparable { } public Integer getColumns() { - return Integer.parseInt(String.valueOf(mGridSizeString.charAt(0))); + return Integer.parseInt(String.valueOf(mGridSizeString.split(",")[0])); } public Integer getRows() { - return Integer.parseInt(String.valueOf(mGridSizeString.charAt(2))); + return Integer.parseInt(String.valueOf(mGridSizeString.split(",")[1])); } @Override diff --git a/src/com/android/launcher3/model/GridSizeMigrationUtil.java b/src/com/android/launcher3/model/GridSizeMigrationUtil.java index 15190c7952..299c952d2a 100644 --- a/src/com/android/launcher3/model/GridSizeMigrationUtil.java +++ b/src/com/android/launcher3/model/GridSizeMigrationUtil.java @@ -223,19 +223,13 @@ public class GridSizeMigrationUtil { screens.add(screenId); } - boolean preservePages = false; - if (screens.isEmpty() && FeatureFlags.ENABLE_NEW_MIGRATION_LOGIC.get()) { - preservePages = destDeviceState.compareTo(srcDeviceState) >= 0 - && destDeviceState.getColumns() - srcDeviceState.getColumns() <= 2; - } - // Then we place the items on the screens for (int screenId : screens) { if (DEBUG) { Log.d(TAG, "Migrating " + screenId); } solveGridPlacement(helper, srcReader, - destReader, screenId, trgX, trgY, workspaceToBeAdded, false); + destReader, screenId, trgX, trgY, workspaceToBeAdded); if (workspaceToBeAdded.isEmpty()) { break; } @@ -245,8 +239,8 @@ public class GridSizeMigrationUtil { // any of the screens, in this case we add them to new screens until all of them are placed. int screenId = destReader.mLastScreenId + 1; while (!workspaceToBeAdded.isEmpty()) { - solveGridPlacement(helper, srcReader, - destReader, screenId, trgX, trgY, workspaceToBeAdded, preservePages); + solveGridPlacement(helper, srcReader, destReader, screenId, trgX, trgY, + workspaceToBeAdded); screenId++; } @@ -348,7 +342,7 @@ public class GridSizeMigrationUtil { private static void solveGridPlacement(@NonNull final DatabaseHelper helper, @NonNull final DbReader srcReader, @NonNull final DbReader destReader, final int screenId, final int trgX, final int trgY, - @NonNull final List sortedItemsToPlace, final boolean matchingScreenIdOnly) { + @NonNull final List sortedItemsToPlace) { final GridOccupancy occupied = new GridOccupancy(trgX, trgY); final Point trg = new Point(trgX, trgY); final Point next = new Point(0, screenId == 0 @@ -366,8 +360,6 @@ public class GridSizeMigrationUtil { Iterator iterator = sortedItemsToPlace.iterator(); while (iterator.hasNext()) { final DbEntry entry = iterator.next(); - if (matchingScreenIdOnly && entry.screenId < screenId) continue; - if (matchingScreenIdOnly && entry.screenId > screenId) break; if (entry.minSpanX > trgX || entry.minSpanY > trgY) { iterator.remove(); continue; @@ -435,7 +427,8 @@ public class GridSizeMigrationUtil { } } - protected static class DbReader { + @VisibleForTesting + public static class DbReader { private final SQLiteDatabase mDb; private final String mTableName; @@ -446,7 +439,7 @@ public class GridSizeMigrationUtil { private final Map> mWorkspaceEntriesByScreenId = new ArrayMap<>(); - DbReader(SQLiteDatabase db, String tableName, Context context, + public DbReader(SQLiteDatabase db, String tableName, Context context, Set validPackages) { mDb = db; mTableName = tableName; diff --git a/tests/src/com/android/launcher3/celllayout/testgenerator/RandomBoardGenerator.kt b/tests/src/com/android/launcher3/celllayout/testgenerator/RandomBoardGenerator.kt index c5dbce42c4..ff4698793f 100644 --- a/tests/src/com/android/launcher3/celllayout/testgenerator/RandomBoardGenerator.kt +++ b/tests/src/com/android/launcher3/celllayout/testgenerator/RandomBoardGenerator.kt @@ -21,6 +21,13 @@ import java.util.Random /** Generates a random CellLayoutBoard. */ open class RandomBoardGenerator(generator: Random) : DeterministicRandomGenerator(generator) { + + companion object { + // This is the max number of widgets because we encode the widgets as letters A-Z and we + // already have some of those letter used by other things so 22 is a safe number + val MAX_NUMBER_OF_WIDGETS = 22 + } + /** * @param remainingEmptySpaces the maximum number of spaces we will fill with icons and widgets * meaning that if the number is 100 we will try to fill the board with at most 100 spaces @@ -33,9 +40,9 @@ open class RandomBoardGenerator(generator: Random) : DeterministicRandomGenerato } protected fun fillBoard( - board: CellLayoutBoard, - area: Rect, - remainingEmptySpacesArg: Int + board: CellLayoutBoard, + area: Rect, + remainingEmptySpacesArg: Int ): CellLayoutBoard { var remainingEmptySpaces = remainingEmptySpacesArg if (area.height() * area.width() <= 0) return board @@ -45,11 +52,18 @@ open class RandomBoardGenerator(generator: Random) : DeterministicRandomGenerato val y = area.top + getRandom(0, area.height() - height) if (remainingEmptySpaces > 0) { remainingEmptySpaces -= width * height - } else if (board.widgets.size <= 22 && width * height > 1) { + } + + if (board.widgets.size <= MAX_NUMBER_OF_WIDGETS && width * height > 1) { board.addWidget(x, y, width, height) } else { board.addIcon(x, y) } + + if (remainingEmptySpaces < 0) { + // optimization, no need to keep going + return board + } fillBoard(board, Rect(area.left, area.top, area.right, y), remainingEmptySpaces) fillBoard(board, Rect(area.left, y, x, area.bottom), remainingEmptySpaces) fillBoard(board, Rect(x, y + height, area.right, area.bottom), remainingEmptySpaces) diff --git a/tests/src/com/android/launcher3/celllayout/testgenerator/ValidGridMigrationTestCaseGenerator.kt b/tests/src/com/android/launcher3/celllayout/testgenerator/ValidGridMigrationTestCaseGenerator.kt new file mode 100644 index 0000000000..e773a86a7a --- /dev/null +++ b/tests/src/com/android/launcher3/celllayout/testgenerator/ValidGridMigrationTestCaseGenerator.kt @@ -0,0 +1,160 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.celllayout.testgenerator + +import android.graphics.Point +import com.android.launcher3.LauncherSettings +import com.android.launcher3.celllayout.board.CellLayoutBoard +import com.android.launcher3.model.data.LauncherAppWidgetInfo +import com.android.launcher3.model.gridmigration.WorkspaceItem +import java.util.Random +import java.util.concurrent.atomic.AtomicInteger + +/** + * Generate a list of WorkspaceItem's for the given test case. + * + * @param repeatAfter a number after which we would repeat the same number of icons and widgets to + * account for cases where the user have the same item multiple times. + */ +fun generateItemsForTest( + testCase: GridMigrationUnitTestCase, + repeatAfter: Int +): List { + val id = AtomicInteger(0) + val widgetId = AtomicInteger(LauncherAppWidgetInfo.CUSTOM_WIDGET_ID - 1) + val boards = testCase.boards + // Repeat the same appWidgetProvider and intent to have repeating widgets and icons and test + // that case too + val getIntent = { i: Int -> "Intent ${i % repeatAfter}" } + val getProvider = { i: Int -> "com.test/test.Provider${i % repeatAfter}" } + val hotseatEntries = + (0 until boards[0].width).map { + WorkspaceItem( + x = it, + y = 0, + spanX = 1, + spanY = 1, + id = id.getAndAdd(1), + screenId = it, + title = "Hotseat ${id.get()}", + appWidgetId = -1, + appWidgetProvider = "Hotseat icons don't have a provider", + intent = getIntent(id.get()), + type = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION, + container = LauncherSettings.Favorites.CONTAINER_HOTSEAT + ) + } + var widgetEntries = + boards + .flatMapIndexed { i, board -> board.widgets.map { Pair(i, it) } } + .map { + WorkspaceItem( + x = it.second.cellX, + y = it.second.cellY, + spanX = it.second.spanX, + spanY = it.second.spanY, + id = id.getAndAdd(1), + screenId = it.first, + title = "Title Widget ${id.get()}", + appWidgetId = widgetId.getAndAdd(-1), + appWidgetProvider = getProvider(id.get()), + intent = "Widgets don't have intent", + type = LauncherSettings.Favorites.ITEM_TYPE_APPWIDGET, + container = LauncherSettings.Favorites.CONTAINER_DESKTOP + ) + } + widgetEntries = widgetEntries.filter { it.appWidgetProvider.contains("Provider4") } + val iconEntries = + boards + .flatMapIndexed { i, board -> board.icons.map { Pair(i, it) } } + .map { + WorkspaceItem( + x = it.second.coord.x, + y = it.second.coord.y, + spanX = 1, + spanY = 1, + id = id.getAndAdd(1), + screenId = it.first, + title = "Title Icon ${id.get()}", + appWidgetId = -1, + appWidgetProvider = "Icons don't have providers", + intent = getIntent(id.get()), + type = LauncherSettings.Favorites.ITEM_TYPE_APPLICATION, + container = LauncherSettings.Favorites.CONTAINER_DESKTOP + ) + } + return widgetEntries + hotseatEntries // + iconEntries +} + +data class GridMigrationUnitTestCase( + val boards: List, + val srcSize: Point, + val targetSize: Point, + val seed: Long +) + +class ValidGridMigrationTestCaseGenerator(private val generator: Random) : + DeterministicRandomGenerator(generator) { + + companion object { + const val MAX_BOARD_SIZE = 12 + const val MAX_BOARD_COUNT = 10 + const val SEED = 10342 + } + + private fun generateBoards( + boardGenerator: RandomBoardGenerator, + width: Int, + height: Int, + boardCount: Int + ): List { + val boards = mutableListOf() + for (i in 0 until boardCount) { + boards.add( + boardGenerator.generateBoard( + width, + height, + boardGenerator.getRandom(0, width * height) + ) + ) + } + return boards + } + + fun generateTestCase(): GridMigrationUnitTestCase { + var seed = generator.nextLong() + val randomBoardGenerator = RandomBoardGenerator(Random(seed)) + val width = randomBoardGenerator.getRandom(3, MAX_BOARD_SIZE) + val height = randomBoardGenerator.getRandom(3, MAX_BOARD_SIZE) + return GridMigrationUnitTestCase( + boards = + generateBoards( + boardGenerator = randomBoardGenerator, + width = width, + height = height, + boardCount = randomBoardGenerator.getRandom(3, MAX_BOARD_COUNT) + ), + srcSize = Point(width, height), + targetSize = + Point( + randomBoardGenerator.getRandom(3, MAX_BOARD_SIZE), + randomBoardGenerator.getRandom(3, MAX_BOARD_SIZE) + ), + seed = seed + ) + } +} diff --git a/tests/src/com/android/launcher3/model/GridSizeMigrationUtilTest.kt b/tests/src/com/android/launcher3/model/GridSizeMigrationUtilTest.kt index 04735f20b1..761f06d514 100644 --- a/tests/src/com/android/launcher3/model/GridSizeMigrationUtilTest.kt +++ b/tests/src/com/android/launcher3/model/GridSizeMigrationUtilTest.kt @@ -28,7 +28,6 @@ import com.android.launcher3.InvariantDeviceProfile import com.android.launcher3.LauncherPrefs import com.android.launcher3.LauncherPrefs.Companion.WORKSPACE_SIZE import com.android.launcher3.LauncherSettings.Favorites.* -import com.android.launcher3.config.FeatureFlags import com.android.launcher3.model.GridSizeMigrationUtil.DbReader import com.android.launcher3.pm.UserCache import com.android.launcher3.provider.LauncherDbUtils @@ -98,10 +97,7 @@ class GridSizeMigrationUtilTest { modelHelper.destroy() } - /** - * Old migration logic, should be modified once [FeatureFlags.ENABLE_NEW_MIGRATION_LOGIC] is not - * needed anymore - */ + /** Old migration logic, should be modified once is not needed anymore */ @Test @Throws(Exception::class) fun testMigration() { @@ -208,10 +204,7 @@ class GridSizeMigrationUtilTest { assertThat(locMap[testPackage9]).isEqualTo(Point(0, 2)) } - /** - * Old migration logic, should be modified once [FeatureFlags.ENABLE_NEW_MIGRATION_LOGIC] is not - * needed anymore - */ + /** Old migration logic, should be modified once is not needed anymore */ @Test @Throws(Exception::class) fun testMigrationBackAndForth() { @@ -605,68 +598,6 @@ class GridSizeMigrationUtilTest { c.close() } - /** - * Migrating from a smaller grid to a large one should keep the pages if the column difference - * is less than 2 - */ - @Test - @Throws(Exception::class) - fun migrateFromSmallerGridSmallDifference() { - enableNewMigrationLogic("4,4") - - // Setup src grid - addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 2, 2, testPackage1, 5, TMP_TABLE) - addItem(ITEM_TYPE_APPLICATION, 0, CONTAINER_DESKTOP, 2, 3, testPackage2, 6, TMP_TABLE) - addItem(ITEM_TYPE_APPLICATION, 1, CONTAINER_DESKTOP, 3, 1, testPackage3, 7, TMP_TABLE) - addItem(ITEM_TYPE_APPLICATION, 1, CONTAINER_DESKTOP, 3, 2, testPackage4, 8, TMP_TABLE) - addItem(ITEM_TYPE_APPLICATION, 2, CONTAINER_DESKTOP, 3, 3, testPackage5, 9, TMP_TABLE) - - idp.numDatabaseHotseatIcons = 4 - idp.numColumns = 6 - idp.numRows = 5 - - val srcReader = DbReader(db, TMP_TABLE, context, validPackages) - val destReader = DbReader(db, TABLE_NAME, context, validPackages) - GridSizeMigrationUtil.migrate( - dbHelper, - srcReader, - destReader, - idp.numDatabaseHotseatIcons, - Point(idp.numColumns, idp.numRows), - DeviceGridState(context), - DeviceGridState(idp) - ) - - // Get workspace items - val c = - db.query( - TABLE_NAME, - arrayOf(INTENT, SCREEN), - "container=$CONTAINER_DESKTOP", - null, - null, - null, - null - ) - ?: throw IllegalStateException() - val intentIndex = c.getColumnIndex(INTENT) - val screenIndex = c.getColumnIndex(SCREEN) - - // Get in which screen the icon is - val locMap = HashMap() - while (c.moveToNext()) { - locMap[Intent.parseUri(c.getString(intentIndex), 0).getPackage()] = - c.getInt(screenIndex) - } - c.close() - assertThat(locMap.size).isEqualTo(5) - assertThat(locMap[testPackage1]).isEqualTo(0) - assertThat(locMap[testPackage2]).isEqualTo(0) - assertThat(locMap[testPackage3]).isEqualTo(1) - assertThat(locMap[testPackage4]).isEqualTo(1) - assertThat(locMap[testPackage5]).isEqualTo(2) - } - /** * Migrating from a smaller grid to a large one should reflow the pages if the column difference * is more than 2 diff --git a/tests/src/com/android/launcher3/model/gridmigration/GridMigrationUtils.kt b/tests/src/com/android/launcher3/model/gridmigration/GridMigrationUtils.kt new file mode 100644 index 0000000000..cc8e61d726 --- /dev/null +++ b/tests/src/com/android/launcher3/model/gridmigration/GridMigrationUtils.kt @@ -0,0 +1,114 @@ +/* + * Copyright (C) 2024 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.launcher3.model.gridmigration + +import android.content.ContentValues +import android.database.sqlite.SQLiteDatabase +import android.graphics.Point +import com.android.launcher3.LauncherSettings.Favorites +import com.android.launcher3.celllayout.board.CellLayoutBoard + +class MockSet(override val size: Int) : Set { + override fun contains(element: String): Boolean = true + override fun containsAll(elements: Collection): Boolean = true + override fun isEmpty(): Boolean = false + override fun iterator(): Iterator = listOf().iterator() +} + +fun itemListToBoard(itemsArg: List, boardSize: Point): List { + val items = itemsArg.filter { it.container != Favorites.CONTAINER_HOTSEAT } + val boardList = + List(items.maxOf { it.screenId + 1 }) { CellLayoutBoard(boardSize.x, boardSize.y) } + items.forEach { + when (it.type) { + Favorites.ITEM_TYPE_FOLDER, + Favorites.ITEM_TYPE_APP_PAIR -> throw Exception("Not implemented") + Favorites.ITEM_TYPE_APPWIDGET -> + boardList[it.screenId].addWidget(it.x, it.y, it.spanX, it.spanY) + Favorites.ITEM_TYPE_APPLICATION -> boardList[it.screenId].addIcon(it.x, it.y) + } + } + return boardList +} + +fun insertIntoDb(tableName: String, entry: WorkspaceItem, db: SQLiteDatabase) { + val values = ContentValues() + values.put(Favorites.SCREEN, entry.screenId) + values.put(Favorites.CELLX, entry.x) + values.put(Favorites.CELLY, entry.y) + values.put(Favorites.SPANX, entry.spanX) + values.put(Favorites.SPANY, entry.spanY) + values.put(Favorites.TITLE, entry.title) + values.put(Favorites.INTENT, entry.intent) + values.put(Favorites.APPWIDGET_PROVIDER, entry.appWidgetProvider) + values.put(Favorites.APPWIDGET_ID, entry.appWidgetId) + values.put(Favorites.CONTAINER, entry.container) + values.put(Favorites.ITEM_TYPE, entry.type) + values.put(Favorites._ID, entry.id) + db.insert(tableName, null, values) +} + +fun readDb(tableName: String, db: SQLiteDatabase): List { + val result = mutableListOf() + val cursor = db.query(tableName, null, null, null, null, null, null) + val indexCellX: Int = cursor.getColumnIndexOrThrow(Favorites.CELLX) + val indexCellY: Int = cursor.getColumnIndexOrThrow(Favorites.CELLY) + val indexSpanX: Int = cursor.getColumnIndexOrThrow(Favorites.SPANX) + val indexSpanY: Int = cursor.getColumnIndexOrThrow(Favorites.SPANY) + val indexId: Int = cursor.getColumnIndexOrThrow(Favorites._ID) + val indexScreen: Int = cursor.getColumnIndexOrThrow(Favorites.SCREEN) + val indexTitle: Int = cursor.getColumnIndexOrThrow(Favorites.TITLE) + val indexAppWidgetId: Int = cursor.getColumnIndexOrThrow(Favorites.APPWIDGET_ID) + val indexWidgetProvider: Int = cursor.getColumnIndexOrThrow(Favorites.APPWIDGET_PROVIDER) + val indexIntent: Int = cursor.getColumnIndexOrThrow(Favorites.INTENT) + val indexItemType: Int = cursor.getColumnIndexOrThrow(Favorites.ITEM_TYPE) + val container: Int = cursor.getColumnIndexOrThrow(Favorites.CONTAINER) + while (cursor.moveToNext()) { + result.add( + WorkspaceItem( + x = cursor.getInt(indexCellX), + y = cursor.getInt(indexCellY), + spanX = cursor.getInt(indexSpanX), + spanY = cursor.getInt(indexSpanY), + id = cursor.getInt(indexId), + screenId = cursor.getInt(indexScreen), + title = cursor.getString(indexTitle), + appWidgetId = cursor.getInt(indexAppWidgetId), + appWidgetProvider = cursor.getString(indexWidgetProvider), + intent = cursor.getString(indexIntent), + type = cursor.getInt(indexItemType), + container = cursor.getInt(container) + ) + ) + } + return result +} + +data class WorkspaceItem( + val x: Int, + val y: Int, + val spanX: Int, + val spanY: Int, + val id: Int, + val screenId: Int, + val title: String, + val appWidgetId: Int, + val appWidgetProvider: String, + val intent: String, + val type: Int, + val container: Int, +) diff --git a/tests/src/com/android/launcher3/model/gridmigration/ValidGridMigrationUnitTest.kt b/tests/src/com/android/launcher3/model/gridmigration/ValidGridMigrationUnitTest.kt new file mode 100644 index 0000000000..100297608b --- /dev/null +++ b/tests/src/com/android/launcher3/model/gridmigration/ValidGridMigrationUnitTest.kt @@ -0,0 +1,173 @@ +/* + * Copyright (C) 2023 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.gridmigration + +import android.content.Context +import android.database.sqlite.SQLiteDatabase +import android.graphics.Point +import android.os.Process +import android.util.Log +import androidx.test.ext.junit.runners.AndroidJUnit4 +import androidx.test.filters.SmallTest +import androidx.test.platform.app.InstrumentationRegistry +import com.android.launcher3.InvariantDeviceProfile +import com.android.launcher3.LauncherSettings.Favorites +import com.android.launcher3.celllayout.testgenerator.ValidGridMigrationTestCaseGenerator +import com.android.launcher3.celllayout.testgenerator.generateItemsForTest +import com.android.launcher3.model.DatabaseHelper +import com.android.launcher3.model.DeviceGridState +import com.android.launcher3.model.GridSizeMigrationUtil +import com.android.launcher3.pm.UserCache +import com.android.launcher3.provider.LauncherDbUtils +import com.android.launcher3.util.rule.TestStabilityRule +import com.android.launcher3.util.rule.TestStabilityRule.Stability +import java.util.Random +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +@SmallTest +@RunWith(AndroidJUnit4::class) +class ValidGridMigrationUnitTest { + + companion object { + const val SEED = 1044542 + const val REPEAT_AFTER = 10 + const val TAG = "ValidGridMigrationUnitTest" + } + + private lateinit var context: Context + + @Before + fun setUp() { + context = InstrumentationRegistry.getInstrumentation().targetContext + } + + private fun validate( + srcItems: List, + dstItems: List, + destinationSize: Point + ) { + // This returns a map with the number of repeated elements + // ex { calculatorIcon : 6, weatherWidget : 2 } + val itemsToSet = { it: List -> + it.filter { it.container != Favorites.CONTAINER_HOTSEAT } + .groupingBy { + when (it.type) { + Favorites.ITEM_TYPE_FOLDER, + Favorites.ITEM_TYPE_APP_PAIR -> throw Exception("Not implemented") + Favorites.ITEM_TYPE_APPWIDGET -> it.appWidgetProvider + Favorites.ITEM_TYPE_APPLICATION -> it.intent + else -> it.title + } + } + .eachCount() + } + for (it in dstItems) { + assert((it.x in 0..destinationSize.x) && (it.y in 0..destinationSize.y)) { + "Item outside of the board size. Size = $destinationSize Item = $it" + } + assert( + (it.x + it.spanX in 0..destinationSize.x) && + (it.y + it.spanY in 0..destinationSize.y) + ) { + "Item doesn't fit in the grid. Size = $destinationSize Item = $it" + } + } + + assert(itemsToSet(srcItems) == itemsToSet(dstItems)) { + "The srcItems do not match the dstItems src = $srcItems dst = $dstItems" + } + } + + private fun addItemsToDb(db: SQLiteDatabase, tableName: String, items: List) { + LauncherDbUtils.SQLiteTransaction(db).use { transaction -> + items.forEach { insertIntoDb(tableName, it, transaction.db) } + transaction.commit() + } + } + + private fun migrate( + srcItems: List, + srcSize: Point, + targetSize: Point + ): List { + val userSerial = UserCache.INSTANCE[context].getSerialNumberForUser(Process.myUserHandle()) + val dbHelper = + DatabaseHelper( + context, + null, + { UserCache.INSTANCE.get(context).getSerialNumberForUser(it) }, + {} + ) + val srcTableName = Favorites.TMP_TABLE + val dstTableName = Favorites.TABLE_NAME + Favorites.addTableToDb(dbHelper.writableDatabase, userSerial, false, srcTableName) + addItemsToDb(dbHelper.writableDatabase, srcTableName, srcItems) + LauncherDbUtils.SQLiteTransaction(dbHelper.writableDatabase).use { + GridSizeMigrationUtil.migrate( + dbHelper, + GridSizeMigrationUtil.DbReader(it.db, srcTableName, context, MockSet(1)), + GridSizeMigrationUtil.DbReader(it.db, dstTableName, context, MockSet(1)), + targetSize.x, + targetSize, + DeviceGridState( + srcSize.x, + srcSize.y, + srcSize.x, + InvariantDeviceProfile.TYPE_PHONE, + srcTableName + ), + DeviceGridState( + targetSize.x, + targetSize.y, + targetSize.x, + InvariantDeviceProfile.TYPE_PHONE, + dstTableName + ) + ) + it.commit() + } + return readDb(dstTableName, dbHelper.readableDatabase) + } + + @Test + fun runTestCase() { + val caseGenerator = ValidGridMigrationTestCaseGenerator(Random(SEED.toLong())) + for (i in 0..50) { + val testCase = caseGenerator.generateTestCase() + Log.d(TAG, "Test case = $testCase") + val srcItemList = generateItemsForTest(testCase, REPEAT_AFTER) + val dstItemList = migrate(srcItemList, testCase.srcSize, testCase.targetSize) + validate(srcItemList, dstItemList, testCase.targetSize) + } + } + + // This test takes about 4 minutes, there is no need to run it in presubmit. + @Stability(flavors = TestStabilityRule.LOCAL or TestStabilityRule.PLATFORM_POSTSUBMIT) + @Test + fun runExtensiveTestCases() { + val caseGenerator = ValidGridMigrationTestCaseGenerator(Random(SEED.toLong())) + for (i in 0..1000) { + val testCase = caseGenerator.generateTestCase() + Log.d(TAG, "Test case = $testCase") + val srcItemList = generateItemsForTest(testCase, REPEAT_AFTER) + val dstItemList = migrate(srcItemList, testCase.srcSize, testCase.targetSize) + validate(srcItemList, dstItemList, testCase.targetSize) + } + } +} From 10c03e499d6c29e1c3fec7b8633c0eaefb623e07 Mon Sep 17 00:00:00 2001 From: Fengjiang Li Date: Tue, 26 Mar 2024 16:21:01 -0700 Subject: [PATCH 12/14] Extend CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK to start as early as when user starts predictive back swipe Bug: 330405993 Test: prefetto trace https://ui.perfetto.dev/#!/?s=58c0513fe0190f84ea1621a96d790a53b83fefc1ee402085b0d75bfc7b51e019 Flag: aconfig com.android.launcher3.enable_predictive_back_gesture TEAMFOOD Change-Id: I76c32975e5ae6dcb0395d2eee68417f761455262 --- .../uioverrides/states/AllAppsState.java | 31 ++++++++++++++++--- .../states/OverviewModalTaskState.java | 2 +- .../uioverrides/states/OverviewState.java | 4 +-- src/com/android/launcher3/Launcher.java | 11 ++++++- src/com/android/launcher3/LauncherState.java | 19 +++++++++--- 5 files changed, 54 insertions(+), 13 deletions(-) diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java index b6002e8b76..7875daee4a 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/AllAppsState.java @@ -32,6 +32,8 @@ import com.android.launcher3.views.ActivityContext; import com.android.quickstep.util.BaseDepthController; import com.android.systemui.shared.system.InteractionJankMonitorWrapper; +import java.util.concurrent.TimeUnit; + /** * Definition for AllApps state */ @@ -39,6 +41,8 @@ public class AllAppsState extends LauncherState { private static final int STATE_FLAGS = FLAG_WORKSPACE_INACCESSIBLE | FLAG_CLOSE_POPUPS | FLAG_HOTSEAT_INACCESSIBLE; + private static final long BACK_CUJ_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(5); + public AllAppsState(int id) { super(id, LAUNCHER_STATE_ALLAPPS, STATE_FLAGS); @@ -53,14 +57,33 @@ public class AllAppsState extends LauncherState { } @Override - public void onBackPressed(Launcher launcher) { + public void onBackStarted(Launcher launcher) { + // Because the back gesture can take longer time depending on when user release the finger, + // we pass BACK_CUJ_TIMEOUT_MS as timeout to the jank monitor. InteractionJankMonitorWrapper.begin(launcher.getAppsView(), - Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK); - super.onBackPressed(launcher); + Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK, BACK_CUJ_TIMEOUT_MS); + super.onBackStarted(launcher); } @Override - protected void onBackPressCompleted(boolean success) { + public void onBackInvoked(Launcher launcher) { + // In predictive back swipe, onBackInvoked() will be called after onBackStarted(). + // Because the 2nd InteractionJankMonitor.begin() will be ignore within timeout, it's safe + // to call InteractionJankMonitorWrapper.begin here. + InteractionJankMonitorWrapper.begin(launcher.getAppsView(), + Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK); + super.onBackInvoked(launcher); + } + + /** Called when predictive back swipe is cancelled. */ + @Override + public void onBackCancelled(Launcher launcher) { + super.onBackCancelled(launcher); + InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK); + } + + @Override + protected void onBackAnimationCompleted(boolean success) { if (success) { // Animation was successful. InteractionJankMonitorWrapper.end(Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_BACK); diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java index 856b519d88..c63eaebc89 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewModalTaskState.java @@ -60,7 +60,7 @@ public class OverviewModalTaskState extends OverviewState { } @Override - public void onBackPressed(Launcher launcher) { + public void onBackInvoked(Launcher launcher) { launcher.getStateManager().goToState(LauncherState.OVERVIEW); } diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java index 8c2efc2910..d0eef8e3bb 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java +++ b/quickstep/src/com/android/launcher3/uioverrides/states/OverviewState.java @@ -199,7 +199,7 @@ public class OverviewState extends LauncherState { } @Override - public void onBackPressed(Launcher launcher) { + public void onBackInvoked(Launcher launcher) { RecentsView recentsView = launcher.getOverviewPanel(); TaskView taskView = recentsView.getRunningTaskView(); if (taskView != null) { @@ -209,7 +209,7 @@ public class OverviewState extends LauncherState { recentsView.snapToPage(recentsView.indexOfChild(taskView)); } } else { - super.onBackPressed(launcher); + super.onBackInvoked(launcher); } } diff --git a/src/com/android/launcher3/Launcher.java b/src/com/android/launcher3/Launcher.java index e7d2843b64..cd3e146b9a 100644 --- a/src/com/android/launcher3/Launcher.java +++ b/src/com/android/launcher3/Launcher.java @@ -660,6 +660,11 @@ public class Launcher extends StatefulActivity // #5 state handler return new OnBackAnimationCallback() { + @Override + public void onBackStarted(BackEvent backEvent) { + Launcher.this.onBackStarted(); + } + @Override public void onBackInvoked() { onStateBack(); @@ -2063,8 +2068,12 @@ public class Launcher extends StatefulActivity getOnBackAnimationCallback().onBackInvoked(); } + protected void onBackStarted() { + mStateManager.getState().onBackStarted(this); + } + protected void onStateBack() { - mStateManager.getState().onBackPressed(this); + mStateManager.getState().onBackInvoked(this); } protected void onScreenOnChanged(boolean isOn) { diff --git a/src/com/android/launcher3/LauncherState.java b/src/com/android/launcher3/LauncherState.java index 6e66c1448d..3bdd8635cf 100644 --- a/src/com/android/launcher3/LauncherState.java +++ b/src/com/android/launcher3/LauncherState.java @@ -424,20 +424,29 @@ public abstract class LauncherState implements BaseState { return TestProtocol.stateOrdinalToString(ordinal); } - public void onBackPressed(Launcher launcher) { + /** Called when predictive back gesture is started. */ + public void onBackStarted(Launcher launcher) {} + + /** + * Called when back action is invoked. This can happen when: + * 1. back button is pressed in 3-button navigation. + * 2. when back is committed during back swiped (predictive or non-predictive). + * 3. when we programmatically perform back action. + */ + public void onBackInvoked(Launcher launcher) { if (this != NORMAL) { StateManager lsm = launcher.getStateManager(); LauncherState lastState = lsm.getLastState(); - lsm.goToState(lastState, forEndCallback(this::onBackPressCompleted)); + lsm.goToState(lastState, forEndCallback(this::onBackAnimationCompleted)); } } /** - * To be called if back press is completed in a launcher state. + * To be called if back animation is completed in a launcher state. * - * @param success whether back press animation was successful or canceled. + * @param success whether back animation was successful or canceled. */ - protected void onBackPressCompleted(boolean success) { + protected void onBackAnimationCompleted(boolean success) { // Do nothing. To be overridden by child class. } From 2165ad7b0eef8b345b5106dc89b84e13cf1f4142 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Fri, 22 Mar 2024 22:13:08 +0000 Subject: [PATCH 13/14] Revert "Log split button visibility to debug spacing issue" This reverts commit 2d55c9c6796788b40ac9381b5cdb5347f6c3f6d3. Reason for revert: Logs not helpful in figuring out the issue and is too spammy Bug: 321291049 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:a5d55fe5efad4db1678dfe7960f82df68b664b7d) Merged-In: I88a4350277ea3e965493da6386cf4c83c5c564e4 Change-Id: I88a4350277ea3e965493da6386cf4c83c5c564e4 --- .../quickstep/views/OverviewActionsView.java | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java index e0091a5ae2..b03b89f0b3 100644 --- a/quickstep/src/com/android/quickstep/views/OverviewActionsView.java +++ b/quickstep/src/com/android/quickstep/views/OverviewActionsView.java @@ -20,7 +20,6 @@ import android.content.Context; import android.content.res.Configuration; import android.graphics.Rect; import android.util.AttributeSet; -import android.util.Log; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; @@ -43,8 +42,6 @@ import com.android.quickstep.util.LayoutUtils; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; -import java.util.Arrays; -import java.util.stream.Collectors; /** * View for showing action buttons in Overview @@ -297,17 +294,6 @@ public class OverviewActionsView extends FrameLayo int desiredVisibility = mSplitButtonHiddenFlags == 0 ? VISIBLE : GONE; mSplitButton.setVisibility(desiredVisibility); findViewById(R.id.action_split_space).setVisibility(desiredVisibility); - - String callStack = Arrays.stream( - Log.getStackTraceString(new Exception("thread stacktrace")) - .split("\\n")) - .limit(5) - .skip(1) // Removes the line "java.lang.Exception: thread stacktrace" - .collect(Collectors.joining("\n")); - Log.d("b/321291049", "updateSplitButtonHiddenFlags called with flag: " + flag - + " enabled: " + enable - + " visibility: " + desiredVisibility - + " partial trace: \n" + callStack); } /** From 3c34c89cca88d4f438a41eba4a75b451a82a9129 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Wed, 27 Mar 2024 16:05:50 +0000 Subject: [PATCH 14/14] Align action_buttons at bottom of OverviewActionsView - http://ag/q/topic:%22b/329255757%22 caused a regression that in landscape, action_buttons shifted up when ShareTarget become visible, because OverviewActionsView become taller when this happens, and the topMargin is no longer valid to put actions_button at the position we want - Bring back layout_gravity="bottom" solves the issue, as bottomMarign is always correct Fix: 331517987 Test: manual as ShareTarget requires AiAi interaction and cannot easily be mocked Flag: None (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:6431d6e87910bc7c7767c40d42f51961dc462134) Merged-In: Iadcdf5731485f42f9586703e34e55ed9b4121bf9 Change-Id: Iadcdf5731485f42f9586703e34e55ed9b4121bf9 --- quickstep/res/layout/overview_actions_container.xml | 1 + 1 file changed, 1 insertion(+) diff --git a/quickstep/res/layout/overview_actions_container.xml b/quickstep/res/layout/overview_actions_container.xml index 758622b64b..5d489f5f34 100644 --- a/quickstep/res/layout/overview_actions_container.xml +++ b/quickstep/res/layout/overview_actions_container.xml @@ -23,6 +23,7 @@ android:id="@+id/action_buttons" android:layout_width="match_parent" android:layout_height="@dimen/overview_actions_height" + android:layout_gravity="bottom" android:gravity="center_horizontal" android:orientation="horizontal">