From 531fc4985bd01e6ee103a2c3753ee841ffb2da24 Mon Sep 17 00:00:00 2001 From: Will Leshner Date: Fri, 1 Dec 2023 15:34:59 -0800 Subject: [PATCH 001/577] Handle widget taps in WidgetPickerActivity. Bug: 307306823 Test: atest Launcher3Tests Flag: NA Change-Id: I05cd42eae91447cfe99165096a735f6e04257203 --- .../launcher3/WidgetPickerActivity.java | 21 +++++++++++++++++++ .../android/launcher3/widget/WidgetCell.java | 5 +++++ 2 files changed, 26 insertions(+) diff --git a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java index 43716abd97..477cd84444 100644 --- a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java +++ b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java @@ -22,7 +22,10 @@ import static android.view.WindowInsets.Type.statusBars; import static com.android.launcher3.util.Executors.MAIN_EXECUTOR; import static com.android.launcher3.util.Executors.MODEL_EXECUTOR; +import android.appwidget.AppWidgetProviderInfo; +import android.content.Intent; import android.os.Bundle; +import android.view.View; import android.view.WindowInsetsController; import android.view.WindowManager; @@ -32,6 +35,7 @@ import com.android.launcher3.dragndrop.SimpleDragLayer; import com.android.launcher3.model.WidgetsModel; import com.android.launcher3.popup.PopupDataProvider; import com.android.launcher3.widget.BaseWidgetSheet; +import com.android.launcher3.widget.WidgetCell; import com.android.launcher3.widget.model.WidgetsListBaseEntry; import com.android.launcher3.widget.picker.WidgetsFullSheet; @@ -81,6 +85,23 @@ public class WidgetPickerActivity extends BaseActivity { return mDragLayer; } + @Override + public View.OnClickListener getItemOnClickListener() { + return v -> { + final AppWidgetProviderInfo info = + (v instanceof WidgetCell) ? ((WidgetCell) v).getWidgetItem().widgetInfo : null; + if (info == null || info.provider == null) { + return; + } + + setResult(RESULT_OK, new Intent() + .putExtra(Intent.EXTRA_COMPONENT_NAME, info.provider) + .putExtra(Intent.EXTRA_USER, info.getProfile())); + + finish(); + }; + } + private void refreshAndBindWidgets() { MODEL_EXECUTOR.execute(() -> { LauncherAppState app = LauncherAppState.getInstance(this); diff --git a/src/com/android/launcher3/widget/WidgetCell.java b/src/com/android/launcher3/widget/WidgetCell.java index c30342ad4b..8f5e2b66e1 100644 --- a/src/com/android/launcher3/widget/WidgetCell.java +++ b/src/com/android/launcher3/widget/WidgetCell.java @@ -147,6 +147,11 @@ public class WidgetCell extends LinearLayout { return mAppWidgetHostViewScale; } + /** Returns the {@link WidgetItem} for this {@link WidgetCell}. */ + public WidgetItem getWidgetItem() { + return mItem; + } + /** * Called to clear the view and free attached resources. (e.g., {@link Bitmap} */ -- GitLab From cefdb2859930d20b624cac5400d49788a076078e Mon Sep 17 00:00:00 2001 From: Sebastian Franco Date: Tue, 12 Dec 2023 15:21:49 -0600 Subject: [PATCH 002/577] Remove ENABLE_NO_LONG_PRESS_DRAG flag. Fix: 299748096 Flag: LEGACY ENABLE_NO_LONG_PRESS_DRAG ENABLED Test: atest TaplDragTest Change-Id: I6f14f2b048e111912fa0d1b8170ca702705e00bc --- src/com/android/launcher3/config/FeatureFlags.java | 4 ---- src/com/android/launcher3/dragndrop/DragController.java | 3 +-- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 2f62840679..65269d4920 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -201,10 +201,6 @@ public final class FeatureFlags { "ENABLE_PARAMETRIZE_REORDER", DISABLED, "Enables generating the reorder using a set of parameters"); - public static final BooleanFlag ENABLE_NO_LONG_PRESS_DRAG = getDebugFlag(299748096, - "ENABLE_NO_LONG_PRESS_DRAG", ENABLED, - "Don't trigger the drag if we are still under long press"); - // TODO(Block 12): Clean up flags public static final BooleanFlag ENABLE_MULTI_INSTANCE = getDebugFlag(270396680, "ENABLE_MULTI_INSTANCE", DISABLED, diff --git a/src/com/android/launcher3/dragndrop/DragController.java b/src/com/android/launcher3/dragndrop/DragController.java index 777f4d5686..aa5329b8d7 100644 --- a/src/com/android/launcher3/dragndrop/DragController.java +++ b/src/com/android/launcher3/dragndrop/DragController.java @@ -17,7 +17,6 @@ package com.android.launcher3.dragndrop; import static com.android.launcher3.Utilities.ATLEAST_Q; -import static com.android.launcher3.config.FeatureFlags.ENABLE_NO_LONG_PRESS_DRAG; import android.graphics.Point; import android.graphics.Rect; @@ -464,7 +463,7 @@ public abstract class DragController private DropTarget checkTouchMove(final int x, final int y) { // If we are in predrag, don't trigger any other event until we get out of it - if (ENABLE_NO_LONG_PRESS_DRAG.get() && mIsInPreDrag) { + if (mIsInPreDrag) { return mLastDropTarget; } DropTarget dropTarget = findDropTarget(x, y); -- GitLab From d757e0c978c1461744016c0c06cfe08dd298c831 Mon Sep 17 00:00:00 2001 From: Vadim Tryshev Date: Tue, 12 Dec 2023 16:30:00 -0800 Subject: [PATCH 003/577] Waiting for Fallback Overview to stop after pressing Home Bug: 313926097 Flag: N/A Test: presubmit Change-Id: Ibbd7faad1f67e2013e3a1d4d9abcc3306729cbc0 --- .../src/com/android/quickstep/FallbackRecentsTest.java | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java index eced5a9a41..00bf587e21 100644 --- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java +++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java @@ -218,10 +218,17 @@ public class FallbackRecentsTest { } private BaseOverview pressHomeAndGoToOverview() { - mDevice.pressHome(); + pressHomeAndWaitForOverviewClose(); return mLauncher.getLaunchedAppState().switchToOverview(); } + private void pressHomeAndWaitForOverviewClose() { + mDevice.pressHome(); + Wait.atMost("Recents activity didn't stop", + () -> getFromRecents(recents -> !recents.isStarted()), + DEFAULT_UI_TIMEOUT, mLauncher); + } + // b/143488140 //@NavigationModeSwitch @Test -- GitLab From fb3ae6a6c4580c8beed284617ad4395d1d8da01c Mon Sep 17 00:00:00 2001 From: Vadim Tryshev Date: Wed, 13 Dec 2023 11:37:17 -0800 Subject: [PATCH 004/577] Converting more pressBack calls to calls that wait for animation Bug: 313926097 Flag: N/A Test: presubmit Change-Id: Ib4e08b4778a24ac617ea1e0101147612b0f53967 --- .../com/android/quickstep/TaplTestsQuickstep.java | 7 ++----- .../launcher3/allapps/TaplOpenCloseAllApps.java | 3 +-- .../com/android/launcher3/tapl/LaunchedAppState.java | 12 ++++++++---- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java index 6cbe1712e0..25adb62d2f 100644 --- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java +++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java @@ -358,14 +358,11 @@ public class TaplTestsQuickstep extends AbstractQuickStepTest { // Debug if we need to goHome to prevent wrong previous state b/315525621 mLauncher.goHome(); assumeFalse(FeatureFlags.ENABLE_BACK_SWIPE_LAUNCHER_ANIMATION.get()); - mLauncher.getWorkspace().switchToAllApps(); - mLauncher.pressBack(); - mLauncher.getWorkspace(); + mLauncher.getWorkspace().switchToAllApps().pressBackToWorkspace(); waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL); startAppFast(CALCULATOR_APP_PACKAGE); - mLauncher.pressBack(); - mLauncher.getWorkspace(); + mLauncher.getLaunchedAppState().pressBackToWorkspace(); waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL); } diff --git a/tests/src/com/android/launcher3/allapps/TaplOpenCloseAllApps.java b/tests/src/com/android/launcher3/allapps/TaplOpenCloseAllApps.java index b4a5169c30..4f10287d40 100644 --- a/tests/src/com/android/launcher3/allapps/TaplOpenCloseAllApps.java +++ b/tests/src/com/android/launcher3/allapps/TaplOpenCloseAllApps.java @@ -214,8 +214,7 @@ public class TaplOpenCloseAllApps extends AbstractLauncherUiTest { .pressBackToWorkspace(); waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL); startAppFast(resolveSystemApp(Intent.CATEGORY_APP_CALCULATOR)); - mLauncher.pressBack(); - mLauncher.getWorkspace(); + mLauncher.getLaunchedAppState().pressBackToWorkspace(); waitForState("Launcher internal state didn't switch to Home", () -> LauncherState.NORMAL); } diff --git a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java index 184ece74f5..501c4c34d7 100644 --- a/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java +++ b/tests/tapl/com/android/launcher3/tapl/LaunchedAppState.java @@ -346,10 +346,14 @@ public final class LaunchedAppState extends Background { try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck(); LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "want to press back from launched app to workspace")) { - mLauncher.executeAndWaitForWallpaperAnimation( - () -> mLauncher.pressBackImpl(), - "pressing back" - ); + if (mLauncher.isLauncher3()) { + mLauncher.pressBackImpl(); + } else { + mLauncher.executeAndWaitForWallpaperAnimation( + () -> mLauncher.pressBackImpl(), + "pressing back" + ); + } return new Workspace(mLauncher); } } -- GitLab From 7a65495beff35934e4486d235a6418a4e7b4b30b Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 13 Dec 2023 15:10:28 -0800 Subject: [PATCH 005/577] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ic31a5d47d4eb0cc6d6d08ef09e4289eca31ae180 --- quickstep/res/values-es/strings.xml | 2 +- quickstep/res/values-fa/strings.xml | 2 +- quickstep/res/values-fr/strings.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml index bb2f5335d2..893b1c8aa7 100644 --- a/quickstep/res/values-es/strings.xml +++ b/quickstep/res/values-es/strings.xml @@ -86,7 +86,7 @@ "¡Muy bien!" "Tutorial %1$d/%2$d" "¡Ya está!" - "Desliza el dedo hacia arriba para ir a la pantalla de inicio" + "Desliza hacia arriba para ir a la pantalla de inicio" "Toca el botón de inicio para ir a la pantalla de inicio" "Ya puedes empezar a usar tu %1$s" "dispositivo" diff --git a/quickstep/res/values-fa/strings.xml b/quickstep/res/values-fa/strings.xml index c8da620e86..91e4ad5558 100644 --- a/quickstep/res/values-fa/strings.xml +++ b/quickstep/res/values-fa/strings.xml @@ -109,7 +109,7 @@ "برای استفاده هم‌زمان از ۲ برنامه، یک برنامه را به کناری بکشید" "برای نمایش «نوار وظیفه»، انگشتتان را آهسته به‌بالا بکشید" "براساس روال‌هایتان، پیشنهاد برنامه دریافت کنید" - "برای سنجاق کردن «نوار وظیفه»، جداکننده را چند ثانیه فشار دهید" + "جداکننده را چند ثانیه فشار دهید تا «نوار وظیفه» سنجاق شود" "با «نوار وظیفه» می‌توانید کارهای بیشتر انجام دهید" "بستن" "تمام" diff --git a/quickstep/res/values-fr/strings.xml b/quickstep/res/values-fr/strings.xml index df6cad48dd..789ef13f7d 100644 --- a/quickstep/res/values-fr/strings.xml +++ b/quickstep/res/values-fr/strings.xml @@ -109,7 +109,7 @@ "Faites glisser une appli sur le côté pour en utiliser 2 à la fois" "Balayez lentement vers haut pour afficher barre des tâches" "Obtenez des suggestions d\'applis basées sur vos habitudes" - "Appui de manière prolongée sur le séparateur pour épingler la barre des tâches" + "Appui prolongé sur le séparateur pour épingler la barre des tâches" "Faites-en plus avec la barre des tâches" "Fermer" "OK" -- GitLab From e70a1cae2edad017748f97db428554bb2c1aeb37 Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 13 Dec 2023 15:10:54 -0800 Subject: [PATCH 006/577] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Ic9fd0692331857c52c909e8c7abbe9b015a96bda --- quickstep/res/values-es/strings.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/quickstep/res/values-es/strings.xml b/quickstep/res/values-es/strings.xml index d40780c59f..4c31d8738b 100644 --- a/quickstep/res/values-es/strings.xml +++ b/quickstep/res/values-es/strings.xml @@ -86,7 +86,7 @@ "¡Muy bien!" "Tutorial %1$d/%2$d" "¡Ya está!" - "Desliza el dedo hacia arriba para ir a la pantalla de inicio" + "Desliza hacia arriba para ir a la pantalla de inicio" "Toca el botón de inicio para ir a la pantalla de inicio" "Ya puedes empezar a usar tu %1$s" "dispositivo" -- GitLab From 7c68b61e09b055618266594d9bc2fed66e97e59b Mon Sep 17 00:00:00 2001 From: Bill Yi Date: Wed, 13 Dec 2023 15:11:53 -0800 Subject: [PATCH 007/577] Import translations. DO NOT MERGE ANYWHERE Auto-generated-cl: translation import Change-Id: Idd965f2d99f1a2d07b0844424d6d300a2302d8d4 --- res/values-da/strings.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/res/values-da/strings.xml b/res/values-da/strings.xml index 9d5a55fa46..415d1f39a2 100644 --- a/res/values-da/strings.xml +++ b/res/values-da/strings.xml @@ -173,10 +173,10 @@ "Genoptag" "Filter" "Mislykket: %1$s" - "Privat rum" + "Privat område" "Privat" "Indstillinger for privat rum" - "Lås/oplås det private rum" - "Ændringer af tilstanden for det private rum" + "Lås/oplås det private område" + "Ændringer af tilstanden for det private område" "Overløb" -- GitLab From 939ca48baec8c419683b0baeb741f3aae271762d Mon Sep 17 00:00:00 2001 From: Fengjiang Li Date: Thu, 7 Dec 2023 12:31:56 -0800 Subject: [PATCH 008/577] Cancel all apps icons preinflation when device profile has changed Bug: 312816372 Test: perinflate large number of App Icons then rotate screen. Verified 1) preinflation runnable is cancelled and 2) no ViewHolder created from this cancelled runnable is added to RecyclerViewPool Flag: LEGACY ENABLE_ALL_APPS_RV_PREINFLATION ENABLED Change-Id: I1a6110278e1af2b32387ab27273106d30513886f --- .../recyclerview/AllAppsRecyclerViewPool.kt | 42 +++++--- .../launcher3/util/ExecutorRunnable.kt | 78 ++++++++++++++ .../launcher3/util/ExecutorRunnableTest.kt | 101 ++++++++++++++++++ 3 files changed, 208 insertions(+), 13 deletions(-) create mode 100644 src/com/android/launcher3/util/ExecutorRunnable.kt create mode 100644 tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt diff --git a/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt b/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt index 45174a7095..cbc6f4434e 100644 --- a/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt +++ b/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt @@ -23,10 +23,10 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder import com.android.launcher3.BubbleTextView import com.android.launcher3.allapps.BaseAllAppsAdapter import com.android.launcher3.config.FeatureFlags +import com.android.launcher3.util.ExecutorRunnable import com.android.launcher3.util.Executors.MAIN_EXECUTOR import com.android.launcher3.util.Executors.VIEW_PREINFLATION_EXECUTOR import com.android.launcher3.views.ActivityContext -import java.util.concurrent.Future const val PREINFLATE_ICONS_ROW_COUNT = 4 const val EXTRA_ICONS_COUNT = 2 @@ -38,9 +38,8 @@ const val EXTRA_ICONS_COUNT = 2 */ class AllAppsRecyclerViewPool : RecycledViewPool() { - private var future: Future? = null - var hasWorkProfile = false + var executorRunnable: ExecutorRunnable>? = null /** * Preinflate app icons. If all apps RV cannot be scrolled down, we don't need to preinflate. @@ -63,21 +62,38 @@ class AllAppsRecyclerViewPool : RecycledViewPool() { override fun getLayoutManager(): RecyclerView.LayoutManager? = null } - // Inflate view holders on background thread, and added to view pool on main thread. - future?.cancel(true) - future = - VIEW_PREINFLATION_EXECUTOR.submit { - val viewHolders = - Array(preInflateCount) { - adapter.createViewHolder(activeRv, BaseAllAppsAdapter.VIEW_TYPE_ICON) + executorRunnable?.cancel(/* interrupt= */ true) + executorRunnable = + ExecutorRunnable.createAndExecute( + VIEW_PREINFLATION_EXECUTOR, + { + val list: ArrayList = ArrayList() + for (i in 0 until preInflateCount) { + if (Thread.interrupted()) { + break + } + list.add( + adapter.createViewHolder(activeRv, BaseAllAppsAdapter.VIEW_TYPE_ICON) + ) } - MAIN_EXECUTOR.execute { + list + }, + MAIN_EXECUTOR, + { viewHolders -> for (i in 0 until minOf(viewHolders.size, getPreinflateCount(context))) { putRecycledView(viewHolders[i]) } } - null - } + ) + } + + /** + * When clearing [RecycledViewPool], we should also abort pre-inflation tasks. This will make + * sure we don't inflate app icons after DeviceProfile has changed. + */ + override fun clear() { + super.clear() + executorRunnable?.cancel(/* interrupt= */ true) } /** diff --git a/src/com/android/launcher3/util/ExecutorRunnable.kt b/src/com/android/launcher3/util/ExecutorRunnable.kt new file mode 100644 index 0000000000..49cf5925b8 --- /dev/null +++ b/src/com/android/launcher3/util/ExecutorRunnable.kt @@ -0,0 +1,78 @@ +/* + * 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.util + +import java.util.concurrent.Executor +import java.util.concurrent.ExecutorService +import java.util.concurrent.Future +import java.util.function.Consumer +import java.util.function.Supplier + +/** A [Runnable] that can be posted to a [Executor] that can be cancelled. */ +class ExecutorRunnable +private constructor( + private val task: Supplier, + // Executor where consumer needs to be executed on. Typically UI executor. + private val callbackExecutor: Executor, + // Consumer that needs to be accepted upon completion of the task. Typically work that needs to + // be done in UI thread after task completes. + private val callback: Consumer +) : Runnable { + + // future of this runnable that will used for cancellation. + lateinit var future: Future<*> + + // flag to cancel the callback + var canceled = false + + override fun run() { + val value: T = task.get() + callbackExecutor.execute { + if (!canceled) { + callback.accept(value) + } + } + } + + /** + * Cancel the [ExecutorRunnable] if not scheduled. If [ExecutorRunnable] has started execution + * at this time, we will try to cancel the callback if not executed yet. + */ + fun cancel(interrupt: Boolean) { + future.cancel(interrupt) + canceled = true + } + + companion object { + /** + * Create [ExecutorRunnable] and execute it on task [Executor]. It will also save the + * [Future] into this [ExecutorRunnable] to be used for cancellation. + */ + fun createAndExecute( + // Executor where task will be executed, typically an Executor running on background + // thread. + taskExecutor: ExecutorService, + task: Supplier, + callbackExecutor: Executor, + callback: Consumer + ): ExecutorRunnable { + val executorRunnable = ExecutorRunnable(task, callbackExecutor, callback) + executorRunnable.future = taskExecutor.submit(executorRunnable) + return executorRunnable + } + } +} diff --git a/tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt b/tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt new file mode 100644 index 0000000000..b4591baa17 --- /dev/null +++ b/tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt @@ -0,0 +1,101 @@ +/* + * 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.util + +import android.testing.AndroidTestingRunner +import androidx.test.filters.SmallTest +import java.util.concurrent.ExecutorService +import junit.framework.Assert.assertEquals +import junit.framework.Assert.assertFalse +import junit.framework.Assert.assertTrue +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith + +/** Unit test for [ExecutorRunnable] */ +@SmallTest +@RunWith(AndroidTestingRunner::class) +class ExecutorRunnableTest { + + private lateinit var underTest: ExecutorRunnable + + private var result: Int = -1 + private var isTaskExecuted = false + private var isCallbackExecuted = false + + @Before + fun setup() { + reset() + underTest = + ExecutorRunnable.createAndExecute( + Executors.UI_HELPER_EXECUTOR, + { + isTaskExecuted = true + 1 + }, + Executors.VIEW_PREINFLATION_EXECUTOR, + { + isCallbackExecuted = true + result = it + 1 + } + ) + } + + @Test + fun run_and_complete() { + awaitAllExecutorCompleted() + + assertTrue(isTaskExecuted) + assertTrue(isCallbackExecuted) + assertEquals(2, result) + } + + @Test + fun run_and_cancel_cancelCallback() { + underTest.cancel(true) + awaitAllExecutorCompleted() + + assertFalse(isCallbackExecuted) + assertEquals(0, result) + } + + @Test + fun run_and_cancelAfterCompletion_executeAll() { + awaitAllExecutorCompleted() + + underTest.cancel(true) + + assertTrue(isTaskExecuted) + assertTrue(isCallbackExecuted) + assertEquals(2, result) + } + + private fun awaitExecutorCompleted(executor: ExecutorService) { + executor.submit { null }.get() + } + + private fun awaitAllExecutorCompleted() { + awaitExecutorCompleted(Executors.UI_HELPER_EXECUTOR) + awaitExecutorCompleted(Executors.VIEW_PREINFLATION_EXECUTOR) + } + + private fun reset() { + result = 0 + isTaskExecuted = false + isCallbackExecuted = false + } +} -- GitLab From b8a71816e125594beac02947abc72ecd7b9d6f32 Mon Sep 17 00:00:00 2001 From: Anushree Ganjam Date: Wed, 13 Dec 2023 15:18:37 -0800 Subject: [PATCH 009/577] [Refactor] Use constants from Cuj.java instead of InteractionJankMonitorWrapper. Bug: 303105164 Test: Manual Flag: NA Change-Id: I05a36fc0421502cd472dd79035b73a69d05592d2 --- .../launcher3/QuickstepTransitionManager.java | 13 +++++---- .../NoButtonQuickSwitchTouchController.java | 11 ++++---- .../PortraitStatesTouchController.java | 27 ++++++++----------- .../android/quickstep/AbsSwipeUpHandler.java | 18 ++++++------- .../quickstep/OverviewCommandHelper.java | 3 ++- .../quickstep/RecentsAnimationController.java | 10 +++---- .../com/android/quickstep/TaskViewUtils.java | 4 +-- .../logging/StatsLogCompatManager.java | 6 ++--- .../util/SplitToWorkspaceController.java | 4 +-- .../util/SwipePipToHomeAnimator.java | 9 +++---- ...erJankMonitorTransitionProgressListener.kt | 5 ++-- .../quickstep/views/GroupedTaskView.java | 8 +++--- .../android/quickstep/views/RecentsView.java | 23 +++++++--------- 13 files changed, 65 insertions(+), 76 deletions(-) diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java index 4898761736..f25b652d0c 100644 --- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java +++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java @@ -64,8 +64,6 @@ import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATI import static com.android.launcher3.views.FloatingIconView.getFloatingIconView; import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS; import static com.android.quickstep.TaskViewUtils.findTaskViewToLaunch; -import static com.android.systemui.shared.system.InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME; -import static com.android.systemui.shared.system.InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME_FALLBACK; import static com.android.systemui.shared.system.QuickStepContract.getWindowCornerRadius; import static com.android.systemui.shared.system.QuickStepContract.supportsRoundedCornersOnWindows; @@ -117,6 +115,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.core.graphics.ColorUtils; +import com.android.internal.jank.Cuj; import com.android.launcher3.DeviceProfile.OnDeviceProfileChangeListener; import com.android.launcher3.LauncherAnimationRunner.RemoteAnimationFactory; import com.android.launcher3.anim.AnimationSuccessListener; @@ -1652,7 +1651,8 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener // is initialized. if (launcherIsForceInvisibleOrOpening) { addCujInstrumentation(anim, playFallBackAnimation - ? CUJ_APP_CLOSE_TO_HOME_FALLBACK : CUJ_APP_CLOSE_TO_HOME); + ? Cuj.CUJ_LAUNCHER_APP_CLOSE_TO_HOME_FALLBACK + : Cuj.CUJ_LAUNCHER_APP_CLOSE_TO_HOME); anim.addListener(new AnimatorListenerAdapter() { @Override @@ -1768,19 +1768,18 @@ public class QuickstepTransitionManager implements OnDeviceProfileChangeListener if (launchingFromWidget) { composeWidgetLaunchAnimator(anim, (LauncherAppWidgetHostView) mV, appTargets, wallpaperTargets, nonAppTargets, launcherClosing); - addCujInstrumentation( - anim, InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_WIDGET); + addCujInstrumentation(anim, Cuj.CUJ_LAUNCHER_APP_LAUNCH_FROM_WIDGET); skipFirstFrame = true; } else if (launchingFromRecents) { composeRecentsLaunchAnimator(anim, mV, appTargets, wallpaperTargets, nonAppTargets, launcherClosing); addCujInstrumentation( - anim, InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_RECENTS); + anim, Cuj.CUJ_LAUNCHER_APP_LAUNCH_FROM_RECENTS); skipFirstFrame = true; } else { composeIconLaunchAnimator(anim, mV, appTargets, wallpaperTargets, nonAppTargets, launcherClosing); - addCujInstrumentation(anim, InteractionJankMonitorWrapper.CUJ_APP_LAUNCH_FROM_ICON); + addCujInstrumentation(anim, Cuj.CUJ_LAUNCHER_APP_LAUNCH_FROM_ICON); skipFirstFrame = false; } diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java index 968faf07c7..6d3b60a203 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/NoButtonQuickSwitchTouchController.java @@ -16,6 +16,7 @@ package com.android.launcher3.uioverrides.touchcontrollers; import static android.view.MotionEvent.ACTION_DOWN; + import static com.android.app.animation.Interpolators.ACCELERATE_0_75; import static com.android.app.animation.Interpolators.DECELERATE_3; import static com.android.app.animation.Interpolators.LINEAR; @@ -65,6 +66,7 @@ import android.graphics.PointF; import android.view.MotionEvent; import android.view.animation.Interpolator; +import com.android.internal.jank.Cuj; import com.android.launcher3.LauncherState; import com.android.launcher3.R; import com.android.launcher3.Utilities; @@ -190,8 +192,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController, public void onDragStart(boolean start) { mMotionPauseDetector.clear(); if (start) { - InteractionJankMonitorWrapper.begin(mRecentsView, - InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH); + InteractionJankMonitorWrapper.begin(mRecentsView, Cuj.CUJ_LAUNCHER_QUICK_SWITCH); mStartState = mLauncher.getStateManager().getState(); @@ -327,7 +328,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController, if (mMotionPauseDetector.isPaused() && noFling) { // Going to Overview. cancelAnimations(); - InteractionJankMonitorWrapper.cancel(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH); + InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_QUICK_SWITCH); StateAnimationConfig config = new StateAnimationConfig(); config.duration = ATOMIC_DURATION_FROM_PAUSED_TO_OVERVIEW; @@ -445,7 +446,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController, RecentsView.SCROLL_VIBRATION_PRIMITIVE_SCALE, RecentsView.SCROLL_VIBRATION_FALLBACK); } else { - InteractionJankMonitorWrapper.cancel(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH); + InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_QUICK_SWITCH); } nonOverviewAnim.setDuration(Math.max(xDuration, yDuration)); @@ -469,7 +470,7 @@ public class NoButtonQuickSwitchTouchController implements TouchController, : LAUNCHER_UNKNOWN_SWIPEDOWN)); if (targetState == QUICK_SWITCH_FROM_HOME) { - InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH); + InteractionJankMonitorWrapper.end(Cuj.CUJ_LAUNCHER_QUICK_SWITCH); } mLauncher.getStateManager().goToState(targetState, false, forEndCallback(this::clearState)); diff --git a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java index 2c937b008e..d94cd8935a 100644 --- a/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java +++ b/quickstep/src/com/android/launcher3/uioverrides/touchcontrollers/PortraitStatesTouchController.java @@ -24,6 +24,7 @@ import static com.android.launcher3.LauncherState.OVERVIEW; import android.view.MotionEvent; import com.android.app.animation.Interpolators; +import com.android.internal.jank.Cuj; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherState; @@ -185,18 +186,15 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr switch (ev.getAction()) { case MotionEvent.ACTION_DOWN: InteractionJankMonitorWrapper.begin( - mLauncher.getRootView(), InteractionJankMonitorWrapper.CUJ_OPEN_ALL_APPS); + mLauncher.getRootView(), Cuj.CUJ_LAUNCHER_OPEN_ALL_APPS); InteractionJankMonitorWrapper.begin( - mLauncher.getRootView(), - InteractionJankMonitorWrapper.CUJ_CLOSE_ALL_APPS_SWIPE); + mLauncher.getRootView(), Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE); break; case MotionEvent.ACTION_CANCEL: case MotionEvent.ACTION_UP: - InteractionJankMonitorWrapper.cancel( - InteractionJankMonitorWrapper.CUJ_OPEN_ALL_APPS); - InteractionJankMonitorWrapper.cancel( - InteractionJankMonitorWrapper.CUJ_CLOSE_ALL_APPS_SWIPE); + InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_OPEN_ALL_APPS); + InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE); break; } return super.onControllerInterceptTouchEvent(ev); @@ -207,11 +205,10 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr protected void onReinitToState(LauncherState newToState) { super.onReinitToState(newToState); if (newToState != ALL_APPS) { - InteractionJankMonitorWrapper.cancel(InteractionJankMonitorWrapper.CUJ_OPEN_ALL_APPS); + InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_OPEN_ALL_APPS); } if (newToState != NORMAL) { - InteractionJankMonitorWrapper.cancel( - InteractionJankMonitorWrapper.CUJ_CLOSE_ALL_APPS_SWIPE); + InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE); } } @@ -219,18 +216,16 @@ public class PortraitStatesTouchController extends AbstractStateChangeTouchContr protected void onReachedFinalState(LauncherState toState) { super.onReachedFinalState(toState); if (toState == ALL_APPS) { - InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_OPEN_ALL_APPS); + InteractionJankMonitorWrapper.end(Cuj.CUJ_LAUNCHER_OPEN_ALL_APPS); } else if (toState == NORMAL) { - InteractionJankMonitorWrapper.end( - InteractionJankMonitorWrapper.CUJ_CLOSE_ALL_APPS_SWIPE); + InteractionJankMonitorWrapper.end(Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE); } } @Override protected void clearState() { super.clearState(); - InteractionJankMonitorWrapper.cancel(InteractionJankMonitorWrapper.CUJ_OPEN_ALL_APPS); - InteractionJankMonitorWrapper.cancel( - InteractionJankMonitorWrapper.CUJ_CLOSE_ALL_APPS_SWIPE); + InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_OPEN_ALL_APPS); + InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_CLOSE_ALL_APPS_SWIPE); } } diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java index d7ff59e2eb..42b18bdfb1 100644 --- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java +++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java @@ -96,6 +96,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.UiThread; +import com.android.internal.jank.Cuj; import com.android.internal.util.LatencyTracker; import com.android.launcher3.AbstractFloatingView; import com.android.launcher3.DeviceProfile; @@ -1024,12 +1025,12 @@ public abstract class AbsSwipeUpHandler, } mHandled = true; + InteractionJankMonitorWrapper.begin(mRecentsView, Cuj.CUJ_LAUNCHER_QUICK_SWITCH, + 2000 /* ms timeout */); InteractionJankMonitorWrapper.begin(mRecentsView, - InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH, 2000 /* ms timeout */); + Cuj.CUJ_LAUNCHER_APP_CLOSE_TO_HOME); InteractionJankMonitorWrapper.begin(mRecentsView, - InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME); - InteractionJankMonitorWrapper.begin(mRecentsView, - InteractionJankMonitorWrapper.CUJ_APP_SWIPE_TO_RECENTS); + Cuj.CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS); rv.post(() -> rv.getViewTreeObserver().removeOnDrawListener(this)); } @@ -1145,16 +1146,13 @@ public abstract class AbsSwipeUpHandler, View postResumeLastTask = mActivityInterface.onSettledOnEndTarget(endTarget); if (endTarget != NEW_TASK) { - InteractionJankMonitorWrapper.cancel( - InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH); + InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_QUICK_SWITCH); } if (endTarget != HOME) { - InteractionJankMonitorWrapper.cancel( - InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME); + InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_APP_CLOSE_TO_HOME); } if (endTarget != RECENTS) { - InteractionJankMonitorWrapper.cancel( - InteractionJankMonitorWrapper.CUJ_APP_SWIPE_TO_RECENTS); + InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS); } switch (endTarget) { diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java index 31fe791faa..b2429ad3ec 100644 --- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.java +++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.java @@ -31,6 +31,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import androidx.annotation.UiThread; +import com.android.internal.jank.Cuj; import com.android.launcher3.DeviceProfile; import com.android.launcher3.config.FeatureFlags; import com.android.launcher3.statemanager.StatefulActivity; @@ -262,7 +263,7 @@ public class OverviewCommandHelper { if (activity != null) { InteractionJankMonitorWrapper.begin( activity.getRootView(), - InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH); + Cuj.CUJ_LAUNCHER_QUICK_SWITCH); } GestureState gestureState = mService.createGestureState(GestureState.DEFAULT_STATE, diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java index 341e18cc99..06a442b6dc 100644 --- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java +++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java @@ -25,14 +25,13 @@ import android.os.Bundle; import android.os.RemoteException; import android.util.Log; import android.view.IRecentsAnimationController; -import android.view.RemoteAnimationTarget; import android.view.SurfaceControl; import android.view.WindowManagerGlobal; import android.window.PictureInPictureSurfaceTransaction; -import androidx.annotation.NonNull; import androidx.annotation.UiThread; +import com.android.internal.jank.Cuj; import com.android.internal.os.IResultReceiver; import com.android.launcher3.util.Preconditions; import com.android.launcher3.util.RunnableList; @@ -183,10 +182,9 @@ public class RecentsAnimationController { }); } }); - InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH); - InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_HOME); - InteractionJankMonitorWrapper.end( - InteractionJankMonitorWrapper.CUJ_APP_SWIPE_TO_RECENTS); + InteractionJankMonitorWrapper.end(Cuj.CUJ_LAUNCHER_QUICK_SWITCH); + InteractionJankMonitorWrapper.end(Cuj.CUJ_LAUNCHER_APP_CLOSE_TO_HOME); + InteractionJankMonitorWrapper.end(Cuj.CUJ_LAUNCHER_APP_SWIPE_TO_RECENTS); }; if (forceFinish) { finishCb.run(); diff --git a/quickstep/src/com/android/quickstep/TaskViewUtils.java b/quickstep/src/com/android/quickstep/TaskViewUtils.java index 11c5ab476a..4e84f4a6c4 100644 --- a/quickstep/src/com/android/quickstep/TaskViewUtils.java +++ b/quickstep/src/com/android/quickstep/TaskViewUtils.java @@ -60,6 +60,7 @@ import androidx.annotation.NonNull; import androidx.annotation.Nullable; import com.android.app.animation.Interpolators; +import com.android.internal.jank.Cuj; import com.android.launcher3.BaseActivity; import com.android.launcher3.DeviceProfile; import com.android.launcher3.anim.AnimatedFloat; @@ -395,8 +396,7 @@ public final class TaskViewUtils { @Override public void onAnimationSuccess(Animator animator) { if (isQuickSwitch) { - InteractionJankMonitorWrapper.end( - InteractionJankMonitorWrapper.CUJ_QUICK_SWITCH); + InteractionJankMonitorWrapper.end(Cuj.CUJ_LAUNCHER_QUICK_SWITCH); } } diff --git a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java index bce2e82bbc..cf9fc74819 100644 --- a/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java +++ b/quickstep/src/com/android/quickstep/logging/StatsLogCompatManager.java @@ -42,6 +42,7 @@ import androidx.annotation.Nullable; import androidx.annotation.WorkerThread; import androidx.slice.SliceItem; +import com.android.internal.jank.Cuj; import com.android.launcher3.LauncherAppState; import com.android.launcher3.Utilities; import com.android.launcher3.logger.LauncherAtom; @@ -401,11 +402,10 @@ public class StatsLogCompatManager extends StatsLogManager { case LAUNCHER_ALLAPPS_VERTICAL_SWIPE_BEGIN: InteractionJankMonitorWrapper.begin( view, - InteractionJankMonitorWrapper.CUJ_ALL_APPS_SCROLL); + Cuj.CUJ_LAUNCHER_ALL_APPS_SCROLL); break; case LAUNCHER_ALLAPPS_VERTICAL_SWIPE_END: - InteractionJankMonitorWrapper.end( - InteractionJankMonitorWrapper.CUJ_ALL_APPS_SCROLL); + InteractionJankMonitorWrapper.end(Cuj.CUJ_LAUNCHER_ALL_APPS_SCROLL); break; default: break; diff --git a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java index e705285fa2..28efc9748b 100644 --- a/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java +++ b/quickstep/src/com/android/quickstep/util/SplitToWorkspaceController.java @@ -34,6 +34,7 @@ import android.graphics.drawable.Drawable; import android.os.UserHandle; import android.view.View; +import com.android.internal.jank.Cuj; import com.android.launcher3.DeviceProfile; import com.android.launcher3.Launcher; import com.android.launcher3.LauncherAppState; @@ -174,8 +175,7 @@ public class SplitToWorkspaceController { public void onAnimationEnd(Animator animation) { if (!mIsCancelled) { mController.launchSplitTasks(aBoolean -> cleanUp()); - InteractionJankMonitorWrapper.end( - InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER); + InteractionJankMonitorWrapper.end(Cuj.CUJ_SPLIT_SCREEN_ENTER); } } diff --git a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java index fe6ce46072..a36b32c1ed 100644 --- a/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java +++ b/quickstep/src/com/android/quickstep/util/SwipePipToHomeAnimator.java @@ -16,8 +16,6 @@ package com.android.quickstep.util; -import static com.android.systemui.shared.system.InteractionJankMonitorWrapper.CUJ_APP_CLOSE_TO_PIP; - import android.animation.Animator; import android.animation.RectEvaluator; import android.content.ComponentName; @@ -35,6 +33,7 @@ import android.window.PictureInPictureSurfaceTransaction; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.internal.jank.Cuj; import com.android.launcher3.anim.AnimationSuccessListener; import com.android.launcher3.icons.IconProvider; import com.android.quickstep.TaskAnimationManager; @@ -174,19 +173,19 @@ public class SwipePipToHomeAnimator extends RectFSpringAnim { addAnimatorListener(new AnimationSuccessListener() { @Override public void onAnimationStart(Animator animation) { - InteractionJankMonitorWrapper.begin(view, CUJ_APP_CLOSE_TO_PIP); + InteractionJankMonitorWrapper.begin(view, Cuj.CUJ_LAUNCHER_APP_CLOSE_TO_PIP); super.onAnimationStart(animation); } @Override public void onAnimationCancel(Animator animation) { super.onAnimationCancel(animation); - InteractionJankMonitorWrapper.cancel(CUJ_APP_CLOSE_TO_PIP); + InteractionJankMonitorWrapper.cancel(Cuj.CUJ_LAUNCHER_APP_CLOSE_TO_PIP); } @Override public void onAnimationSuccess(Animator animator) { - InteractionJankMonitorWrapper.end(CUJ_APP_CLOSE_TO_PIP); + InteractionJankMonitorWrapper.end(Cuj.CUJ_LAUNCHER_APP_CLOSE_TO_PIP); } @Override diff --git a/quickstep/src/com/android/quickstep/util/unfold/LauncherJankMonitorTransitionProgressListener.kt b/quickstep/src/com/android/quickstep/util/unfold/LauncherJankMonitorTransitionProgressListener.kt index 4f89c7e7c2..b4ca35e8fa 100644 --- a/quickstep/src/com/android/quickstep/util/unfold/LauncherJankMonitorTransitionProgressListener.kt +++ b/quickstep/src/com/android/quickstep/util/unfold/LauncherJankMonitorTransitionProgressListener.kt @@ -16,6 +16,7 @@ package com.android.quickstep.util.unfold import android.view.View +import com.android.internal.jank.Cuj import com.android.systemui.shared.system.InteractionJankMonitorWrapper import com.android.systemui.unfold.UnfoldTransitionProgressProvider.TransitionProgressListener import java.util.function.Supplier @@ -28,11 +29,11 @@ class LauncherJankMonitorTransitionProgressListener( override fun onTransitionStarted() { InteractionJankMonitorWrapper.begin( attachedViewProvider.get(), - InteractionJankMonitorWrapper.CUJ_LAUNCHER_UNFOLD_ANIM + Cuj.CUJ_LAUNCHER_UNFOLD_ANIM ) } override fun onTransitionFinished() { - InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_LAUNCHER_UNFOLD_ANIM) + InteractionJankMonitorWrapper.end(Cuj.CUJ_LAUNCHER_UNFOLD_ANIM) } } diff --git a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java index dd201af92f..2ae64ffa63 100644 --- a/quickstep/src/com/android/quickstep/views/GroupedTaskView.java +++ b/quickstep/src/com/android/quickstep/views/GroupedTaskView.java @@ -17,6 +17,7 @@ import android.view.ViewStub; import androidx.annotation.NonNull; import androidx.annotation.Nullable; +import com.android.internal.jank.Cuj; import com.android.launcher3.DeviceProfile; import com.android.launcher3.R; import com.android.launcher3.Utilities; @@ -246,12 +247,11 @@ public class GroupedTaskView extends TaskView { RunnableList endCallback = new RunnableList(); RecentsView recentsView = getRecentsView(); // Callbacks run from remote animation when recents animation not currently running - InteractionJankMonitorWrapper.begin(this, - InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER, "Enter form GroupedTaskView"); + InteractionJankMonitorWrapper.begin(this, Cuj.CUJ_SPLIT_SCREEN_ENTER, + "Enter form GroupedTaskView"); launchTaskInternal(success -> { endCallback.executeAllAndDestroy(); - InteractionJankMonitorWrapper.end( - InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER); + InteractionJankMonitorWrapper.end(Cuj.CUJ_SPLIT_SCREEN_ENTER); }, false /* freezeTaskList */, true /*launchingExistingTaskview*/); diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java index 87cee63f9e..ca9d13e49f 100644 --- a/quickstep/src/com/android/quickstep/views/RecentsView.java +++ b/quickstep/src/com/android/quickstep/views/RecentsView.java @@ -133,6 +133,7 @@ import androidx.annotation.Nullable; import androidx.annotation.UiThread; import androidx.core.graphics.ColorUtils; +import com.android.internal.jank.Cuj; import com.android.launcher3.BaseActivity; import com.android.launcher3.BaseActivity.MultiWindowModeChangedListener; import com.android.launcher3.DeviceProfile; @@ -1444,8 +1445,7 @@ public abstract class RecentsView 0) { setSwipeDownShouldLaunchApp(true); } - InteractionJankMonitorWrapper.end(InteractionJankMonitorWrapper.CUJ_RECENTS_SCROLLING); + InteractionJankMonitorWrapper.end(Cuj.CUJ_RECENTS_SCROLLING); } @Override @@ -3313,8 +3313,8 @@ public abstract class RecentsView { if (success) { - InteractionJankMonitorWrapper.end( - InteractionJankMonitorWrapper.CUJ_SPLIT_SCREEN_ENTER); + InteractionJankMonitorWrapper.end(Cuj.CUJ_SPLIT_SCREEN_ENTER); } else { // If transition to split select was interrupted, clean up to prevent glitches if (FeatureFlags.enableSplitContextually()) { @@ -3339,8 +3338,7 @@ public abstract class RecentsView Date: Thu, 14 Dec 2023 18:19:35 +0000 Subject: [PATCH 010/577] Revert " ALLAPPS PREINFLATION to TEAMFOOD" This reverts commit 11d8641e8a423f7786d1084110fc3ae0c77d6852. Reason for revert: ag/25590079 has been submitted to guarantee that we cancel icon preinflation job when device profile is changed. Change-Id: I2c9254c63d89c389bd83725301c4957c66dad770 --- src/com/android/launcher3/config/FeatureFlags.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index b7b0816e6e..14d1683585 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -484,10 +484,10 @@ public final class FeatureFlags { // TODO(Block 33): Clean up flags public static final BooleanFlag ENABLE_ALL_APPS_RV_PREINFLATION = getDebugFlag(288161355, - "ENABLE_ALL_APPS_RV_PREINFLATION", TEAMFOOD, + "ENABLE_ALL_APPS_RV_PREINFLATION", ENABLED, "Enables preinflating all apps icons to avoid scrolling jank."); public static final BooleanFlag ALL_APPS_GONE_VISIBILITY = getDebugFlag(291651514, - "ALL_APPS_GONE_VISIBILITY", TEAMFOOD, + "ALL_APPS_GONE_VISIBILITY", ENABLED, "Set all apps container view's hidden visibility to GONE instead of INVISIBLE."); // TODO(Block 34): Empty block -- GitLab From b0de412e4770ec5cf01222783e37eda7774480ec Mon Sep 17 00:00:00 2001 From: Catherine Liang Date: Tue, 12 Dec 2023 21:16:22 +0000 Subject: [PATCH 011/577] Fix Launcher preview display size When previewing the Launcher in the Wallpaper Picker for a different display size than the current screen, the preview no longer adapts to that screen size. Flag: ACONFIG com.android.wallpaper.multi_crop_preview_ui_flag DEVELOPMENT Bug: 316000567 Test: manually verified Change-Id: Ib10f2c9acec98ed99cadd40a588e2ffdea900ba6 --- .../graphics/LauncherPreviewRenderer.java | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java index 3330448919..7dcc8a8637 100644 --- a/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java +++ b/src/com/android/launcher3/graphics/LauncherPreviewRenderer.java @@ -35,6 +35,7 @@ import android.appwidget.AppWidgetHostView; import android.appwidget.AppWidgetProviderInfo; import android.content.Context; import android.content.ContextWrapper; +import android.content.res.Configuration; import android.content.res.TypedArray; import android.graphics.PointF; import android.graphics.Rect; @@ -197,7 +198,7 @@ public class LauncherPreviewRenderer extends ContextWrapper mUiHandler = new Handler(Looper.getMainLooper()); mContext = context; mIdp = idp; - mDp = idp.getDeviceProfile(context).toBuilder(context).setViewScaleProvider( + mDp = getDeviceProfileForPreview(context).toBuilder(context).setViewScaleProvider( this::getAppWidgetScale).build(); if (context instanceof PreviewContext) { Context tempContext = ((PreviewContext) context).getBaseContext(); @@ -259,6 +260,21 @@ public class LauncherPreviewRenderer extends ContextWrapper mAppWidgetHost = new LauncherPreviewAppWidgetHost(context); } + /** + * Returns the device profile based on resource configuration for previewing various display + * sizes + */ + private DeviceProfile getDeviceProfileForPreview(Context context) { + float density = context.getResources().getDisplayMetrics().density; + Configuration config = context.getResources().getConfiguration(); + + return mIdp.getBestMatch( + config.screenWidthDp * density, + config.screenHeightDp * density, + WindowManagerProxy.INSTANCE.get(context).getRotation(context) + ); + } + /** * Returns the insets of the screen closest to the display given by the context */ -- GitLab From df14dad9276f25467fb0d39f4f3897ffa5161819 Mon Sep 17 00:00:00 2001 From: Vadim Tryshev Date: Mon, 11 Dec 2023 16:14:34 -0800 Subject: [PATCH 012/577] Waiting for Launcher stop when starting a task from keyboard quick switch This will help to ensure that Launcher state has settled before continuing the test. Bug: 313926097 Flag: N/A Test: presubmit Change-Id: I4ba5dd2eaa8cf2fbfe21f2cafd9835ef42b19341 --- .../launcher3/tapl/KeyboardQuickSwitch.java | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/KeyboardQuickSwitch.java b/tests/tapl/com/android/launcher3/tapl/KeyboardQuickSwitch.java index a1d8059631..5ef82ca897 100644 --- a/tests/tapl/com/android/launcher3/tapl/KeyboardQuickSwitch.java +++ b/tests/tapl/com/android/launcher3/tapl/KeyboardQuickSwitch.java @@ -58,15 +58,15 @@ public final class KeyboardQuickSwitch { private final LauncherInstrumentation mLauncher; private final LauncherInstrumentation.ContainerType mStartingContainerType; - private final boolean mExpectHomeKeyEventsOnDismiss; + private final boolean mIsHomeState; KeyboardQuickSwitch( LauncherInstrumentation launcher, LauncherInstrumentation.ContainerType startingContainerType, - boolean expectHomeKeyEventsOnDismiss) { + boolean isHomeState) { mLauncher = launcher; mStartingContainerType = startingContainerType; - mExpectHomeKeyEventsOnDismiss = expectHomeKeyEventsOnDismiss; + mIsHomeState = isHomeState; } /** @@ -164,7 +164,7 @@ public final class KeyboardQuickSwitch { mLauncher.verifyContainerType(mStartingContainerType); // Wait until the device has fully settled before unpressing the key code - if (mExpectHomeKeyEventsOnDismiss) { + if (mIsHomeState) { mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_HOME_ALT_LEFT_UP); } mLauncher.unpressKeyCode(KeyEvent.KEYCODE_ALT_LEFT, 0); @@ -204,7 +204,14 @@ public final class KeyboardQuickSwitch { "want to launch focused task: " + (expectedPackageName == null ? "Overview" : expectedPackageName))) { mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, EVENT_KQS_ALT_LEFT_UP); - mLauncher.unpressKeyCode(KeyEvent.KEYCODE_ALT_LEFT, 0); + + if (expectedPackageName == null || !mIsHomeState) { + mLauncher.unpressKeyCode(KeyEvent.KEYCODE_ALT_LEFT, 0); + } else { + mLauncher.executeAndWaitForLauncherStop( + () -> mLauncher.unpressKeyCode(KeyEvent.KEYCODE_ALT_LEFT, 0), + "unpressing left alt"); + } try (LauncherInstrumentation.Closable c2 = mLauncher.addContextLayer( "un-pressed left alt")) { -- GitLab From 9e9799b28c7a05794257e58fc00df6dd18c586e2 Mon Sep 17 00:00:00 2001 From: Jagrut Desai Date: Thu, 14 Dec 2023 15:30:35 -0800 Subject: [PATCH 013/577] Refactoring testDragIcon() test - refactoring getWidget method to add support for different app packages. - removing platinum test annotation since adding test on platform scenario test. Test: Presubmit, Local Bug: 303258153 Flag: NONE Change-Id: Ifd5e50cfe8019984ba25312f52266e8b1774318e --- .../ui/widget/TaplAddWidgetTest.java | 1 - .../com/android/launcher3/tapl/Widgets.java | 26 +++++++++++++++---- 2 files changed, 21 insertions(+), 6 deletions(-) diff --git a/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java index 27fda9b680..d75b387cc9 100644 --- a/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java +++ b/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java @@ -47,7 +47,6 @@ public class TaplAddWidgetTest extends AbstractLauncherUiTest { @Rule public ShellCommandRule mGrantWidgetRule = ShellCommandRule.grantWidgetBind(); - @PlatinumTest(focusArea = "launcher") @Test @PortraitLandscape @ScreenRecordRule.ScreenRecord // b/289161193 diff --git a/tests/tapl/com/android/launcher3/tapl/Widgets.java b/tests/tapl/com/android/launcher3/tapl/Widgets.java index 105bc3bf50..6387b05cc8 100644 --- a/tests/tapl/com/android/launcher3/tapl/Widgets.java +++ b/tests/tapl/com/android/launcher3/tapl/Widgets.java @@ -19,6 +19,7 @@ package com.android.launcher3.tapl; import static com.android.launcher3.tapl.LauncherInstrumentation.WAIT_TIME_MS; import static com.android.launcher3.tapl.LauncherInstrumentation.log; +import android.annotation.Nullable; import android.graphics.Rect; import androidx.test.uiautomator.By; @@ -114,7 +115,13 @@ public final class Widgets extends LauncherInstrumentation.VisibleContainer .getInt(TestProtocol.TEST_INFO_RESPONSE_FIELD); } + /** Get widget with supplied text. */ public Widget getWidget(String labelText) { + return getWidget(labelText, null); + } + + /** Get widget with supplied text and app package */ + public Widget getWidget(String labelText, @Nullable String testAppWidgetPackage) { try (LauncherInstrumentation.Closable e = mLauncher.eventsCheck(); LauncherInstrumentation.Closable c = mLauncher.addContextLayer( "getting widget " + labelText + " in widgets list")) { @@ -124,7 +131,8 @@ public final class Widgets extends LauncherInstrumentation.VisibleContainer mLauncher.assertTrue("Widgets container didn't become scrollable", fullWidgetsPicker.wait(Until.scrollable(true), WAIT_TIME_MS)); - final UiObject2 widgetsContainer = findTestAppWidgetsTableContainer(); + final UiObject2 widgetsContainer = + findTestAppWidgetsTableContainer(testAppWidgetPackage); mLauncher.assertTrue("Can't locate widgets list for the test app: " + mLauncher.getLauncherPackageName(), widgetsContainer != null); @@ -180,14 +188,22 @@ public final class Widgets extends LauncherInstrumentation.VisibleContainer return searchBar; } - /** Finds the widgets list of this test app from the collapsed full widgets picker. */ - private UiObject2 findTestAppWidgetsTableContainer() { + /** + * Finds the widgets list of this test app or supplied test app package from the collapsed full + * widgets picker. + */ + private UiObject2 findTestAppWidgetsTableContainer(@Nullable String testAppWidgetPackage) { final BySelector headerSelector = By.res(mLauncher.getLauncherPackageName(), "widgets_list_header"); final BySelector widgetPickerSelector = By.res(mLauncher.getLauncherPackageName(), "container"); - final BySelector targetAppSelector = By.clazz("android.widget.TextView").text( - mLauncher.getContext().getPackageName()); + + String packageName = mLauncher.getContext().getPackageName(); + final BySelector targetAppSelector = By + .clazz("android.widget.TextView") + .text((testAppWidgetPackage == null || testAppWidgetPackage.isEmpty()) + ? packageName + : testAppWidgetPackage); final BySelector widgetsContainerSelector = By.res(mLauncher.getLauncherPackageName(), "widgets_table"); -- GitLab From 95c4c8d2680169a57a1924a5bc2018ea39a26fe8 Mon Sep 17 00:00:00 2001 From: Tracy Zhou Date: Wed, 22 Nov 2023 22:43:52 -0800 Subject: [PATCH 014/577] Fix crash from folding/unfolding This is fundamentally caused by the phone device profile not having task bar related attributes, which crashes in icon alignment animation. We had resolved it by skipping this animation based on isPhoneMode check. However, we passed in launcherDp instead of taskbarDp (from TaskbarActivityContext) which doesn't always have the most up to date information in race conditions (e.g. repetitively fold/unfold) Fixes: 311431054 Test: repetively fold/unfold, make sure it doesn't crash Change-Id: I65f600112da4123d337b3f59a2fe6dd13ac7af74 --- .../taskbar/NavbarButtonsViewController.java | 15 ++++----- .../taskbar/StashedHandleViewController.java | 10 ++---- .../taskbar/TaskbarActivityContext.java | 31 +++++++++++++++---- .../taskbar/TaskbarBackgroundRenderer.kt | 5 ++- .../launcher3/taskbar/TaskbarDragLayer.java | 2 +- .../taskbar/TaskbarDragLayerController.java | 7 ++--- .../taskbar/TaskbarEduTooltipController.kt | 3 +- .../TaskbarLauncherStateController.java | 3 +- .../launcher3/taskbar/TaskbarManager.java | 18 +---------- .../taskbar/TaskbarStashController.java | 19 ++++-------- .../launcher3/taskbar/TaskbarView.java | 2 +- .../taskbar/TaskbarViewController.java | 8 ++--- .../taskbar/navbutton/KidsNavLayoutter.kt | 4 +-- .../navbutton/NavButtonLayoutFactory.kt | 3 +- .../navbutton/PhoneGestureLayoutter.kt | 4 +-- .../navbutton/PhoneLandscapeNavLayoutter.kt | 9 +++--- .../navbutton/PhonePortraitNavLayoutter.kt | 9 +++--- .../taskbar/navbutton/SetupNavLayoutter.kt | 4 +-- .../taskbar/navbutton/TaskbarNavLayoutter.kt | 10 +++--- .../quickstep/TouchInteractionService.java | 4 +-- 20 files changed, 77 insertions(+), 93 deletions(-) diff --git a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java index bed4c376ae..709d3bac57 100644 --- a/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/NavbarButtonsViewController.java @@ -25,8 +25,6 @@ import static com.android.launcher3.LauncherAnimUtils.VIEW_TRANSLATE_X; import static com.android.launcher3.Utilities.getDescendantCoordRelativeToAncestor; import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NAVBAR_UNIFICATION; import static com.android.launcher3.taskbar.LauncherTaskbarUIController.SYSUI_SURFACE_PROGRESS_INDEX; -import static com.android.launcher3.taskbar.TaskbarManager.isPhoneButtonNavMode; -import static com.android.launcher3.taskbar.TaskbarManager.isPhoneMode; import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_A11Y; import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_BACK; import static com.android.launcher3.taskbar.TaskbarNavButtonController.BUTTON_HOME; @@ -239,7 +237,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT Point p = !mContext.isUserSetupComplete() ? new Point(0, mControllers.taskbarActivityContext.getSetupWindowHeight()) : DimensionUtils.getTaskbarPhoneDimensions(deviceProfile, resources, - TaskbarManager.isPhoneMode(deviceProfile)); + mContext.isPhoneMode()); mNavButtonsView.getLayoutParams().height = p.y; mIsImeRenderingNavButtons = @@ -305,7 +303,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT initButtons(mNavButtonContainer, mEndContextualContainer, mControllers.navButtonController); updateButtonLayoutSpacing(); - updateStateForFlag(FLAG_SMALL_SCREEN, isPhoneButtonNavMode(mContext)); + updateStateForFlag(FLAG_SMALL_SCREEN, mContext.isPhoneButtonNavMode()); mPropertyHolders.add(new StatePropertyHolder( mControllers.taskbarDragLayerController.getNavbarBackgroundAlpha(), @@ -388,7 +386,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT int navButtonSize = mContext.getResources().getDimensionPixelSize( R.dimen.taskbar_nav_buttons_size); boolean isRtl = Utilities.isRtl(mContext.getResources()); - if (!isPhoneMode(mContext.getDeviceProfile())) { + if (!mContext.isPhoneMode()) { mPropertyHolders.add(new StatePropertyHolder( mBackButton, flags -> (flags & FLAG_ONLY_BACK_FOR_BOUNCER_VISIBLE) != 0 || (flags & FLAG_KEYGUARD_VISIBLE) != 0, @@ -632,7 +630,7 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT * Sets the translationY of the nav buttons based on the current device state. */ public void updateNavButtonTranslationY() { - if (isPhoneButtonNavMode(mContext)) { + if (mContext.isPhoneButtonNavMode()) { return; } final float normalTranslationY = mTaskbarNavButtonTranslationY.value; @@ -751,9 +749,8 @@ public class NavbarButtonsViewController implements TaskbarControllers.LoggableT dp, mNavButtonsView, mImeSwitcherButton, mControllers.rotationButtonController.getRotationButton(), mA11yButton, res, isInKidsMode, isInSetup, isThreeButtonNav, - TaskbarManager.isPhoneMode(dp), - mWindowManagerProxy.getRotation(mContext)); - navButtonLayoutter.layoutButtons(dp, isA11yButtonPersistent()); + mContext.isPhoneMode(), mWindowManagerProxy.getRotation(mContext)); + navButtonLayoutter.layoutButtons(mContext, isA11yButtonPersistent()); updateNavButtonColor(); return; } diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java index da1f766420..ad2dc234a0 100644 --- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java @@ -107,7 +107,7 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT mControllers = controllers; DeviceProfile deviceProfile = mActivity.getDeviceProfile(); Resources resources = mActivity.getResources(); - if (isPhoneGestureNavMode(mActivity.getDeviceProfile())) { + if (mActivity.isPhoneGestureNavMode()) { mTaskbarSize = resources.getDimensionPixelSize(R.dimen.taskbar_phone_size); mStashedHandleWidth = resources.getDimensionPixelSize(R.dimen.taskbar_stashed_small_screen); @@ -120,7 +120,7 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT mStashedHandleView.getLayoutParams().height = mTaskbarSize + taskbarBottomMargin; mTaskbarStashedHandleAlpha.get(ALPHA_INDEX_STASHED).setValue( - isPhoneGestureNavMode(deviceProfile) ? 1 : 0); + mActivity.isPhoneGestureNavMode() ? 1 : 0); mTaskbarStashedHandleHintScale.updateValue(1f); final int stashedTaskbarHeight = mControllers.taskbarStashController.getStashedHeight(); @@ -148,7 +148,7 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT view.setPivotY(stashedCenterY); }); initRegionSampler(); - if (isPhoneGestureNavMode(deviceProfile)) { + if (mActivity.isPhoneGestureNavMode()) { onIsStashedChanged(true); } } @@ -184,10 +184,6 @@ public class StashedHandleViewController implements TaskbarControllers.LoggableT mRegionSamplingHelper = null; } - private boolean isPhoneGestureNavMode(DeviceProfile deviceProfile) { - return TaskbarManager.isPhoneMode(deviceProfile) && !mActivity.isThreeButtonNav(); - } - public MultiPropertyFactory getStashedHandleAlpha() { return mTaskbarStashedHandleAlpha; } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java index 4290948ad2..f6703f3139 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java @@ -214,7 +214,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { Context c = getApplicationContext(); mWindowManager = c.getSystemService(WindowManager.class); - boolean phoneMode = TaskbarManager.isPhoneMode(mDeviceProfile); + boolean phoneMode = isPhoneMode(); mLeftCorner = phoneMode ? null : display.getRoundedCorner(RoundedCorner.POSITION_BOTTOM_LEFT); @@ -387,6 +387,28 @@ public class TaskbarActivityContext extends BaseTaskbarContext { } } + /** + * @return {@code true} if the device profile isn't a large screen profile and we are using a + * single window for taskbar and navbar. + */ + public boolean isPhoneMode() { + return ENABLE_TASKBAR_NAVBAR_UNIFICATION && mDeviceProfile.isPhone; + } + + /** + * @return {@code true} if {@link #isPhoneMode()} is true and we're using 3 button-nav + */ + public boolean isPhoneButtonNavMode() { + return isPhoneMode() && isThreeButtonNav(); + } + + /** + * @return {@code true} if {@link #isPhoneMode()} is true and we're using gesture nav + */ + public boolean isPhoneGestureNavMode() { + return isPhoneMode() && !isThreeButtonNav(); + } + /** * Show Taskbar upon receiving broadcast */ @@ -464,9 +486,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { windowLayoutParams.privateFlags = WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION; windowLayoutParams.accessibilityTitle = getString( - TaskbarManager.isPhoneMode(mDeviceProfile) - ? R.string.taskbar_phone_a11y_title - : R.string.taskbar_a11y_title); + isPhoneMode() ? R.string.taskbar_phone_a11y_title : R.string.taskbar_a11y_title); return windowLayoutParams; } @@ -480,8 +500,7 @@ public class TaskbarActivityContext extends BaseTaskbarContext { ENABLE_TASKBAR_NAVBAR_UNIFICATION ? TYPE_NAVIGATION_BAR : TYPE_NAVIGATION_BAR_PANEL; WindowManager.LayoutParams windowLayoutParams = createDefaultWindowLayoutParams(windowType, TaskbarActivityContext.WINDOW_TITLE); - boolean isPhoneNavMode = TaskbarManager.isPhoneButtonNavMode(this); - if (!isPhoneNavMode) { + if (!isPhoneButtonNavMode()) { return windowLayoutParams; } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt index d6016f1304..30f8d56504 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarBackgroundRenderer.kt @@ -23,7 +23,6 @@ import android.graphics.Paint import android.graphics.Path import android.graphics.RectF import com.android.app.animation.Interpolators -import com.android.launcher3.DeviceProfile import com.android.launcher3.R import com.android.launcher3.Utilities import com.android.launcher3.Utilities.mapRange @@ -95,10 +94,10 @@ class TaskbarBackgroundRenderer(private val context: TaskbarActivityContext) { setCornerRoundness(DEFAULT_ROUNDNESS) } - fun updateStashedHandleWidth(dp: DeviceProfile, res: Resources) { + fun updateStashedHandleWidth(context: TaskbarActivityContext, res: Resources) { stashedHandleWidth = res.getDimensionPixelSize( - if (TaskbarManager.isPhoneMode(dp)) R.dimen.taskbar_stashed_small_screen + if (context.isPhoneMode) R.dimen.taskbar_stashed_small_screen else R.dimen.taskbar_stashed_handle_width ) } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java index a24cf4ba58..f9fc9832c8 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayer.java @@ -106,7 +106,7 @@ public class TaskbarDragLayer extends BaseDragLayer { public void init(TaskbarDragLayerController.TaskbarDragLayerCallbacks callbacks) { mControllerCallbacks = callbacks; - mBackgroundRenderer.updateStashedHandleWidth(mActivity.getDeviceProfile(), getResources()); + mBackgroundRenderer.updateStashedHandleWidth(mActivity, getResources()); recreateControllers(); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java index 73e32abb2c..3823c5a098 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java @@ -276,11 +276,10 @@ public class TaskbarDragLayerController implements TaskbarControllers.LoggableTa */ public int getTaskbarBackgroundHeight() { DeviceProfile deviceProfile = mActivity.getDeviceProfile(); - if (TaskbarManager.isPhoneMode(deviceProfile)) { + if (mActivity.isPhoneMode()) { Resources resources = mActivity.getResources(); - Point taskbarDimensions = - DimensionUtils.getTaskbarPhoneDimensions(deviceProfile, resources, - TaskbarManager.isPhoneMode(deviceProfile)); + Point taskbarDimensions = DimensionUtils.getTaskbarPhoneDimensions(deviceProfile, + resources, true /* isPhoneMode */); return taskbarDimensions.y == -1 ? deviceProfile.getDisplayInfo().currentSize.y : taskbarDimensions.y; diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt index 6d1b55870f..4776f0cb30 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarEduTooltipController.kt @@ -32,7 +32,6 @@ import com.android.launcher3.Utilities import com.android.launcher3.config.FeatureFlags.enableTaskbarPinningEdu import com.android.launcher3.taskbar.TaskbarAutohideSuspendController.FLAG_AUTOHIDE_SUSPEND_EDU_OPEN import com.android.launcher3.taskbar.TaskbarControllers.LoggableTaskbarController -import com.android.launcher3.taskbar.TaskbarManager.isPhoneMode import com.android.launcher3.util.DisplayController import com.android.launcher3.util.OnboardingPrefs.TASKBAR_EDU_TOOLTIP_STEP import com.android.quickstep.util.LottieAnimationColorUtils @@ -62,7 +61,7 @@ class TaskbarEduTooltipController(val activityContext: TaskbarActivityContext) : LoggableTaskbarController { private val isTooltipEnabled: Boolean - get() = !Utilities.isRunningInTestHarness() && !isPhoneMode(activityContext.deviceProfile) + get() = !Utilities.isRunningInTestHarness() && !activityContext.isPhoneMode private val isOpen: Boolean get() = tooltip?.isOpen ?: false val isBeforeTooltipFeaturesStep: Boolean diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java index 057b71b74f..a8506805b8 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarLauncherStateController.java @@ -17,7 +17,6 @@ package com.android.launcher3.taskbar; import static com.android.app.animation.Interpolators.EMPHASIZED; import static com.android.launcher3.taskbar.TaskbarKeyguardController.MASK_ANY_SYSUI_LOCKED; -import static com.android.launcher3.taskbar.TaskbarManager.isPhoneMode; import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP; import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_OVERVIEW; import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_STASHED_LAUNCHER_STATE; @@ -734,7 +733,7 @@ public class TaskbarLauncherStateController { } mIconAlphaForHome.setValue(alpha); boolean hotseatVisible = alpha == 0 - || isPhoneMode(mLauncher.getDeviceProfile()) + || mControllers.taskbarActivityContext.isPhoneMode() || (!mControllers.uiController.isHotseatIconOnTopWhenAligned() && mIconAlignment.value > 0); /* diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java index bbac11625d..831bc1167d 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarManager.java @@ -492,23 +492,7 @@ public class TaskbarManager { } } - /** - * @return {@code true} if provided device profile isn't a large screen profile - * and we are using a single window for taskbar and navbar. - */ - public static boolean isPhoneMode(DeviceProfile deviceProfile) { - return ENABLE_TASKBAR_NAVBAR_UNIFICATION && deviceProfile.isPhone; - } - - /** - * @return {@code true} if {@link #isPhoneMode(DeviceProfile)} is true and we're using - * 3 button-nav - */ - public static boolean isPhoneButtonNavMode(TaskbarActivityContext context) { - return isPhoneMode(context.getDeviceProfile()) && context.isThreeButtonNav(); - } - - private boolean isTaskbarPresent(DeviceProfile deviceProfile) { + private static boolean isTaskbarPresent(DeviceProfile deviceProfile) { return ENABLE_TASKBAR_NAVBAR_UNIFICATION || deviceProfile.isTaskbarPresent; } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java index 9aaa80f74c..b3a8b935f1 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarStashController.java @@ -256,7 +256,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba mSystemUiProxy = SystemUiProxy.INSTANCE.get(activity); mAccessibilityManager = mActivity.getSystemService(AccessibilityManager.class); - if (isPhoneMode()) { + if (mActivity.isPhoneMode()) { mUnstashedHeight = mActivity.getResources().getDimensionPixelSize( R.dimen.taskbar_phone_size); mStashedHeight = mActivity.getResources().getDimensionPixelSize( @@ -316,7 +316,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba updateStateForFlag(FLAG_STASHED_IN_APP_AUTO, isStashedInAppAuto); updateStateForFlag(FLAG_STASHED_IN_APP_SETUP, isInSetup); updateStateForFlag(FLAG_IN_SETUP, isInSetup); - updateStateForFlag(FLAG_STASHED_SMALL_SCREEN, isPhoneMode() + updateStateForFlag(FLAG_STASHED_SMALL_SCREEN, mActivity.isPhoneMode() && !mActivity.isThreeButtonNav()); // For now, assume we're in an app, since LauncherTaskbarUIController won't be able to tell // us that we're paused until a bit later. This avoids flickering upon recreating taskbar. @@ -386,13 +386,6 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba return (hasAnyFlag(FLAG_IN_STASHED_LAUNCHER_STATE) && supportsVisualStashing()); } - /** - * @return {@code true} if we're not on a large screen AND using gesture nav - */ - private boolean isPhoneMode() { - return TaskbarManager.isPhoneMode(mActivity.getDeviceProfile()); - } - private boolean hasAnyFlag(int flagMask) { return hasAnyFlag(mState, flagMask); } @@ -428,7 +421,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba * @see android.view.WindowInsets.Type#systemBars() */ public int getContentHeightToReportToApps() { - if ((isPhoneMode() && !mActivity.isThreeButtonNav()) + if ((mActivity.isPhoneMode() && !mActivity.isThreeButtonNav()) || DisplayController.isTransientTaskbar(mActivity)) { return getStashedHeight(); } @@ -579,7 +572,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba mAnimator = new AnimatorSet(); addJankMonitorListener(mAnimator, /* appearing= */ !mIsStashed); boolean isTransientTaskbar = DisplayController.isTransientTaskbar(mActivity); - final float stashTranslation = isPhoneMode() || isTransientTaskbar + final float stashTranslation = mActivity.isPhoneMode() || isTransientTaskbar ? 0 : (mUnstashedHeight - mStashedHeight); @@ -651,7 +644,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba firstHalfAnimatorSet.playTogether( mIconAlphaForStash.animateToValue(0), - mIconScaleForStash.animateToValue(isPhoneMode() ? + mIconScaleForStash.animateToValue(mActivity.isPhoneMode() ? 0 : STASHED_TASKBAR_SCALE) ); secondHalfAnimatorSet.playTogether( @@ -948,7 +941,7 @@ public class TaskbarStashController implements TaskbarControllers.LoggableTaskba return false; } return (mIsImeShowing || mIsImeSwitcherShowing) && - !(isPhoneMode() && mActivity.isThreeButtonNav() + !(mActivity.isPhoneMode() && mActivity.isThreeButtonNav() && mActivity.getDeviceProfile().isLandscape); } diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java index 2ab00665ed..74517a8c69 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java @@ -123,7 +123,7 @@ public class TaskbarView extends FrameLayout implements FolderIcon.FolderIconPar mIconLayoutBounds = mActivityContext.getTransientTaskbarBounds(); Resources resources = getResources(); boolean isTransientTaskbar = DisplayController.isTransientTaskbar(mActivityContext) - && !TaskbarManager.isPhoneMode(mActivityContext.getDeviceProfile()); + && !mActivityContext.isPhoneMode(); mIsRtl = Utilities.isRtl(resources); mTransientTaskbarMinWidth = resources.getDimension(R.dimen.transient_taskbar_min_width); diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java index c0cbd45cc1..33fb3954ea 100644 --- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java +++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java @@ -29,8 +29,6 @@ import static com.android.launcher3.config.FeatureFlags.enableTaskbarPinning; import static com.android.launcher3.logging.StatsLogManager.LauncherEvent.LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP; import static com.android.launcher3.taskbar.TaskbarPinningController.PINNING_PERSISTENT; import static com.android.launcher3.taskbar.TaskbarPinningController.PINNING_TRANSIENT; -import static com.android.launcher3.taskbar.TaskbarManager.isPhoneButtonNavMode; -import static com.android.launcher3.taskbar.TaskbarManager.isPhoneMode; import static com.android.launcher3.util.MultiPropertyFactory.MULTI_PROPERTY_VALUE; import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_TASKBAR_ALIGNMENT_ANIM; import static com.android.launcher3.util.MultiTranslateDelegate.INDEX_TASKBAR_PINNING_ANIM; @@ -191,7 +189,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar public void init(TaskbarControllers controllers) { mControllers = controllers; mTaskbarView.init(new TaskbarViewCallbacks()); - mTaskbarView.getLayoutParams().height = isPhoneMode(mActivity.getDeviceProfile()) + mTaskbarView.getLayoutParams().height = mActivity.isPhoneMode() ? mActivity.getResources().getDimensionPixelSize(R.dimen.taskbar_phone_size) : mActivity.getDeviceProfile().taskbarHeight; @@ -219,7 +217,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar // This gets modified in NavbarButtonsViewController, but the initial value it reads // may be incorrect since it's state gets destroyed on taskbar recreate, so reset here mTaskbarIconAlpha.get(ALPHA_INDEX_SMALL_SCREEN) - .animateToValue(isPhoneButtonNavMode(mActivity) ? 0 : 1).start(); + .animateToValue(mActivity.isPhoneButtonNavMode() ? 0 : 1).start(); } if (enableTaskbarPinning()) { mTaskbarView.addOnLayoutChangeListener(mTaskbarViewLayoutChangeListener); @@ -598,7 +596,7 @@ public class TaskbarViewController implements TaskbarControllers.LoggableTaskbar * 1 => fully aligned */ public void setLauncherIconAlignment(float alignmentRatio, DeviceProfile launcherDp) { - if (isPhoneMode(launcherDp)) { + if (mActivity.isPhoneMode()) { mIconAlignControllerLazy = null; return; } diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/KidsNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/KidsNavLayoutter.kt index 3f51958402..65b77ac31c 100644 --- a/quickstep/src/com/android/launcher3/taskbar/navbutton/KidsNavLayoutter.kt +++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/KidsNavLayoutter.kt @@ -24,8 +24,8 @@ import android.view.ViewGroup import android.widget.FrameLayout import android.widget.ImageView import android.widget.LinearLayout -import com.android.launcher3.DeviceProfile import com.android.launcher3.R +import com.android.launcher3.taskbar.TaskbarActivityContext import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.* import com.android.systemui.shared.rotation.RotationButton @@ -48,7 +48,7 @@ class KidsNavLayoutter( a11yButton ) { - override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) { + override fun layoutButtons(context: TaskbarActivityContext, isA11yButtonPersistent: Boolean) { val iconSize: Int = resources.getDimensionPixelSize(DIMEN_TASKBAR_ICON_SIZE_KIDS) val buttonWidth: Int = resources.getDimensionPixelSize(DIMEN_TASKBAR_NAV_BUTTONS_WIDTH_KIDS) val buttonHeight: Int = diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt index 6b05e9a891..22f0131bb2 100644 --- a/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt +++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/NavButtonLayoutFactory.kt @@ -24,6 +24,7 @@ import android.widget.FrameLayout import android.widget.ImageView import android.widget.LinearLayout import com.android.launcher3.DeviceProfile +import com.android.launcher3.taskbar.TaskbarActivityContext import com.android.launcher3.taskbar.navbutton.LayoutResourceHelper.* import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.Companion import com.android.launcher3.taskbar.navbutton.NavButtonLayoutFactory.NavButtonLayoutter @@ -162,6 +163,6 @@ class NavButtonLayoutFactory { /** Lays out and provides access to the home, recents, and back buttons for various mischief */ interface NavButtonLayoutter { - fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) + fun layoutButtons(context: TaskbarActivityContext, isA11yButtonPersistent: Boolean) } } diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneGestureLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneGestureLayoutter.kt index 5a7bc4969c..3817f91ec1 100644 --- a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneGestureLayoutter.kt +++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneGestureLayoutter.kt @@ -20,7 +20,7 @@ import android.content.res.Resources import android.view.ViewGroup import android.widget.ImageView import android.widget.LinearLayout -import com.android.launcher3.DeviceProfile +import com.android.launcher3.taskbar.TaskbarActivityContext import com.android.systemui.shared.rotation.RotationButton /** Layoutter for showing gesture navigation on phone screen. No buttons here, no-op container */ @@ -43,7 +43,7 @@ class PhoneGestureLayoutter( a11yButton ) { - override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) { + override fun layoutButtons(context: TaskbarActivityContext, isA11yButtonPersistent: Boolean) { endContextualContainer.removeAllViews() startContextualContainer.removeAllViews() } diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt index 382e29832d..7583cc1761 100644 --- a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt +++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhoneLandscapeNavLayoutter.kt @@ -23,9 +23,8 @@ import android.widget.FrameLayout import android.widget.ImageView import android.widget.LinearLayout import androidx.core.view.children -import com.android.launcher3.DeviceProfile import com.android.launcher3.R -import com.android.launcher3.taskbar.TaskbarManager +import com.android.launcher3.taskbar.TaskbarActivityContext import com.android.launcher3.util.DimensionUtils import com.android.systemui.shared.rotation.RotationButton @@ -48,11 +47,11 @@ open class PhoneLandscapeNavLayoutter( a11yButton ) { - override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) { + override fun layoutButtons(context: TaskbarActivityContext, isA11yButtonPersistent: Boolean) { // TODO(b/230395757): Polish pending, this is just to make it usable val endStartMargins = resources.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size) - val taskbarDimensions = DimensionUtils.getTaskbarPhoneDimensions(dp, resources, - TaskbarManager.isPhoneMode(dp)) + val taskbarDimensions = DimensionUtils.getTaskbarPhoneDimensions(context.deviceProfile, + resources, context.isPhoneMode) navButtonContainer.removeAllViews() navButtonContainer.orientation = LinearLayout.VERTICAL diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt index e1ffa4dabf..4388ce617f 100644 --- a/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt +++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/PhonePortraitNavLayoutter.kt @@ -22,9 +22,8 @@ import android.view.ViewGroup import android.widget.FrameLayout import android.widget.ImageView import android.widget.LinearLayout -import com.android.launcher3.DeviceProfile import com.android.launcher3.R -import com.android.launcher3.taskbar.TaskbarManager +import com.android.launcher3.taskbar.TaskbarActivityContext import com.android.launcher3.util.DimensionUtils import com.android.systemui.shared.rotation.RotationButton @@ -47,11 +46,11 @@ class PhonePortraitNavLayoutter( a11yButton ) { - override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) { + override fun layoutButtons(context: TaskbarActivityContext, isA11yButtonPersistent: Boolean) { // TODO(b/230395757): Polish pending, this is just to make it usable val taskbarDimensions = - DimensionUtils.getTaskbarPhoneDimensions(dp, resources, - TaskbarManager.isPhoneMode(dp)) + DimensionUtils.getTaskbarPhoneDimensions(context.deviceProfile, resources, + context.isPhoneMode) val endStartMargins = resources.getDimensionPixelSize(R.dimen.taskbar_nav_buttons_size) // Ensure order of buttons is correct diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt index abdd32c712..1ac00608d6 100644 --- a/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt +++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/SetupNavLayoutter.kt @@ -22,8 +22,8 @@ import android.view.ViewGroup import android.widget.FrameLayout import android.widget.ImageView import android.widget.LinearLayout -import com.android.launcher3.DeviceProfile import com.android.launcher3.R +import com.android.launcher3.taskbar.TaskbarActivityContext import com.android.systemui.shared.rotation.RotationButton class SetupNavLayoutter( @@ -45,7 +45,7 @@ class SetupNavLayoutter( a11yButton ) { - override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) { + override fun layoutButtons(context: TaskbarActivityContext, isA11yButtonPersistent: Boolean) { // Since setup wizard only has back button enabled, it looks strange to be // end-aligned, so start-align instead. val navButtonsLayoutParams = navButtonContainer.layoutParams as FrameLayout.LayoutParams diff --git a/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt b/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt index f5a4c64fd5..5465b6bbc9 100644 --- a/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt +++ b/quickstep/src/com/android/launcher3/taskbar/navbutton/TaskbarNavLayoutter.kt @@ -22,8 +22,8 @@ import android.view.ViewGroup import android.widget.FrameLayout import android.widget.ImageView import android.widget.LinearLayout -import com.android.launcher3.DeviceProfile import com.android.launcher3.R +import com.android.launcher3.taskbar.TaskbarActivityContext import com.android.systemui.shared.rotation.RotationButton /** @@ -48,9 +48,11 @@ class TaskbarNavLayoutter( a11yButton ) { - override fun layoutButtons(dp: DeviceProfile, isA11yButtonPersistent: Boolean) { + override fun layoutButtons(context: TaskbarActivityContext, isA11yButtonPersistent: Boolean) { // Add spacing after the end of the last nav button - var navMarginEnd = resources.getDimension(dp.inv.inlineNavButtonsEndSpacing).toInt() + var navMarginEnd = resources + .getDimension(context.deviceProfile.inv.inlineNavButtonsEndSpacing) + .toInt() val contextualWidth = endContextualContainer.width // If contextual buttons are showing, we check if the end margin is enough for the // contextual button to be showing - if not, move the nav buttons over a smidge @@ -91,7 +93,7 @@ class TaskbarNavLayoutter( endContextualContainer.removeAllViews() startContextualContainer.removeAllViews() - if (!dp.isGestureMode) { + if (!context.deviceProfile.isGestureMode) { val contextualMargin = resources.getDimensionPixelSize( R.dimen.taskbar_contextual_button_padding) repositionContextualContainer(endContextualContainer, 0, Gravity.END) diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index bd4625b7f7..d1d2f972ba 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -974,8 +974,8 @@ public class TouchInteractionService extends Service { TaskbarActivityContext tac = mTaskbarManager.getCurrentActivityContext(); if (tac != null && !(base instanceof AssistantInputConsumer)) { // Present always on large screen or on small screen w/ flag - DeviceProfile dp = tac.getDeviceProfile(); - boolean useTaskbarConsumer = dp.isTaskbarPresent && !TaskbarManager.isPhoneMode(dp) + boolean useTaskbarConsumer = tac.getDeviceProfile().isTaskbarPresent + && !tac.isPhoneMode() && !tac.isInStashedLauncherState(); if (canStartSystemGesture && useTaskbarConsumer) { reasonString.append(NEWLINE_PREFIX) -- GitLab From 734c6f3974b6cc6cf22ea27d80332d33dd4639ca Mon Sep 17 00:00:00 2001 From: Winson Chung Date: Fri, 15 Dec 2023 05:08:53 +0000 Subject: [PATCH 015/577] Workaround for handling single device specific state in dump tests - There's a DeviceProfile state that is dynamic on a specific device class (based on a fw resource), this causes problems with the dump tests which compare the device profile against static prior dumps. For now, we can just update the expected dump based on the state of the resource to ensure that the current device profile state on this device matches. To do this, we also need to consolidate the various duplicate methods to assert the current and golden dumps match to have a common place to adjust the expected dump. Bug: 315230497 Test: atest DeviceProfileDumpTest Test: atest DeviceProfileAlternativeDisplaysDumpTest Change-Id: I5130d330878757702af07e166a669cc76452b271 --- .../launcher3/AbstractDeviceProfileTest.kt | 30 +++++++++++++++++++ .../nonquickstep/DeviceProfileDumpTest.kt | 6 +--- 2 files changed, 31 insertions(+), 5 deletions(-) diff --git a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt b/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt index e46726dc50..d44ccf57d5 100644 --- a/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt +++ b/tests/src/com/android/launcher3/AbstractDeviceProfileTest.kt @@ -17,11 +17,13 @@ package com.android.launcher3 import android.content.Context import android.content.res.Configuration +import android.content.res.Resources import android.graphics.Point import android.graphics.Rect import android.util.DisplayMetrics import android.view.Surface import androidx.test.core.app.ApplicationProvider +import androidx.test.platform.app.InstrumentationRegistry import com.android.launcher3.testing.shared.ResourceUtils import com.android.launcher3.util.DisplayController import com.android.launcher3.util.MainThreadInitializedObject.SandboxContext @@ -30,6 +32,8 @@ import com.android.launcher3.util.WindowBounds import com.android.launcher3.util.rule.TestStabilityRule import com.android.launcher3.util.window.CachedDisplayInfo import com.android.launcher3.util.window.WindowManagerProxy +import com.android.wm.shell.Flags +import com.google.common.truth.Truth import java.io.BufferedReader import java.io.File import java.io.PrintWriter @@ -49,11 +53,18 @@ import org.mockito.kotlin.whenever * For an implementation that mocks InvariantDeviceProfile, use [FakeInvariantDeviceProfileTest] */ abstract class AbstractDeviceProfileTest { + protected val testContext: Context = InstrumentationRegistry.getInstrumentation().context protected lateinit var context: SandboxContext protected open val runningContext: Context = ApplicationProvider.getApplicationContext() private val displayController: DisplayController = mock() private val windowManagerProxy: WindowManagerProxy = mock() private val launcherPrefs: LauncherPrefs = mock() + private val allowLeftRightSplitInPortrait: Boolean = initAllowLeftRightSplitInPortrait() + fun initAllowLeftRightSplitInPortrait() : Boolean { + val res = Resources.getSystem(); + val resId = res.getIdentifier("config_leftRightSplitInPortrait", "bool", "android") + return Flags.enableLeftRightSplitInPortrait() && resId > 0 && res.getBoolean(resId) + } @Rule @JvmField val testStabilityRule = TestStabilityRule() @@ -306,6 +317,25 @@ abstract class AbstractDeviceProfileTest { whenever(info.isTransientTaskbar).thenReturn(isGestureMode) } + /** Asserts that the given device profile matches a previously dumped device profile state. */ + protected fun assertDump(dp: DeviceProfile, folderName: String, filename: String) { + val dump = dump(context!!, dp, "${folderName}_$filename.txt") + var expected = readDumpFromAssets(testContext, "$folderName/$filename.txt") + + // TODO(b/315230497): We don't currently have device-specific device profile dumps, so just + // update the result before we do the comparison + if (allowLeftRightSplitInPortrait) { + val isLeftRightSplitInPortrait = when { + allowLeftRightSplitInPortrait && dp.isTablet -> !dp.isLandscape + else -> dp.isLandscape + } + expected = expected.replace(Regex("isLeftRightSplit:\\w+"), + "isLeftRightSplit:$isLeftRightSplitInPortrait") + } + + Truth.assertThat(dump).isEqualTo(expected) + } + /** Create a new dump of DeviceProfile, saves to a file in the device and returns it */ protected fun dump(context: Context, dp: DeviceProfile, fileName: String): String { val stringWriter = StringWriter() diff --git a/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt b/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt index 9b67310314..9409ac1c1a 100644 --- a/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt +++ b/tests/src/com/android/launcher3/nonquickstep/DeviceProfileDumpTest.kt @@ -30,7 +30,6 @@ import org.junit.runner.RunWith @SmallTest @RunWith(AndroidJUnit4::class) class DeviceProfileDumpTest : AbstractDeviceProfileTest() { - private val testContext: Context = InstrumentationRegistry.getInstrumentation().context private val folderName: String = "DeviceProfileDumpTest" @Test fun phonePortrait3Button() { @@ -154,9 +153,6 @@ class DeviceProfileDumpTest : AbstractDeviceProfileTest() { } private fun assertDump(dp: DeviceProfile, filename: String) { - val dump = dump(context!!, dp, "${folderName}_$filename.txt") - val expected = readDumpFromAssets(testContext, "$folderName/$filename.txt") - - assertThat(dump).isEqualTo(expected) + assertDump(dp, folderName, filename); } } -- GitLab From 9330619ee01b42e86418380c1b74923f9dc0a3ac Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Thu, 14 Dec 2023 13:53:29 +0900 Subject: [PATCH 016/577] Fixes crash when launching app pairs with intent+intent This CL adds a new case for app pair launches. When we launch app pairs with intents, we receive initialTaskId and secondTaskId as -1, which was previously unhandled and caused a crash. With this change, we find the left/top app leash a different way, by looking for windowingMode=WINDOWING_MODE_MULTI_WINDOW and endAbsBounds.left/top == 0. Fixes: 316050315 Test: Clear all running tasks from Overview, launch app pair, no longer crashes Flag: ACONFIG com.android.wm.shell.enable_app_pairs DEVELOPMENT Change-Id: Ic356d71ad267f079242213ebc59322bf1fb86b7c --- .../util/SplitAnimationController.kt | 96 ++++++++++--------- .../util/SplitAnimationControllerTest.kt | 4 +- 2 files changed, 55 insertions(+), 45 deletions(-) diff --git a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt index ade8074d8b..b2d1b43765 100644 --- a/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt +++ b/quickstep/src/com/android/quickstep/util/SplitAnimationController.kt @@ -23,6 +23,7 @@ import android.animation.AnimatorSet import android.animation.ObjectAnimator import android.animation.ValueAnimator import android.app.ActivityManager.RunningTaskInfo +import android.app.WindowConfiguration.WINDOWING_MODE_MULTI_WINDOW import android.graphics.Bitmap import android.graphics.Rect import android.graphics.RectF @@ -31,9 +32,11 @@ import android.view.RemoteAnimationTarget import android.view.SurfaceControl import android.view.SurfaceControl.Transaction import android.view.View -import android.view.WindowManager +import android.view.WindowManager.TRANSIT_OPEN +import android.view.WindowManager.TRANSIT_TO_FRONT import android.window.TransitionInfo import android.window.TransitionInfo.Change +import android.window.WindowContainerToken import androidx.annotation.VisibleForTesting import com.android.app.animation.Interpolators import com.android.launcher3.DeviceProfile @@ -387,14 +390,7 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC "trying to launch an app pair icon, but encountered an unexpected null" } - composeIconSplitLaunchAnimator( - launchingIconView, - initialTaskId, - secondTaskId, - info, - t, - finishCallback - ) + composeIconSplitLaunchAnimator(launchingIconView, info, t, finishCallback) } else { // Fallback case: simple fade-in animation check(info != null && t != null) { @@ -461,12 +457,27 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC /** * When the user taps an app pair icon to launch split, this will play the tasks' launch * animation from the position of the icon. + * + * To find the root shell leash that we want to fade in, we do the following: + * The Changes we receive in transitionInfo are structured like this + * + * Root (grandparent) + * | + * |--> Split Root 1 (left/top side parent) (WINDOWING_MODE_MULTI_WINDOW) + * | | + * | --> App 1 (left/top side child) (WINDOWING_MODE_MULTI_WINDOW) + * |--> Divider + * |--> Split Root 2 (right/bottom side parent) (WINDOWING_MODE_MULTI_WINDOW) + * | + * --> App 2 (right/bottom side child) (WINDOWING_MODE_MULTI_WINDOW) + * + * We want to animate the Root (grandparent) so that it affects both apps and the divider. + * To do this, we find one of the nodes with WINDOWING_MODE_MULTI_WINDOW (one of the + * left-side ones, for simplicity) and traverse the tree until we find the grandparent. */ @VisibleForTesting fun composeIconSplitLaunchAnimator( launchingIconView: AppPairIcon, - initialTaskId: Int, - secondTaskId: Int, transitionInfo: TransitionInfo, t: Transaction, finishCallback: Runnable @@ -481,45 +492,46 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC progressUpdater.setDuration(timings.getDuration().toLong()) progressUpdater.interpolator = Interpolators.LINEAR - // Find the root shell leash that we want to fade in (parent of both app windows and - // the divider). For simplicity, we search using the initialTaskId. - var rootShellLayer: SurfaceControl? = null - var dividerPos = 0 + var rootCandidate: Change? = null for (change in transitionInfo.changes) { val taskInfo: RunningTaskInfo = change.taskInfo ?: continue - val taskId = taskInfo.taskId - val mode = change.mode - if (taskId == initialTaskId || taskId == secondTaskId) { - check( - mode == WindowManager.TRANSIT_OPEN || mode == WindowManager.TRANSIT_TO_FRONT - ) { - "Expected task to be showing, but it is $mode" + // TODO (b/316490565): Replace this logic when SplitBounds is available to + // startAnimation() and we can know the precise taskIds of launching tasks. + // Find a change that has WINDOWING_MODE_MULTI_WINDOW. + if (taskInfo.windowingMode == WINDOWING_MODE_MULTI_WINDOW && + (change.mode == TRANSIT_OPEN || change.mode == TRANSIT_TO_FRONT)) { + // Check if it is a left/top app. + val isLeftTopApp = + (dp.isLeftRightSplit && change.endAbsBounds.left == 0) || + (!dp.isLeftRightSplit && change.endAbsBounds.top == 0) + if (isLeftTopApp) { + // Found one! + rootCandidate = change + break } } + } - if (taskId == initialTaskId) { - var splitRoot1 = change - val parentToken = change.parent - if (parentToken != null) { - splitRoot1 = transitionInfo.getChange(parentToken) ?: change - } + // If we could not find a proper root candidate, something went wrong. + check(rootCandidate != null) { "Could not find a split root candidate" } - val topLevelToken = splitRoot1.parent - if (topLevelToken != null) { - rootShellLayer = transitionInfo.getChange(topLevelToken)?.leash - } + // Find the place where our left/top app window meets the divider (used for the + // launcher side animation) + val dividerPos = + if (dp.isLeftRightSplit) rootCandidate.endAbsBounds.right + else rootCandidate.endAbsBounds.bottom - dividerPos = - if (dp.isLeftRightSplit) change.endAbsBounds.right - else change.endAbsBounds.bottom - } + // Recurse up the tree until parent is null, then we've found our root. + var parentToken: WindowContainerToken? = rootCandidate.parent + while (parentToken != null) { + rootCandidate = transitionInfo.getChange(parentToken) ?: break + parentToken = rootCandidate.parent } - check(rootShellLayer != null) { - "Could not find a TransitionInfo.Change matching the initialTaskId" - } + // Make sure nothing weird happened, like getChange() returning null. + check(rootCandidate != null) { "Failed to find a root leash" } // Shell animation: the apps are revealed toward end of the launch animation progressUpdater.addUpdateListener { valueAnimator: ValueAnimator -> @@ -532,7 +544,7 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC ) // Set the alpha of the shell layer (2 apps + divider) - t.setAlpha(rootShellLayer, progress) + t.setAlpha(rootCandidate.leash, progress) t.apply() } @@ -651,9 +663,7 @@ class SplitAnimationController(val splitSelectStateController: SplitSelectStateC // Find the target tasks' root tasks since those are the split stages that need to // be animated (the tasks themselves are children and thus inherit animation). if (taskId == initialTaskId || taskId == secondTaskId) { - check( - mode == WindowManager.TRANSIT_OPEN || mode == WindowManager.TRANSIT_TO_FRONT - ) { + check(mode == TRANSIT_OPEN || mode == TRANSIT_TO_FRONT) { "Expected task to be showing, but it is $mode" } } diff --git a/quickstep/tests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt b/quickstep/tests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt index 86018b1783..929bd8e8af 100644 --- a/quickstep/tests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt +++ b/quickstep/tests/src/com/android/quickstep/util/SplitAnimationControllerTest.kt @@ -249,7 +249,7 @@ class SplitAnimationControllerTest { val spySplitAnimationController = spy(splitAnimationController) doNothing() .whenever(spySplitAnimationController) - .composeIconSplitLaunchAnimator(any(), any(), any(), any(), any(), any()) + .composeIconSplitLaunchAnimator(any(), any(), any(), any()) spySplitAnimationController.playSplitLaunchAnimation( null /* launchingTaskView */, @@ -267,7 +267,7 @@ class SplitAnimationControllerTest { ) verify(spySplitAnimationController) - .composeIconSplitLaunchAnimator(any(), any(), any(), any(), any(), any()) + .composeIconSplitLaunchAnimator(any(), any(), any(), any()) } @Test -- GitLab From b4626f46986e12fcc914b545ab2e1636faee3942 Mon Sep 17 00:00:00 2001 From: helencheuk Date: Mon, 11 Dec 2023 11:33:30 +0000 Subject: [PATCH 017/577] Add focus outline to launcher Fix: 310953377 Test: TBC Flag: ACONFIG com.android.launcher3.enable_focus_outline Development Change-Id: Ie395ec74c8a4a13a68539ca7ec6496481d96b860 --- aconfig/launcher.aconfig | 7 +++++++ res/layout/folder_icon.xml | 3 ++- res/values/colors.xml | 1 + res/values/dimens.xml | 3 +++ .../keyboard/FocusIndicatorHelper.java | 17 +++++++++++++++-- .../keyboard/ItemFocusIndicatorHelper.java | 16 +++++++++++++--- 6 files changed, 41 insertions(+), 6 deletions(-) diff --git a/aconfig/launcher.aconfig b/aconfig/launcher.aconfig index af175ce921..210cfd02bb 100644 --- a/aconfig/launcher.aconfig +++ b/aconfig/launcher.aconfig @@ -42,6 +42,13 @@ flag { bug: "257950105" } +flag { + name: "enable_focus_outline" + namespace: "launcher" + description: "Enables focus states outline for launcher." + bug: "310953377" +} + flag { name: "enable_taskbar_no_recreate" namespace: "launcher" diff --git a/res/layout/folder_icon.xml b/res/layout/folder_icon.xml index 4093744628..6af346e042 100644 --- a/res/layout/folder_icon.xml +++ b/res/layout/folder_icon.xml @@ -19,7 +19,8 @@ android:layout_width="match_parent" android:layout_height="match_parent" android:orientation="vertical" - android:focusable="true" > + android:focusable="true" + android:defaultFocusHighlightEnabled="false"> #FFF0592B #80c6c5c5 + @color/material_color_on_secondary_container #FF000000 diff --git a/res/values/dimens.xml b/res/values/dimens.xml index 242c4396a5..7c0526b6b0 100644 --- a/res/values/dimens.xml +++ b/res/values/dimens.xml @@ -432,6 +432,9 @@ 60dp 8dp + 16dp + 3dp + 16dp 6dp diff --git a/src/com/android/launcher3/keyboard/FocusIndicatorHelper.java b/src/com/android/launcher3/keyboard/FocusIndicatorHelper.java index 83003ffb14..1a7d79755f 100644 --- a/src/com/android/launcher3/keyboard/FocusIndicatorHelper.java +++ b/src/com/android/launcher3/keyboard/FocusIndicatorHelper.java @@ -20,6 +20,7 @@ import android.graphics.Rect; import android.view.View; import android.view.View.OnFocusChangeListener; +import com.android.launcher3.Flags; import com.android.launcher3.R; /** @@ -29,7 +30,8 @@ public abstract class FocusIndicatorHelper extends ItemFocusIndicatorHelper implements AnimatorUpdateListe mContainer = container; mPaint = new Paint(Paint.ANTI_ALIAS_FLAG); - mMaxAlpha = Color.alpha(color); mPaint.setColor(0xFF000000 | color); + if (Flags.enableFocusOutline()) { + mPaint.setStyle(Paint.Style.STROKE); + mPaint.setStrokeWidth(container.getResources().getDimensionPixelSize( + R.dimen.focus_outline_stroke_width)); + mRadius = container.getResources().getDimensionPixelSize( + R.dimen.focus_outline_radius); + } else { + mPaint.setStyle(Paint.Style.FILL); + mRadius = container.getResources().getDimensionPixelSize( + R.dimen.grid_visualization_rounding_radius); + } + mMaxAlpha = Color.alpha(color); setAlpha(0); mShift = 0; - mRadius = container.getResources().getDimensionPixelSize( - R.dimen.grid_visualization_rounding_radius); } protected void setAlpha(float alpha) { -- GitLab From ea2a13a03a09ccfe95496805451f82c6247f269f Mon Sep 17 00:00:00 2001 From: Pat Manning Date: Fri, 15 Dec 2023 17:30:03 +0000 Subject: [PATCH 018/577] Do not process stashed taskbar hover actions when taskbar is not present. Fix: 306745595 Test: Manual. Flag: ACONFIG com.android.launcher3.enable_cursor_hover_states NEXTFOOD. Change-Id: I419e4dcbea6f615b0bf9521fb34c9c5df65df8ef --- .../android/quickstep/TouchInteractionService.java | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java index d1d2f972ba..86ba7ef49a 100644 --- a/quickstep/src/com/android/quickstep/TouchInteractionService.java +++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java @@ -86,7 +86,6 @@ import androidx.annotation.UiThread; import com.android.launcher3.BaseDraggingActivity; import com.android.launcher3.ConstantItem; -import com.android.launcher3.DeviceProfile; import com.android.launcher3.EncryptionType; import com.android.launcher3.LauncherPrefs; import com.android.launcher3.R; @@ -725,8 +724,7 @@ public class TouchInteractionService extends Service { final int action = event.getActionMasked(); // Note this will create a new consumer every mouse click, as after ACTION_UP from the click // an ACTION_HOVER_ENTER will fire as well. - boolean isHoverActionWithoutConsumer = - event.isHoverEvent() && (mUncheckedConsumer.getType() & TYPE_CURSOR_HOVER) == 0; + boolean isHoverActionWithoutConsumer = isHoverActionWithoutConsumer(event); CompoundString reasonString = action == ACTION_DOWN ? new CompoundString("onMotionEvent: ") : CompoundString.NO_OP; if (action == ACTION_DOWN || isHoverActionWithoutConsumer) { @@ -846,6 +844,15 @@ public class TouchInteractionService extends Service { traceToken.close(); } + private boolean isHoverActionWithoutConsumer(MotionEvent event) { + // Only process these events when taskbar is present. + TaskbarActivityContext tac = mTaskbarManager.getCurrentActivityContext(); + boolean isTaskbarPresent = tac != null && tac.getDeviceProfile().isTaskbarPresent + && !tac.isPhoneMode(); + return event.isHoverEvent() && (mUncheckedConsumer.getType() & TYPE_CURSOR_HOVER) == 0 + && isTaskbarPresent; + } + // Talkback generates hover events on touch, which we do not want to consume. private boolean isCursorHoverEvent(MotionEvent event) { return event.isHoverEvent() && event.getSource() == InputDevice.SOURCE_MOUSE; -- GitLab From 971358567def299d737c4c49736c333003d3b7c5 Mon Sep 17 00:00:00 2001 From: Vadim Tryshev Date: Fri, 15 Dec 2023 10:32:35 -0800 Subject: [PATCH 019/577] Disabling a failing test from presubmit Bug: 316588649 Test: presubmit Flag: N/A Change-Id: I98487a4786fdab7f0ee5b10d59fc8df0e621b4f0 --- tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt b/tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt index b4591baa17..bfc08b7680 100644 --- a/tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt +++ b/tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt @@ -18,6 +18,7 @@ package com.android.launcher3.util import android.testing.AndroidTestingRunner import androidx.test.filters.SmallTest +import com.android.launcher3.util.rule.TestStabilityRule import java.util.concurrent.ExecutorService import junit.framework.Assert.assertEquals import junit.framework.Assert.assertFalse @@ -65,6 +66,9 @@ class ExecutorRunnableTest { } @Test + @TestStabilityRule.Stability( + flavors = TestStabilityRule.LOCAL or TestStabilityRule.PLATFORM_POSTSUBMIT + ) // b/316588649 fun run_and_cancel_cancelCallback() { underTest.cancel(true) awaitAllExecutorCompleted() -- GitLab From e392955e3716f984cc171101eb0bf43288daf977 Mon Sep 17 00:00:00 2001 From: fbaron Date: Fri, 15 Dec 2023 11:30:58 -0800 Subject: [PATCH 020/577] Stop interrupt to see if it fixes failing tests Bug: 316394228 Test: atest WidgetsListContentEntryTest Flag: NONE Change-Id: Iaabbcb0c00040f78ad4d6355fef9bc91f4b66ed7 --- .../android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt | 2 +- tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt b/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt index cbc6f4434e..71957e165b 100644 --- a/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt +++ b/src/com/android/launcher3/recyclerview/AllAppsRecyclerViewPool.kt @@ -62,7 +62,7 @@ class AllAppsRecyclerViewPool : RecycledViewPool() { override fun getLayoutManager(): RecyclerView.LayoutManager? = null } - executorRunnable?.cancel(/* interrupt= */ true) + executorRunnable?.cancel(/* interrupt= */ false) executorRunnable = ExecutorRunnable.createAndExecute( VIEW_PREINFLATION_EXECUTOR, diff --git a/tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt b/tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt index b4591baa17..4760cd8af4 100644 --- a/tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt +++ b/tests/src/com/android/launcher3/util/ExecutorRunnableTest.kt @@ -66,7 +66,7 @@ class ExecutorRunnableTest { @Test fun run_and_cancel_cancelCallback() { - underTest.cancel(true) + underTest.cancel(false) awaitAllExecutorCompleted() assertFalse(isCallbackExecuted) @@ -77,7 +77,7 @@ class ExecutorRunnableTest { fun run_and_cancelAfterCompletion_executeAll() { awaitAllExecutorCompleted() - underTest.cancel(true) + underTest.cancel(false) assertTrue(isTaskExecuted) assertTrue(isCallbackExecuted) -- GitLab From 447ddf0b63f448c5ba9d984f3c3f808a12e58593 Mon Sep 17 00:00:00 2001 From: Liran Binyamin Date: Fri, 15 Dec 2023 15:43:09 -0500 Subject: [PATCH 021/577] Make BubbleBarView initially hidden The BubbleBarView visibility is updated as part of the initial state change. This CL fixes the issue where switching from floating bubbles to bubble bar ends up in a state where both the handle and the bar are visible. Note: once the initial TAPL tests land I will add a test for mode switching Flag: LEGACY persist.wm.debug.bubble_bar DISABLED Fixes: 316356971 Test: Manual - Add bubble in floating mode - Switch to bubble bar - Observe that the bubble bar is not visible (only the handle is) Change-Id: Ib8fc76f90dbf1fee83e594b7f28eed00f1589ae1 --- .../com/android/launcher3/taskbar/bubbles/BubbleBarView.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java index c482911ae8..ec9f4e5567 100644 --- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java +++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java @@ -130,6 +130,8 @@ public class BubbleBarView extends FrameLayout { super(context, attrs, defStyleAttr, defStyleRes); TaskbarActivityContext activityContext = ActivityContext.lookupContext(context); + setAlpha(0); + setVisibility(INVISIBLE); mIconOverlapAmount = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_overlap); mIconSpacing = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_spacing); mIconSize = getResources().getDimensionPixelSize(R.dimen.bubblebar_icon_size); -- GitLab From 149dc53f85a07f90e4b79a51de5e0b1be5e89bc0 Mon Sep 17 00:00:00 2001 From: Vadim Tryshev Date: Fri, 15 Dec 2023 13:57:05 -0800 Subject: [PATCH 022/577] Waiting for Launcher stop from quick switch gesture Bug: 313926097 Flag: N/A Test: presubmit Change-Id: I31ae3af36b71c73ed4750b92ccc3704df9714ea6 --- tests/tapl/com/android/launcher3/tapl/Background.java | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) diff --git a/tests/tapl/com/android/launcher3/tapl/Background.java b/tests/tapl/com/android/launcher3/tapl/Background.java index 8713b689f3..9f2ce22e23 100644 --- a/tests/tapl/com/android/launcher3/tapl/Background.java +++ b/tests/tapl/com/android/launcher3/tapl/Background.java @@ -16,8 +16,6 @@ package com.android.launcher3.tapl; -import static android.view.accessibility.AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED; - import static com.android.launcher3.tapl.OverviewTask.TASK_START_EVENT; import static com.android.launcher3.testing.shared.TestProtocol.OVERVIEW_STATE_ORDINAL; @@ -244,12 +242,11 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine endY = startY; } - mLauncher.executeAndWaitForEvent( + mLauncher.executeAndWaitForLauncherStop( () -> mLauncher.linearGesture( startX, startY, endX, endY, 20, false, LauncherInstrumentation.GestureScope.EXPECT_PILFER), - event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED, - () -> "Quick switch gesture didn't change window state", "swiping"); + "swiping"); } else { // Double press the recents button. UiObject2 recentsButton = mLauncher.waitForNavigationUiObject("recent_apps"); @@ -258,10 +255,8 @@ public abstract class Background extends LauncherInstrumentation.VisibleContaine "clicking Recents button for the first time"); mLauncher.getOverview(); mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, SQUARE_BUTTON_EVENT); - mLauncher.executeAndWaitForEvent( + mLauncher.executeAndWaitForLauncherStop( () -> recentsButton.click(), - event -> event.getEventType() == TYPE_WINDOW_STATE_CHANGED, - () -> "Pressing recents button didn't change window state", "clicking Recents button for the second time"); } mLauncher.expectEvent(TestProtocol.SEQUENCE_MAIN, TASK_START_EVENT); -- GitLab From e03af75df4b2b3fb9071284572d321785505fb4b Mon Sep 17 00:00:00 2001 From: fbaron Date: Fri, 15 Dec 2023 14:46:39 -0800 Subject: [PATCH 023/577] Remove unused flag UNFOLDED_WIDGET_PICKER this flag was made long before we actually implemented unfolded two pane picker and by that point we migrated to using aconfig so this flag is not used. Bug: 301918659 Flag: NONE Test: NONE Change-Id: Ibc541826d85ae251337567ae0275e1cd02c7bb43 --- src/com/android/launcher3/config/FeatureFlags.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/com/android/launcher3/config/FeatureFlags.java b/src/com/android/launcher3/config/FeatureFlags.java index 7dfce56f5e..f9d282ca09 100644 --- a/src/com/android/launcher3/config/FeatureFlags.java +++ b/src/com/android/launcher3/config/FeatureFlags.java @@ -169,10 +169,6 @@ public final class FeatureFlags { // TODO(Block 8): Clean up flags // TODO(Block 9): Clean up flags - public static final BooleanFlag UNFOLDED_WIDGET_PICKER = getDebugFlag(301918659, - "UNFOLDED_WIDGET_PICKER", DISABLED, "Enable new widget picker that takes " - + "advantage of the unfolded foldable format"); - public static final BooleanFlag MULTI_SELECT_EDIT_MODE = getDebugFlag(270709220, "MULTI_SELECT_EDIT_MODE", DISABLED, "Enable new multi-select edit mode " + "for home screen"); -- GitLab From de1e88da74314c59717aaa7589546baab23a1ef4 Mon Sep 17 00:00:00 2001 From: Vadim Tryshev Date: Sun, 17 Dec 2023 15:45:51 -0800 Subject: [PATCH 024/577] Waiting for Fallback Overview to stop after pressing Home Bug: 313926097 Flag: N/A Test: presubmit Change-Id: I1128ca6eabe29e02d8039445696f7a006f6448bf --- .../tests/src/com/android/quickstep/FallbackRecentsTest.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java index 39633eab1d..e0ee28dc02 100644 --- a/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java +++ b/quickstep/tests/src/com/android/quickstep/FallbackRecentsTest.java @@ -131,8 +131,7 @@ public class FallbackRecentsTest { UiDevice.getInstance(getInstrumentation()).executeShellCommand( getLauncherCommand(getLauncherInMyProcess())); // b/143488140 - mDevice.pressHome(); - mDevice.waitForIdle(); + pressHomeAndWaitForOverviewClose(); } } }; -- GitLab From e1fcb5390b3a59e57084f1d759000cbe358f7777 Mon Sep 17 00:00:00 2001 From: Jeremy Sim Date: Fri, 8 Dec 2023 18:43:02 -0800 Subject: [PATCH 025/577] App Pairs: Implement Overview Actions View button [App Pairs 6/?] This patch includes: - Ability to "save app pair" from Overview Actions - The actions bar is not longer hidden for GroupedTasks; instead the individual buttons for "Select", "Screenshot", and "Split screen" are toggled off and "Save app pair" is toggled on. Note: This patch introduces a slight regression (b/315545418) where users are now able to long-press to select text on task 1 of a paired GroupedTaskView (previously we did not let them select text on either task for consistency.) Will follow up with a fix -- see bug for details. Flag: ACONFIG com.android.wm.shell.enable_app_pairs DEVELOPMENT Bug: 315545418 Bug: 315292030 Test: Manual, all action buttons still work and "Save app pair" appears and disappears correctly Change-Id: I0eb1fa9520ba14074ede3480e771b340cf2f6e2c --- .../res/layout/overview_actions_container.xml | 9 ++ quickstep/res/values/strings.xml | 2 + .../android/quickstep/TaskOverlayFactory.java | 16 ++- .../quickstep/views/GroupedTaskView.java | 7 +- .../quickstep/views/OverviewActionsView.java | 102 +++++++++++++----- .../android/quickstep/views/RecentsView.java | 22 ++-- .../testing/TestInformationHandler.java | 6 ++ .../testing/shared/TestProtocol.java | 1 + .../android/launcher3/tapl/BaseOverview.java | 7 +- .../tapl/LauncherInstrumentation.java | 4 + 10 files changed, 137 insertions(+), 39 deletions(-) diff --git a/quickstep/res/layout/overview_actions_container.xml b/quickstep/res/layout/overview_actions_container.xml index 0fda0bf8d4..5bd5823094 100644 --- a/quickstep/res/layout/overview_actions_container.xml +++ b/quickstep/res/layout/overview_actions_container.xml @@ -55,6 +55,15 @@ android:theme="@style/ThemeControlHighlightWorkspaceColor" android:visibility="gone" /> +