From 16f2206f24b23342969cb1ecf32726b165695f3d Mon Sep 17 00:00:00 2001 From: Anushree Ganjam Date: Tue, 23 Jul 2024 15:20:19 -0700 Subject: [PATCH 1/9] Format dump logs so each of apps info prints in new line. Bug: 353510823 Test: Manual Flag: NONE BugFix Change-Id: Id5b0deca68e7af3c63422206db21ce3eba5b0f3a --- .../android/launcher3/appprediction/PredictionRowView.java | 5 ++++- .../launcher3/hybridhotseat/HotseatPredictionController.java | 5 ++++- 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java index a16031d804..92d9516836 100644 --- a/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java +++ b/quickstep/src/com/android/launcher3/appprediction/PredictionRowView.java @@ -290,6 +290,9 @@ public class PredictionRowView writer.println(prefix + "\tmPredictionsEnabled: " + mPredictionsEnabled); writer.println(prefix + "\tmPredictionUiUpdatePaused: " + mPredictionUiUpdatePaused); writer.println(prefix + "\tmNumPredictedAppsPerRow: " + mNumPredictedAppsPerRow); - writer.println(prefix + "\tmPredictedApps: " + mPredictedApps); + writer.println(prefix + "\tmPredictedApps: " + mPredictedApps.size()); + for (WorkspaceItemInfo info : mPredictedApps) { + writer.println(prefix + "\t\t" + info); + } } } diff --git a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java index de974ecae1..c50e82dd91 100644 --- a/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java +++ b/quickstep/src/com/android/launcher3/hybridhotseat/HotseatPredictionController.java @@ -536,6 +536,9 @@ public class HotseatPredictionController implements DragController.DragListener, writer.println(prefix + "HotseatPredictionController"); writer.println(prefix + "\tFlags: " + getStateString(mPauseFlags)); writer.println(prefix + "\tmHotSeatItemsCount: " + mHotSeatItemsCount); - writer.println(prefix + "\tmPredictedItems: " + mPredictedItems); + writer.println(prefix + "\tmPredictedItems: " + mPredictedItems.size()); + for (ItemInfo info : mPredictedItems) { + writer.println(prefix + "\t\t" + info); + } } } From 75ce1a2cd6a1d4a5bbb08f5ab821993032c47efe Mon Sep 17 00:00:00 2001 From: Andy Wickham Date: Wed, 17 Jul 2024 18:44:23 +0000 Subject: [PATCH 2/9] Move TestExtensions.kt to quickstep for DeviceConfig overrides. Fix: 353740808 Test: Run existing tests using this class Flag: TEST_ONLY Change-Id: Ie72fb86ea4d451e90a6629554dc717126db0b24c --- .../android/quickstep/util/TestExtensions.kt | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 quickstep/tests/multivalentTests/src/com/android/quickstep/util/TestExtensions.kt diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TestExtensions.kt b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TestExtensions.kt new file mode 100644 index 0000000000..6c526a4855 --- /dev/null +++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/util/TestExtensions.kt @@ -0,0 +1,65 @@ +/* + * 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.quickstep.util + +import com.android.launcher3.BuildConfig +import com.android.launcher3.util.SafeCloseable +import com.android.quickstep.DeviceConfigWrapper.Companion.configHelper +import com.android.quickstep.util.DeviceConfigHelper.Companion.prefs +import java.util.concurrent.CountDownLatch +import java.util.function.BooleanSupplier +import org.junit.Assert +import org.junit.Assume + +/** Helper methods for testing */ +object TestExtensions { + + @JvmStatic + fun overrideNavConfigFlag( + key: String, + value: Boolean, + targetValue: BooleanSupplier + ): AutoCloseable { + Assume.assumeTrue(BuildConfig.IS_DEBUG_DEVICE) + if (targetValue.asBoolean == value) { + return AutoCloseable {} + } + + navConfigEditWatcher().let { + prefs.edit().putBoolean(key, value).commit() + it.close() + } + Assert.assertEquals(value, targetValue.asBoolean) + + val watcher = navConfigEditWatcher() + return AutoCloseable { + prefs.edit().remove(key).commit() + watcher.close() + } + } + + private fun navConfigEditWatcher(): SafeCloseable { + val wait = CountDownLatch(1) + val listener = Runnable { wait.countDown() } + configHelper.addChangeListener(listener) + + return SafeCloseable { + wait.await() + configHelper.removeChangeListener(listener) + } + } +} From 71a69133b2e87fb3eaf3e0a27efceff15db0897c Mon Sep 17 00:00:00 2001 From: Saumya Prakash Date: Wed, 24 Jul 2024 18:34:05 +0000 Subject: [PATCH 3/9] Add aconfig feature flag for multi instance menu in Taskbar Test: Presubmit Fix: 355237285 Flag: com.android.launcher3.enable_multi_instance_menu_taskbar Change-Id: I049ebe3808223a9d7e96251c8cdb3134d9a9be28 --- aconfig/launcher.aconfig | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig index 21b98631aa..b3253d11d0 100644 --- a/aconfig/launcher.aconfig +++ b/aconfig/launcher.aconfig @@ -316,3 +316,10 @@ flag { description: "Archived apps will use new icon in app title" bug: "350758155" } + +flag { + name: "enable_multi_instance_menu_taskbar" + namespace: "launcher" + description: "Menu in Taskbar with options to launch and manage multiple instances of the same app" + bug: "355237285" +} \ No newline at end of file From da9520355f1d8b330ab006ef99b20c3ebd5f6c42 Mon Sep 17 00:00:00 2001 From: Brandon Dayauon Date: Wed, 17 Jul 2024 11:15:47 -0700 Subject: [PATCH 4/9] Don't let settings button clickable during animation. Otherwise the user will open settings instead of unlocking the container like normal. bug: 349115995 Test: before: https://drive.google.com/file/d/1jmd9Pxp6d0aGSC5Sp7efrlY6JLCPvKLR/view?usp=sharing after: https://drive.google.com/file/d/1xyKPd_hT9ut10r5B1PHxLO9gE3zh9vxK/view?usp=sharing Flag: com.android.launcher3.enable_private_space Change-Id: Icefaf7de72678ccf0b976039f4a3ee88c6712167 --- .../launcher3/allapps/PrivateProfileManager.java | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/com/android/launcher3/allapps/PrivateProfileManager.java b/src/com/android/launcher3/allapps/PrivateProfileManager.java index c1264d6135..904e973778 100644 --- a/src/com/android/launcher3/allapps/PrivateProfileManager.java +++ b/src/com/android/launcher3/allapps/PrivateProfileManager.java @@ -403,6 +403,7 @@ public class PrivateProfileManager extends UserProfileManager { mLockText.setHorizontallyScrolling(false); mPrivateSpaceSettingsButton.setVisibility( isPrivateSpaceSettingsAvailable() ? VISIBLE : GONE); + mPrivateSpaceSettingsButton.setClickable(isPrivateSpaceSettingsAvailable()); } lockPill.setVisibility(VISIBLE); lockPill.setOnClickListener(view -> lockingAction(/* lock */ true)); @@ -425,6 +426,7 @@ public class PrivateProfileManager extends UserProfileManager { lockPill.setContentDescription(mLockedStateContentDesc); mPrivateSpaceSettingsButton.setVisibility(GONE); + mPrivateSpaceSettingsButton.setClickable(false); transitionView.setVisibility(GONE); } case STATE_TRANSITION -> { @@ -794,6 +796,14 @@ public class PrivateProfileManager extends UserProfileManager { @Override public void onAnimationStart(Animator animator) { mPrivateSpaceSettingsButton.setVisibility(VISIBLE); + mPrivateSpaceSettingsButton.setClickable(false); + } + + @Override + public void onAnimationEnd(Animator animator) { + if (expand) { + mPrivateSpaceSettingsButton.setClickable(true); + } } }); return settingsAlphaAnim; From 058559e3dbf51b6c464adbde12d7156fe6e9d0b0 Mon Sep 17 00:00:00 2001 From: "Liam, Lee Pong Lam" Date: Wed, 26 Jun 2024 21:58:31 +0000 Subject: [PATCH 5/9] [Launcher3] Supports child Settings navigation on Search After adding all launcher settings to search, adding support for navigating to child settings if the setting isn't on the current screen. result: go/launcher-settings-navigate-to-child Bug: 293390881 Flag: com.android.launcher3.navigate_to_child_preference Test: Manual Change-Id: I5eecbf9a3c569f58b6c8830443d86ba122e4f53b --- aconfig/launcher.aconfig | 8 ++- .../launcher3/settings/SettingsActivity.java | 54 +++++++++++++++++++ 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig index b3253d11d0..a7796415e2 100644 --- a/aconfig/launcher.aconfig +++ b/aconfig/launcher.aconfig @@ -322,4 +322,10 @@ flag { namespace: "launcher" description: "Menu in Taskbar with options to launch and manage multiple instances of the same app" bug: "355237285" -} \ No newline at end of file +} +flag { + name: "navigate_to_child_preference" + namespace: "launcher" + description: "Settings screen supports navigating to child preference if the key is not on the screen" + bug: "293390881" +} diff --git a/src/com/android/launcher3/settings/SettingsActivity.java b/src/com/android/launcher3/settings/SettingsActivity.java index 52ce4e85a6..bd9298b99a 100644 --- a/src/com/android/launcher3/settings/SettingsActivity.java +++ b/src/com/android/launcher3/settings/SettingsActivity.java @@ -44,11 +44,13 @@ import androidx.preference.Preference; import androidx.preference.PreferenceFragmentCompat; import androidx.preference.PreferenceFragmentCompat.OnPreferenceStartFragmentCallback; import androidx.preference.PreferenceFragmentCompat.OnPreferenceStartScreenCallback; +import androidx.preference.PreferenceGroup; import androidx.preference.PreferenceGroup.PreferencePositionCallback; import androidx.preference.PreferenceScreen; import androidx.recyclerview.widget.RecyclerView; import com.android.launcher3.BuildConfig; +import com.android.launcher3.Flags; import com.android.launcher3.LauncherFiles; import com.android.launcher3.R; import com.android.launcher3.states.RotationHelper; @@ -165,6 +167,7 @@ public class SettingsActivity extends FragmentActivity private boolean mRestartOnResume = false; private String mHighLightKey; + private boolean mPreferenceHighlighted = false; @Override @@ -198,11 +201,62 @@ public class SettingsActivity extends FragmentActivity } } + // If the target preference is not in the current preference screen, find the parent + // preference screen that contains the target preference and set it as the preference + // screen. + if (Flags.navigateToChildPreference() + && mHighLightKey != null + && !isKeyInPreferenceGroup(mHighLightKey, screen)) { + final PreferenceScreen parentPreferenceScreen = + findParentPreference(screen, mHighLightKey); + if (parentPreferenceScreen != null && getActivity() != null) { + if (!TextUtils.isEmpty(parentPreferenceScreen.getTitle())) { + getActivity().setTitle(parentPreferenceScreen.getTitle()); + } + setPreferenceScreen(parentPreferenceScreen); + return; + } + } + if (getActivity() != null && !TextUtils.isEmpty(getPreferenceScreen().getTitle())) { getActivity().setTitle(getPreferenceScreen().getTitle()); } } + private boolean isKeyInPreferenceGroup(String targetKey, PreferenceGroup parent) { + for (int i = 0; i < parent.getPreferenceCount(); i++) { + Preference pref = parent.getPreference(i); + if (pref.getKey() != null && pref.getKey().equals(targetKey)) { + return true; + } + } + return false; + } + + /** + * Finds the parent preference screen for the given target key. + * + * @param parent the parent preference screen + * @param targetKey the key of the preference to find + * @return the parent preference screen that contains the target preference + */ + @Nullable + private PreferenceScreen findParentPreference(PreferenceScreen parent, String targetKey) { + for (int i = 0; i < parent.getPreferenceCount(); i++) { + Preference pref = parent.getPreference(i); + if (pref instanceof PreferenceScreen) { + PreferenceScreen foundKey = findParentPreference((PreferenceScreen) pref, + targetKey); + if (foundKey != null) { + return foundKey; + } + } else if (pref.getKey() != null && pref.getKey().equals(targetKey)) { + return parent; + } + } + return null; + } + @Override public void onViewCreated(View view, Bundle savedInstanceState) { super.onViewCreated(view, savedInstanceState); From 1fe2da0d5d4c3ee310c5b90e78c1f752a64aef8b Mon Sep 17 00:00:00 2001 From: Brandon Dayauon Date: Tue, 23 Jul 2024 13:56:03 -0700 Subject: [PATCH 6/9] Make settings/text alpha animation happen in parallelSet instead of when headerSetter starts. With the addition of floating mask views, settingsAlpha and textAlpha animation shouldn't be played in the beginning when animatorSet starts but more so during the parallel set. Otherwise, the text/settings alpha will start first before/same time as translationView. You can see this if you were to look at the video at the bottom of this commit message, specifically during the collapse case. bug:355042924 Test manually - before:https://drive.google.com/file/d/1BoCA5rlr9m3QDVfF5zfp9G12Ldst3kn0/view?usp=sharing after:https://drive.google.com/file/d/1y84uxmAfJ7_SNh26jT2O-m2xOFWCMkJm/view?usp=sharing Flag: com.android.launcher3.enable_private_space Change-Id: I98248f4b9aa2a4e1287183710ffdc66093cef022 --- .../launcher3/allapps/PrivateProfileManager.java | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/com/android/launcher3/allapps/PrivateProfileManager.java b/src/com/android/launcher3/allapps/PrivateProfileManager.java index c1264d6135..402f5808f8 100644 --- a/src/com/android/launcher3/allapps/PrivateProfileManager.java +++ b/src/com/android/launcher3/allapps/PrivateProfileManager.java @@ -660,10 +660,7 @@ public class PrivateProfileManager extends UserProfileManager { return; } attachFloatingMaskView(expand); - PropertySetter headerSetter = new AnimatedPropertySetter(); - headerSetter.add(updateSettingsGearAlpha(expand)); - headerSetter.add(updateLockTextAlpha(expand)); - AnimatorSet animatorSet = headerSetter.buildAnim(); + AnimatorSet animatorSet = new AnimatedPropertySetter().buildAnim(); animatorSet.addListener(new AnimatorListenerAdapter() { @Override public void onAnimationStart(Animator animation) { @@ -708,12 +705,16 @@ public class PrivateProfileManager extends UserProfileManager { } })); if (expand) { - animatorSet.playTogether(animateAlphaOfIcons(true), + animatorSet.playTogether(updateSettingsGearAlpha(true), + updateLockTextAlpha(true), + animateAlphaOfIcons(true), animatePillTransition(true), translateFloatingMaskView(false)); } else { AnimatorSet parallelSet = new AnimatorSet(); - parallelSet.playTogether(animateAlphaOfIcons(false), + parallelSet.playTogether(updateSettingsGearAlpha(false), + updateLockTextAlpha(false), + animateAlphaOfIcons(false), animatePillTransition(false)); if (isPrivateSpaceHidden()) { animatorSet.playSequentially(parallelSet, From a616e7976491984f88665e89d689b3e5546f89f4 Mon Sep 17 00:00:00 2001 From: Brandon Dayauon Date: Fri, 19 Jul 2024 09:56:00 -0700 Subject: [PATCH 7/9] Create floatingMaskViewTest and make FloatingMaskView testable. bug: 354209068 Test: presubmit locally Flag: NONE writing test for floatingmaskview Change-Id: I90cbed18a908279365af185330fb2dc1e747ebff --- .../launcher3/allapps/FloatingMaskView.java | 21 ++++-- .../launcher3/allapps/FloatingMaskViewTest.kt | 66 +++++++++++++++++++ 2 files changed, 81 insertions(+), 6 deletions(-) create mode 100644 tests/src/com/android/launcher3/allapps/FloatingMaskViewTest.kt diff --git a/src/com/android/launcher3/allapps/FloatingMaskView.java b/src/com/android/launcher3/allapps/FloatingMaskView.java index 606eb0328e..cee5e18958 100644 --- a/src/com/android/launcher3/allapps/FloatingMaskView.java +++ b/src/com/android/launcher3/allapps/FloatingMaskView.java @@ -21,6 +21,7 @@ import android.util.AttributeSet; import android.view.ViewGroup; import android.widget.ImageView; +import androidx.annotation.VisibleForTesting; import androidx.constraintlayout.widget.ConstraintLayout; import com.android.launcher3.R; @@ -53,13 +54,21 @@ public class FloatingMaskView extends ConstraintLayout { @Override protected void onLayout(boolean changed, int left, int top, int right, int bottom) { super.onLayout(changed, left, top, right, bottom); - ViewGroup.MarginLayoutParams lp = (ViewGroup.MarginLayoutParams) getLayoutParams(); - AllAppsRecyclerView allAppsContainerView = - mActivityContext.getAppsView().getActiveRecyclerView(); + setParameters((ViewGroup.MarginLayoutParams) getLayoutParams(), + mActivityContext.getAppsView().getActiveRecyclerView()); + } + + @VisibleForTesting + void setParameters(ViewGroup.MarginLayoutParams lp, AllAppsRecyclerView recyclerView) { if (lp != null) { - lp.rightMargin = allAppsContainerView.getPaddingRight(); - lp.leftMargin = allAppsContainerView.getPaddingLeft(); - mBottomBox.setMinimumHeight(allAppsContainerView.getPaddingBottom()); + lp.rightMargin = recyclerView.getPaddingRight(); + lp.leftMargin = recyclerView.getPaddingLeft(); + getBottomBox().setMinimumHeight(recyclerView.getPaddingBottom()); } } + + @VisibleForTesting + ImageView getBottomBox() { + return mBottomBox; + } } diff --git a/tests/src/com/android/launcher3/allapps/FloatingMaskViewTest.kt b/tests/src/com/android/launcher3/allapps/FloatingMaskViewTest.kt new file mode 100644 index 0000000000..cf03adcc5b --- /dev/null +++ b/tests/src/com/android/launcher3/allapps/FloatingMaskViewTest.kt @@ -0,0 +1,66 @@ +/* + * 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.allapps + +import android.content.Context +import android.view.ViewGroup +import android.view.ViewGroup.MarginLayoutParams +import android.widget.ImageView +import androidx.test.core.app.ApplicationProvider +import com.android.launcher3.util.ActivityContextWrapper +import com.google.common.truth.Truth +import org.junit.Before +import org.junit.Test +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.MockitoAnnotations + +class FloatingMaskViewTest { + @Mock + private val mockAllAppsRecyclerView: AllAppsRecyclerView? = null + + @Mock + private val mockBottomBox: ImageView? = null + private var mVut: FloatingMaskView? = null + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + val context: Context = ActivityContextWrapper(ApplicationProvider.getApplicationContext()) + mVut = FloatingMaskView(context) + mVut!!.layoutParams = MarginLayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, + ViewGroup.LayoutParams.WRAP_CONTENT) + } + + @Test + fun setParameters_paramsMarginEqualRecyclerViewPadding() { + val floatingMaskView = Mockito.spy(mVut) + Mockito.`when`(mockAllAppsRecyclerView!!.paddingLeft).thenReturn(PADDING_PX) + Mockito.`when`(mockAllAppsRecyclerView.paddingRight).thenReturn(PADDING_PX) + Mockito.`when`(mockAllAppsRecyclerView.paddingBottom).thenReturn(PADDING_PX) + Mockito.`when`(floatingMaskView!!.bottomBox).thenReturn(mockBottomBox) + val lp = floatingMaskView.layoutParams as MarginLayoutParams + + floatingMaskView.setParameters(lp, mockAllAppsRecyclerView) + + Truth.assertThat(lp.leftMargin).isEqualTo(PADDING_PX) + Truth.assertThat(lp.rightMargin).isEqualTo(PADDING_PX) + Mockito.verify(mockBottomBox)?.minimumHeight = PADDING_PX + } + + companion object { + private const val PADDING_PX = 15 + } +} From 310e4c8038c209e18567580861fa2b4f49b6dabd Mon Sep 17 00:00:00 2001 From: Jon Miranda Date: Thu, 25 Jul 2024 05:41:38 +0000 Subject: [PATCH 8/9] Fix NPE when activity launch options are created before taskbaer init Change-Id: Ibb8cf96ad4e528754aeb98ff0a702af2412e1052 Test: init Fixes: 355231499 Flag: com.android.launcher3.enable_scaling_reveal_home_animation --- .../launcher3/taskbar/LauncherTaskbarUIController.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java index 93a023dbdd..252ebf7d47 100644 --- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java +++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java @@ -272,6 +272,10 @@ public class LauncherTaskbarUIController extends TaskbarUIController { * app launch animation. */ public void setIgnoreInAppFlagForSync(boolean enabled) { + if (mControllers == null) { + // This method can be called before init() is called. + return; + } mControllers.taskbarStashController.updateStateForFlag(FLAG_IGNORE_IN_APP, enabled); } From 36ef7bf6e734add70aafe87d8f2f1c13edac1717 Mon Sep 17 00:00:00 2001 From: vinayjoglekar Date: Tue, 23 Jul 2024 17:17:01 +0100 Subject: [PATCH 9/9] Dim TaskThumbnailView on Foreground scrim Bug: 349601769 Test: TaskThumbnailViewModelTest Flag: com.android.launcher3.enable_refactor_task_thumbnail Change-Id: I3a9fa21d8a4c28ffe40279243030f0e47c957513 --- .../recents/viewmodel/RecentsViewData.kt | 3 +++ .../recents/viewmodel/RecentsViewModel.kt | 4 ++++ .../task/thumbnail/TaskThumbnailView.kt | 9 +------- .../task/viewmodel/TaskThumbnailViewModel.kt | 12 ++++++++++- .../android/quickstep/views/RecentsView.java | 5 ++++- .../thumbnail/TaskThumbnailViewModelTest.kt | 21 +++++++++++++++++++ 6 files changed, 44 insertions(+), 10 deletions(-) diff --git a/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewData.kt b/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewData.kt index fdb62dfb3e..0d38fb9655 100644 --- a/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewData.kt +++ b/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewData.kt @@ -31,4 +31,7 @@ class RecentsViewData { // The settled set of visible taskIds that is updated after RecentsView scroll settles. val settledFullyVisibleTaskIds = MutableStateFlow(emptySet()) + + // Color tint on foreground scrim + val tintAmount = MutableStateFlow(0f) } diff --git a/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewModel.kt b/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewModel.kt index 8b03a84362..edeca2d3f3 100644 --- a/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewModel.kt +++ b/quickstep/src/com/android/quickstep/recents/viewmodel/RecentsViewModel.kt @@ -45,4 +45,8 @@ class RecentsViewModel( fun setOverlayEnabled(isOverlayEnabled: Boolean) { recentsViewData.overlayEnabled.value = isOverlayEnabled } + + fun setTintAmount(tintAmount: Float) { + recentsViewData.tintAmount.value = tintAmount + } } diff --git a/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt b/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt index fcc2af36b4..8659734e7e 100644 --- a/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt +++ b/quickstep/src/com/android/quickstep/task/thumbnail/TaskThumbnailView.kt @@ -98,10 +98,7 @@ class TaskThumbnailView : FrameLayout, ViewPool.Reusable { } .launchIn(viewAttachedScope) viewModel.dimProgress - .onEach { dimProgress -> - // TODO(b/348195366) Add fade in/out for scrim - scrimView.alpha = dimProgress * MAX_SCRIM_ALPHA - } + .onEach { dimProgress -> scrimView.alpha = dimProgress } .launchIn(viewAttachedScope) viewModel.cornerRadiusProgress.onEach { invalidateOutline() }.launchIn(viewAttachedScope) viewModel.inheritedScale @@ -176,8 +173,4 @@ class TaskThumbnailView : FrameLayout, ViewPool.Reusable { overviewCornerRadius, fullscreenCornerRadius ) / inheritedScale - - private companion object { - const val MAX_SCRIM_ALPHA = 0.4f - } } diff --git a/quickstep/src/com/android/quickstep/task/viewmodel/TaskThumbnailViewModel.kt b/quickstep/src/com/android/quickstep/task/viewmodel/TaskThumbnailViewModel.kt index 64656452e7..0753bb9d04 100644 --- a/quickstep/src/com/android/quickstep/task/viewmodel/TaskThumbnailViewModel.kt +++ b/quickstep/src/com/android/quickstep/task/viewmodel/TaskThumbnailViewModel.kt @@ -30,6 +30,7 @@ import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.LiveTile import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Snapshot import com.android.quickstep.task.thumbnail.TaskThumbnailUiState.Uninitialized import com.android.systemui.shared.recents.model.Task +import kotlin.math.max import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.MutableStateFlow @@ -63,7 +64,12 @@ class TaskThumbnailViewModel( combine(recentsViewData.scale, taskViewData.scale) { recentsScale, taskScale -> recentsScale * taskScale } - val dimProgress: Flow = taskContainerData.taskMenuOpenProgress + val dimProgress: Flow = + combine(taskContainerData.taskMenuOpenProgress, recentsViewData.tintAmount) { + taskMenuOpenProgress, + tintAmount -> + max(taskMenuOpenProgress * MAX_SCRIM_ALPHA, tintAmount) + } val uiState: Flow = task .flatMapLatest { taskFlow -> @@ -110,4 +116,8 @@ class TaskThumbnailViewModel( } @ColorInt private fun Int.removeAlpha(): Int = ColorUtils.setAlphaComponent(this, 0xff) + + private companion object { + const val MAX_SCRIM_ALPHA = 0.4f + } } diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index d63ac56691..46f6feb0d4 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -6116,7 +6116,6 @@ public abstract class RecentsView