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 43716abd978..477cd84444b 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 c30342ad4b7..8f5e2b66e16 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 2f62840679b..65269d49208 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 777f4d56860..aa5329b8d7d 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 eced5a9a411..00bf587e21c 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 6cbe1712e0c..25adb62d2fd 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 b4a5169c307..4f10287d40c 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 184ece74f5e..501c4c34d76 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 bb2f5335d23..893b1c8aa7c 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 c8da620e860..91e4ad55589 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 df6cad48ddc..789ef13f7dc 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 d40780c59f3..4c31d8738b4 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 9d5a55fa469..415d1f39a28 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 45174a70953..cbc6f4434e3 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 00000000000..49cf5925b8e --- /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 00000000000..b4591baa175 --- /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 4898761736f..f25b652d0ce 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 968faf07c7e..6d3b60a2037 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 2c937b008ed..d94cd8935a3 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 d7ff59e2eb2..42b18bdfb17 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 31fe791faa7..b2429ad3ece 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 341e18cc995..06a442b6dc6 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 11c5ab476a3..4e84f4a6c4b 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 bce2e82bbc7..cf9fc748191 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 e705285fa2f..28efc9748b0 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 fe6ce46072f..a36b32c1ede 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 4f89c7e7c2e..b4ca35e8fac 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 dd201af92fe..2ae64ffa632 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 87cee63f9eb..ca9d13e49f9 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 b7b0816e6e8..14d16835851 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 33304489196..7dcc8a86370 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 a1d80596313..5ef82ca897f 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 27fda9b6807..d75b387cc97 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 105bc3bf501..6387b05cc86 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 bed4c376ae5..709d3bac576 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 da1f7664203..ad2dc234a09 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 4290948ad2a..f6703f31396 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 d6016f13041..30f8d565048 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 a24cf4ba58e..f9fc9832c87 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 73e32abb2c6..3823c5a0985 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 6d1b55870f3..4776f0cb30d 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 057b71b74f7..a8506805b89 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 bbac11625d5..831bc1167d9 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 9aaa80f74c1..b3a8b935f13 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 2ab00665ed5..74517a8c69d 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 c0cbd45cc1c..33fb3954ea4 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 3f51958402e..65b77ac31c9 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 6b05e9a8911..22f0131bb2d 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 5a7bc4969ca..3817f91ec14 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 382e29832d3..7583cc17616 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 e1ffa4dabf0..4388ce617fe 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 abdd32c7127..1ac00608d6e 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 f5a4c64fd58..5465b6bbc92 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 bd4625b7f75..d1d2f972ba8 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 e46726dc50c..d44ccf57d52 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 9b67310314b..9409ac1c1ab 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 ade8074d8b0..b2d1b437657 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 86018b17834..929bd8e8af8 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 af175ce921e..210cfd02bb8 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 40937446286..6af346e042b 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 242c4396a5b..7c0526b6b0b 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 83003ffb143..1a7d79755f4 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 d1d2f972ba8..86ba7ef49a9 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 b4591baa175..bfc08b76801 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 cbc6f4434e3..71957e165b5 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 b4591baa175..4760cd8af41 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 c482911ae87..ec9f4e55678 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 8713b689f3b..9f2ce22e23f 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 7dfce56f5ea..f9d282ca098 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 39633eab1da..e0ee28dc02b 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 0fda0bf8d45..5bd5823094f 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" /> +