From db295670fdd17f749b77176daa70fac0e564877b Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Mon, 20 May 2024 17:26:41 -0700 Subject: [PATCH 01/14] Register input monitor for trackpad only when trackpad is attached Fixes: 335146977 Test: Use logging to make sure that input monitor isn't registered in 3 button mode when trackpad is not attached. When it's attached, it's registered upon attachment Change-Id: I89fc249546945b3adfc4c804eefd53808138168d --- .../quickstep/TouchInteractionService.java | 61 ++++++++++++++++++- .../android/quickstep/TaplTestsTrackpad.java | 8 +-- 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index 4599f180b1..b153396154 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -68,11 +68,13 @@ import android.content.IIntentSender; import android.content.Intent; import android.content.res.Configuration; import android.graphics.Region; +import android.hardware.input.InputManager; import android.os.Bundle; import android.os.IBinder; import android.os.Looper; import android.os.SystemClock; import android.os.Trace; +import android.util.ArraySet; import android.util.Log; import android.view.Choreographer; import android.view.InputDevice; @@ -146,6 +148,7 @@ import com.android.wm.shell.startingsurface.IStartingWindow; import java.io.FileDescriptor; import java.io.PrintWriter; import java.lang.ref.WeakReference; +import java.util.Set; import java.util.function.Consumer; import java.util.function.Function; @@ -453,6 +456,47 @@ public class TouchInteractionService extends Service { } } + private final InputManager.InputDeviceListener mInputDeviceListener = + new InputManager.InputDeviceListener() { + @Override + public void onInputDeviceAdded(int deviceId) { + if (isTrackpadDevice(deviceId)) { + boolean wasEmpty = mTrackpadsConnected.isEmpty(); + mTrackpadsConnected.add(deviceId); + if (wasEmpty) { + update(); + } + } + } + + @Override + public void onInputDeviceChanged(int deviceId) { + } + + @Override + public void onInputDeviceRemoved(int deviceId) { + mTrackpadsConnected.remove(deviceId); + if (mTrackpadsConnected.isEmpty()) { + update(); + } + } + + private void update() { + if (mInputMonitorCompat != null && !mTrackpadsConnected.isEmpty()) { + // Don't destroy and reinitialize input monitor due to trackpad + // connecting when it's already set up. + return; + } + initInputMonitor("onTrackpadConnected()"); + } + + private boolean isTrackpadDevice(int deviceId) { + InputDevice inputDevice = mInputManager.getInputDevice(deviceId); + return inputDevice.getSources() == (InputDevice.SOURCE_MOUSE + | InputDevice.SOURCE_TOUCHPAD); + } + }; + private static boolean sConnected = false; private static boolean sIsInitialized = false; private RotationTouchHelper mRotationTouchHelper; @@ -503,6 +547,8 @@ public class TouchInteractionService extends Service { private TaskbarManager mTaskbarManager; private Function mSwipeUpProxyProvider = i -> null; private AllAppsActionManager mAllAppsActionManager; + private InputManager mInputManager; + private final Set mTrackpadsConnected = new ArraySet<>(); @Override public void onCreate() { @@ -514,6 +560,15 @@ public class TouchInteractionService extends Service { mDeviceState = new RecentsAnimationDeviceState(this, true); mAllAppsActionManager = new AllAppsActionManager( this, UI_HELPER_EXECUTOR, this::createAllAppsPendingIntent); + mInputManager = getSystemService(InputManager.class); + if (ENABLE_TRACKPAD_GESTURE.get()) { + mInputManager.registerInputDeviceListener(mInputDeviceListener, + UI_HELPER_EXECUTOR.getHandler()); + int [] inputDevices = mInputManager.getInputDeviceIds(); + for (int inputDeviceId : inputDevices) { + mInputDeviceListener.onInputDeviceAdded(inputDeviceId); + } + } mTaskbarManager = new TaskbarManager(this, mAllAppsActionManager, mNavCallbacks); mRotationTouchHelper = mDeviceState.getRotationTouchHelper(); mInputConsumer = InputConsumerController.getRecentsAnimationInputConsumer(); @@ -542,7 +597,8 @@ public class TouchInteractionService extends Service { private void initInputMonitor(String reason) { disposeEventHandlers("Initializing input monitor due to: " + reason); - if (mDeviceState.isButtonNavMode() && !ENABLE_TRACKPAD_GESTURE.get()) { + if (mDeviceState.isButtonNavMode() && (!ENABLE_TRACKPAD_GESTURE.get() + || mTrackpadsConnected.isEmpty())) { return; } @@ -678,6 +734,9 @@ public class TouchInteractionService extends Service { mAllAppsActionManager.onDestroy(); + mInputManager.unregisterInputDeviceListener(mInputDeviceListener); + mTrackpadsConnected.clear(); + mTaskbarManager.destroy(); sConnected = false; diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsTrackpad.java b/quickstep/tests/src/com/android/quickstep/TaplTestsTrackpad.java index e4f8b6cd43..106e590e16 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsTrackpad.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsTrackpad.java @@ -54,7 +54,7 @@ public class TaplTestsTrackpad extends AbstractQuickStepTest { @Test @PortraitLandscape - @NavigationModeSwitch + @NavigationModeSwitch(mode = ZERO_BUTTON) public void goHome() throws Exception { assumeTrue(mLauncher.isTablet()); @@ -87,7 +87,7 @@ public class TaplTestsTrackpad extends AbstractQuickStepTest { @Test @PortraitLandscape - @NavigationModeSwitch + @NavigationModeSwitch(mode = ZERO_BUTTON) @ScreenRecordRule.ScreenRecord // b/336606166 @TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/336606166 public void switchToOverview() throws Exception { @@ -100,7 +100,7 @@ public class TaplTestsTrackpad extends AbstractQuickStepTest { @Test @PortraitLandscape - @NavigationModeSwitch + @NavigationModeSwitch(mode = ZERO_BUTTON) public void testAllAppsFromHome() throws Exception { assumeTrue(mLauncher.isTablet()); @@ -110,7 +110,7 @@ public class TaplTestsTrackpad extends AbstractQuickStepTest { } @Test - @NavigationModeSwitch + @NavigationModeSwitch(mode = ZERO_BUTTON) @PortraitLandscape public void testQuickSwitchFromHome() throws Exception { assumeTrue(mLauncher.isTablet()); From 350c29a5f657bf6ee82dc2c87bf94c8555604bdb Mon Sep 17 00:00:00 2001 From: Sihua Ma Date: Thu, 23 May 2024 22:03:42 +0000 Subject: [PATCH 02/14] Move SettingsActivityTest to multivalent Test: atest NexusLauncherRoboTests Test: SysUI studio Flag: None Test migration Bug: 297950111 Fix: 325089136 Change-Id: I85a2ed62453088941cb12fee9067acb076819dc5 --- tests/Android.bp | 3 +++ .../com/android/launcher3/settings/SettingsActivityTest.java | 0 2 files changed, 3 insertions(+) rename tests/{ => multivalentTests}/src/com/android/launcher3/settings/SettingsActivityTest.java (100%) diff --git a/tests/Android.bp b/tests/Android.bp index 5794cce8f5..adadf3c051 100644 --- a/tests/Android.bp +++ b/tests/Android.bp @@ -198,6 +198,9 @@ android_robolectric_test { "androidx.test.uiautomator_uiautomator", "androidx.core_core-animation-testing", "androidx.test.ext.junit", + "androidx.test.espresso.core", + "androidx.test.espresso.contrib", + "androidx.test.espresso.intents", "androidx.test.rules", "uiautomator-helpers", "inline-mockito-robolectric-prebuilt", diff --git a/tests/src/com/android/launcher3/settings/SettingsActivityTest.java b/tests/multivalentTests/src/com/android/launcher3/settings/SettingsActivityTest.java similarity index 100% rename from tests/src/com/android/launcher3/settings/SettingsActivityTest.java rename to tests/multivalentTests/src/com/android/launcher3/settings/SettingsActivityTest.java From 4304a14206805a99b63a0a0079c3907ad7f6893d Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Wed, 29 May 2024 06:39:57 +0000 Subject: [PATCH 03/14] Always report mandatory insets for button nav Fixes: 340134342 Test: atest android.systemui.cts.WindowInsetsBehaviorTests Change-Id: Iee9d5ca9f12ff63f856e7aa94227e5b8273e02a4 --- .../com/android/launcher3/taskbar/TaskbarInsetsController.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt index 4f511c1bfd..6869ecd539 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarInsetsController.kt @@ -223,7 +223,7 @@ class TaskbarInsetsController(val context: TaskbarActivityContext) : LoggableTas provider.insetsSize = getInsetsForGravityWithCutout(contentHeight, gravity, endRotation) } else if (provider.type == mandatorySystemGestures()) { if (context.isThreeButtonNav) { - provider.insetsSize = Insets.of(0, 0, 0, 0) + // Leave null to inset by the window frame } else { val gestureHeight = ResourceUtils.getNavbarSize( From 8e9da3c79c33aa027d438aaf9ec96ca4efcf18d0 Mon Sep 17 00:00:00 2001 From: Jordan Demeulenaere Date: Wed, 29 May 2024 16:36:46 +0200 Subject: [PATCH 04/14] Replace ktfmt.py hook by built-in hook in Launcher3/ This CL replaces the ktfmt.py hook of this repository by the builtin ktfmt hook. This will allow to delete our custom hook and provide features like automatic fixup (see http://screen/5uXuuPgs7oL83c2). Note that this also means that this CL is upgrading ktfmt from v0.43 to v0.49, so it is expected to see some minor formatting diffs on existing files after this CL is submitted. Bug: 342153000 Test: N/A Flag: NONE Repohook Update Change-Id: I66ae0443e6d5c45c771791b4182e610a20675815 --- PREUPLOAD.cfg | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg index 3d15e77853..ff97b22e4e 100644 --- a/PREUPLOAD.cfg +++ b/PREUPLOAD.cfg @@ -1,6 +1,13 @@ +[Builtin Hooks] +ktfmt = true + +[Builtin Hooks Options] +ktfmt = --kotlinlang-style + +[Tool Paths] +ktfmt = ${REPO_ROOT}/prebuilts/build-tools/common/framework/ktfmt.jar + [Hook Scripts] checkstyle_hook = ${REPO_ROOT}/prebuilts/checkstyle/checkstyle.py --config_xml tools/checkstyle.xml --sha ${PREUPLOAD_COMMIT} -ktfmt_hook = ${REPO_ROOT}/external/ktfmt/ktfmt.py --check ${PREUPLOAD_FILES} - flag_hook = ${REPO_ROOT}/frameworks/base/packages/SystemUI/flag_check.py --msg=${PREUPLOAD_COMMIT_MESSAGE} --files=${PREUPLOAD_FILES} --project=${REPO_PATH} From e081914fb1afc044e8ba3681b640ef57319ff990 Mon Sep 17 00:00:00 2001 From: Alex Chau Date: Tue, 28 May 2024 18:00:39 +0100 Subject: [PATCH 05/14] Fix DWB banner not showing up for split tasks - Remove DWB banner and thumbnailView from TaskView when being recycled to avoid multiple banners from staying - Extracted DWB toastg splitbounds update to not be called whenever task icon is loaded - Refactor DWB toast to remove unused variable, and extract mSplitBannerConfig to be a getter Fix: 343212887 Test: OverviewImageTest.digitalWellbeingToast Flag: EXEMPT bugfix Change-Id: I2dbdc483a7b99de009c9e2a946e1b026c5e4817f --- .../views/DigitalWellBeingToast.java | 125 +++++++++--------- .../quickstep/views/GroupedTaskView.kt | 5 + .../com/android/quickstep/views/TaskView.kt | 14 +- 3 files changed, 79 insertions(+), 65 deletions(-) diff --git a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java index a8ebe51b8a..cb1ee0c804 100644 --- a/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java +++ b/quickstep/src/com/android/quickstep/views/DigitalWellBeingToast.java @@ -74,7 +74,7 @@ public final class DigitalWellBeingToast { SPLIT_GRID_BANNER_SMALL, }) @Retention(RetentionPolicy.SOURCE) - @interface SPLIT_BANNER_CONFIG{} + @interface SplitBannerConfig{} static final Intent OPEN_APP_USAGE_SETTINGS_TEMPLATE = new Intent(ACTION_APP_USAGE_SETTINGS); static final int MINUTE_MS = 60000; @@ -88,7 +88,6 @@ public final class DigitalWellBeingToast { private Task mTask; private boolean mHasLimit; - private long mAppUsageLimitTimeMs; private long mAppRemainingTimeMs; @Nullable private View mBanner; @@ -96,10 +95,11 @@ public final class DigitalWellBeingToast { private float mBannerOffsetPercentage; @Nullable private SplitBounds mSplitBounds; - private int mSplitBannerConfig = SPLIT_BANNER_FULLSCREEN; private float mSplitOffsetTranslationY; private float mSplitOffsetTranslationX; + private boolean mIsDestroyed = false; + public DigitalWellBeingToast(RecentsViewContainer container, TaskView taskView) { mContainer = container; mTaskView = taskView; @@ -110,12 +110,10 @@ public final class DigitalWellBeingToast { mHasLimit = false; mTaskView.setContentDescription(mTask.titleDescription); replaceBanner(null); - mAppUsageLimitTimeMs = -1; mAppRemainingTimeMs = -1; } private void setLimit(long appUsageLimitTimeMs, long appRemainingTimeMs) { - mAppUsageLimitTimeMs = appUsageLimitTimeMs; mAppRemainingTimeMs = appRemainingTimeMs; mHasLimit = true; TextView toast = mContainer.getViewCache().getView(R.layout.digital_wellbeing_toast, @@ -138,89 +136,95 @@ public final class DigitalWellBeingToast { } public void initialize(Task task) { - mAppUsageLimitTimeMs = mAppRemainingTimeMs = -1; + if (mIsDestroyed) { + throw new IllegalStateException("Cannot re-initialize a destroyed toast"); + } mTask = task; ORDERED_BG_EXECUTOR.execute(() -> { - AppUsageLimit usageLimit = null; - try { - usageLimit = mLauncherApps.getAppUsageLimit( - mTask.getTopComponent().getPackageName(), - UserHandle.of(mTask.key.userId)); - } catch (Exception e) { - Log.e(TAG, "Error initializing digital well being toast", e); - } - final long appUsageLimitTimeMs = - usageLimit != null ? usageLimit.getTotalUsageLimit() : -1; - final long appRemainingTimeMs = - usageLimit != null ? usageLimit.getUsageRemaining() : -1; - - mTaskView.post(() -> { - if (appUsageLimitTimeMs < 0 || appRemainingTimeMs < 0) { - setNoLimit(); - } else { - setLimit(appUsageLimitTimeMs, appRemainingTimeMs); - } - }); + AppUsageLimit usageLimit = null; + try { + usageLimit = mLauncherApps.getAppUsageLimit( + mTask.getTopComponent().getPackageName(), + UserHandle.of(mTask.key.userId)); + } catch (Exception e) { + Log.e(TAG, "Error initializing digital well being toast", e); + } + final long appUsageLimitTimeMs = + usageLimit != null ? usageLimit.getTotalUsageLimit() : -1; + final long appRemainingTimeMs = + usageLimit != null ? usageLimit.getUsageRemaining() : -1; + mTaskView.post(() -> { + if (mIsDestroyed) { + return; } - ); + if (appUsageLimitTimeMs < 0 || appRemainingTimeMs < 0) { + setNoLimit(); + } else { + setLimit(appUsageLimitTimeMs, appRemainingTimeMs); + } + }); + }); } - public void setSplitConfiguration(SplitBounds splitBounds) { + /** + * Mark the DWB toast as destroyed and remove banner from TaskView. + */ + public void destroy() { + mIsDestroyed = true; + mTaskView.post(() -> replaceBanner(null)); + } + + public void setSplitBounds(@Nullable SplitBounds splitBounds) { mSplitBounds = splitBounds; + } + + private @SplitBannerConfig int getSplitBannerConfig() { if (mSplitBounds == null || !mContainer.getDeviceProfile().isTablet || mTaskView.isFocusedTask()) { - mSplitBannerConfig = SPLIT_BANNER_FULLSCREEN; - return; + return SPLIT_BANNER_FULLSCREEN; } // For portrait grid only height of task changes, not width. So we keep the text the same if (!mContainer.getDeviceProfile().isLeftRightSplit) { - mSplitBannerConfig = SPLIT_GRID_BANNER_LARGE; - return; + return SPLIT_GRID_BANNER_LARGE; } // For landscape grid, for 30% width we only show icon, otherwise show icon and time if (mTask.key.id == mSplitBounds.leftTopTaskId) { - mSplitBannerConfig = mSplitBounds.leftTaskPercent < THRESHOLD_LEFT_ICON_ONLY ? - SPLIT_GRID_BANNER_SMALL : SPLIT_GRID_BANNER_LARGE; + return mSplitBounds.leftTaskPercent < THRESHOLD_LEFT_ICON_ONLY + ? SPLIT_GRID_BANNER_SMALL : SPLIT_GRID_BANNER_LARGE; } else { - mSplitBannerConfig = mSplitBounds.leftTaskPercent > THRESHOLD_RIGHT_ICON_ONLY ? - SPLIT_GRID_BANNER_SMALL : SPLIT_GRID_BANNER_LARGE; + return mSplitBounds.leftTaskPercent > THRESHOLD_RIGHT_ICON_ONLY + ? SPLIT_GRID_BANNER_SMALL : SPLIT_GRID_BANNER_LARGE; } } private String getReadableDuration( Duration duration, - FormatWidth formatWidthHourAndMinute, - @StringRes int durationLessThanOneMinuteStringId, - boolean forceFormatWidth) { + @StringRes int durationLessThanOneMinuteStringId) { int hours = Math.toIntExact(duration.toHours()); int minutes = Math.toIntExact(duration.minusHours(hours).toMinutes()); - // Apply formatWidthHourAndMinute if both the hour part and the minute part are non-zero. + // Apply FormatWidth.WIDE if both the hour part and the minute part are non-zero. if (hours > 0 && minutes > 0) { - return MeasureFormat.getInstance(Locale.getDefault(), formatWidthHourAndMinute) + return MeasureFormat.getInstance(Locale.getDefault(), FormatWidth.NARROW) .formatMeasures( new Measure(hours, MeasureUnit.HOUR), new Measure(minutes, MeasureUnit.MINUTE)); } - // Apply formatWidthHourOrMinute if only the hour part is non-zero (unless forced). + // Apply FormatWidth.WIDE if only the hour part is non-zero (unless forced). if (hours > 0) { - return MeasureFormat.getInstance( - Locale.getDefault(), - forceFormatWidth ? formatWidthHourAndMinute : FormatWidth.WIDE) - .formatMeasures(new Measure(hours, MeasureUnit.HOUR)); + return MeasureFormat.getInstance(Locale.getDefault(), FormatWidth.WIDE).formatMeasures( + new Measure(hours, MeasureUnit.HOUR)); } - // Apply formatWidthHourOrMinute if only the minute part is non-zero (unless forced). + // Apply FormatWidth.WIDE if only the minute part is non-zero (unless forced). if (minutes > 0) { - return MeasureFormat.getInstance( - Locale.getDefault() - , forceFormatWidth ? formatWidthHourAndMinute : FormatWidth.WIDE) - .formatMeasures(new Measure(minutes, MeasureUnit.MINUTE)); + return MeasureFormat.getInstance(Locale.getDefault(), FormatWidth.WIDE).formatMeasures( + new Measure(minutes, MeasureUnit.MINUTE)); } // Use a specific string for usage less than one minute but non-zero. @@ -229,13 +233,12 @@ public final class DigitalWellBeingToast { } // Otherwise, return 0-minute string. - return MeasureFormat.getInstance( - Locale.getDefault(), forceFormatWidth ? formatWidthHourAndMinute : FormatWidth.WIDE) - .formatMeasures(new Measure(0, MeasureUnit.MINUTE)); + return MeasureFormat.getInstance(Locale.getDefault(), FormatWidth.WIDE).formatMeasures( + new Measure(0, MeasureUnit.MINUTE)); } /** - * Returns text to show for the banner depending on {@link #mSplitBannerConfig} + * Returns text to show for the banner depending on {@link #getSplitBannerConfig()} * If {@param forContentDesc} is {@code true}, this will always return the full * string corresponding to {@link #SPLIT_BANNER_FULLSCREEN} */ @@ -245,16 +248,16 @@ public final class DigitalWellBeingToast { (remainingTime + MINUTE_MS - 1) / MINUTE_MS * MINUTE_MS : remainingTime); String readableDuration = getReadableDuration(duration, - FormatWidth.NARROW, - R.string.shorter_duration_less_than_one_minute, - false /* forceFormatWidth */); - if (forContentDesc || mSplitBannerConfig == SPLIT_BANNER_FULLSCREEN) { + R.string.shorter_duration_less_than_one_minute + /* forceFormatWidth */); + @SplitBannerConfig int splitBannerConfig = getSplitBannerConfig(); + if (forContentDesc || splitBannerConfig == SPLIT_BANNER_FULLSCREEN) { return mContainer.asContext().getString( R.string.time_left_for_app, readableDuration); } - if (mSplitBannerConfig == SPLIT_GRID_BANNER_SMALL) { + if (splitBannerConfig == SPLIT_GRID_BANNER_SMALL) { // show no text return ""; } else { // SPLIT_GRID_BANNER_LARGE @@ -309,7 +312,7 @@ public final class DigitalWellBeingToast { private void setBanner(@Nullable View view) { mBanner = view; - if (view != null && mTaskView.getRecentsView() != null) { + if (mBanner != null && mTaskView.getRecentsView() != null) { setupAndAddBanner(); setBannerOutline(); } diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt index efbfa09420..d6a3376c53 100644 --- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt +++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.kt @@ -162,6 +162,7 @@ class GroupedTaskView @JvmOverloads constructor(context: Context, attrs: Attribu PreviewPositionHelper.STAGE_POSITION_BOTTOM_OR_RIGHT ) } + taskContainers.forEach { it.digitalWellBeingToast?.setSplitBounds(splitBoundsConfig) } setOrientationState(orientedState) } @@ -240,6 +241,10 @@ class GroupedTaskView @JvmOverloads constructor(context: Context, attrs: Attribu fun updateSplitBoundsConfig(splitBounds: SplitConfigurationOptions.SplitBounds?) { splitBoundsConfig = splitBounds + taskContainers.forEach { + it.digitalWellBeingToast?.setSplitBounds(splitBoundsConfig) + it.digitalWellBeingToast?.initialize(it.task) + } invalidate() } diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt index 4045ad7a91..71093af5dc 100644 --- a/quickstep/src/com/android/quickstep/views/TaskView.kt +++ b/quickstep/src/com/android/quickstep/views/TaskView.kt @@ -512,6 +512,7 @@ constructor( onTaskListVisibilityChanged(false) borderEnabled = false taskViewId = UNBOUND_TASK_VIEW_ID + taskContainers.forEach { it.destroy() } } // TODO: Clip-out the icon region from the thumbnail, since they are overlapping. @@ -801,12 +802,12 @@ constructor( taskContainers.forEach { if (visible) { recentsModel.iconCache - .updateIconInBackground(it.task) { thumbnailData -> - setIcon(it.iconView, thumbnailData.icon) + .updateIconInBackground(it.task) { task -> + setIcon(it.iconView, task.icon) if (enableOverviewIconMenu()) { - setText(it.iconView, thumbnailData.title) + setText(it.iconView, task.title) } - it.digitalWellBeingToast?.initialize(thumbnailData) + it.digitalWellBeingToast?.initialize(task) } ?.also { request -> pendingIconLoadRequests.add(request) } } else { @@ -1586,6 +1587,11 @@ constructor( val taskView: TaskView get() = this@TaskView + fun destroy() { + digitalWellBeingToast?.destroy() + thumbnailView?.let { taskView.removeView(it) } + } + // TODO(b/335649589): TaskView's VM will already have access to TaskThumbnailView's VM // so there will be no need to access TaskThumbnailView's VM through the TaskThumbnailView fun bindThumbnailView() { From 1abc4761cc0a40d6306e6688c32cd0db8ad58a0b Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Fri, 24 May 2024 16:48:14 -0700 Subject: [PATCH 06/14] Address jank and memory issues with OverviewActionsView Attempt to improve jank and memory regressions by simplifying the view layout of OverviewActionsView. Bug: 339688091 Bug: 339853741 Test: testSaveAppPairMenuItemOrActionExistsOnSplitPair() Flag: EXEMPT bugfix Change-Id: Ib4a7c5a813b221c0a083144e7fb1e1c5f3fedb1c --- .../res/layout/overview_actions_container.xml | 26 +++++++------------ .../res/layout/overview_actions_container.xml | 24 +++++++---------- .../quickstep/views/OverviewActionsView.java | 24 +++++++++-------- .../quickstep/TaplTestsSplitscreen.java | 2 -- .../android/launcher3/tapl/BaseOverview.java | 19 ++------------ .../launcher3/tapl/OverviewActions.java | 9 ------- 6 files changed, 33 insertions(+), 71 deletions(-) diff --git a/go/quickstep/res/layout/overview_actions_container.xml b/go/quickstep/res/layout/overview_actions_container.xml index b1a62022e9..e31f462562 100644 --- a/go/quickstep/res/layout/overview_actions_container.xml +++ b/go/quickstep/res/layout/overview_actions_container.xml @@ -124,23 +124,15 @@ - - -