Merge "Scale bubble bar to the width of the handle" into main
diff --git a/Android.bp b/Android.bp
index b205d0c..4274613 100644
--- a/Android.bp
+++ b/Android.bp
@@ -221,7 +221,7 @@
android_library {
name: "launcher-aosp-tapl",
libs: [
- "framework-statsd",
+ "framework-statsd.stubs.module_lib",
],
static_libs: [
"androidx.annotation_annotation",
@@ -388,7 +388,7 @@
"quickstep/res",
],
libs: [
- "framework-statsd",
+ "framework-statsd.stubs.module_lib",
],
static_libs: [
"Launcher3ResLib",
@@ -453,7 +453,7 @@
],
resource_dirs: [],
libs: [
- "framework-statsd",
+ "framework-statsd.stubs.module_lib",
],
// Note the ordering here is important when it comes to resource
// overriding. We want the most specific resource overrides defined
diff --git a/quickstep/res/drawable/keyboard_quick_switch_overview_button_background.xml b/quickstep/res/drawable/keyboard_quick_switch_text_button_background.xml
similarity index 78%
rename from quickstep/res/drawable/keyboard_quick_switch_overview_button_background.xml
rename to quickstep/res/drawable/keyboard_quick_switch_text_button_background.xml
index 8180293..f204920 100644
--- a/quickstep/res/drawable/keyboard_quick_switch_overview_button_background.xml
+++ b/quickstep/res/drawable/keyboard_quick_switch_text_button_background.xml
@@ -15,8 +15,7 @@
-->
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
android:shape="rectangle">
- <solid android:color="?attr/materialColorSurfaceBright" />
- <corners android:radius="@dimen/keyboard_quick_switch_task_view_radius" />
+ <solid android:color="@android:color/white" />
+ <corners android:radius="@dimen/keyboard_quick_switch_text_button_radius" />
</shape>
diff --git a/quickstep/res/layout-land/keyboard_quick_switch_taskview.xml b/quickstep/res/layout-land/keyboard_quick_switch_taskview.xml
index 613edac..d1e5667 100644
--- a/quickstep/res/layout-land/keyboard_quick_switch_taskview.xml
+++ b/quickstep/res/layout-land/keyboard_quick_switch_taskview.xml
@@ -18,8 +18,8 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
- android:layout_width="@dimen/keyboard_quick_switch_taskview_width"
- android:layout_height="@dimen/keyboard_quick_switch_taskview_height"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:importantForAccessibility="yes"
android:background="@drawable/keyboard_quick_switch_task_view_background"
android:clipToOutline="true"
@@ -27,8 +27,8 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_width="@dimen/keyboard_quick_switch_taskview_width"
+ android:layout_height="@dimen/keyboard_quick_switch_taskview_height"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
@@ -52,7 +52,7 @@
android:layout_width="0dp"
android:layout_height="match_parent"
android:visibility="gone"
- android:layout_marginStart="@dimen/keyboard_quick_switch_split_view_spacing"
+ android:layout_marginStart="@dimen/keyboard_quick_switch_view_small_spacing"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
diff --git a/quickstep/res/layout-land/keyboard_quick_switch_taskview_square.xml b/quickstep/res/layout-land/keyboard_quick_switch_taskview_square.xml
new file mode 100644
index 0000000..0eccd8e
--- /dev/null
+++ b/quickstep/res/layout-land/keyboard_quick_switch_taskview_square.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2024 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<com.android.launcher3.taskbar.KeyboardQuickSwitchTaskView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:importantForAccessibility="yes"
+ android:background="@drawable/keyboard_quick_switch_task_view_background"
+ android:clipToOutline="true"
+ launcher:focusBorderColor="?androidprv:attr/materialColorOutline">
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/content"
+ android:layout_width="0dp"
+ android:layout_height="@dimen/keyboard_quick_switch_taskview_height"
+
+ app:layout_constraintDimensionRatio="1:1"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+
+ <include
+ layout="@layout/keyboard_quick_switch_taskview_thumbnail"
+ android:id="@+id/thumbnail_1"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/thumbnail_2"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <include
+ layout="@layout/keyboard_quick_switch_taskview_thumbnail"
+ android:id="@+id/thumbnail_2"
+ android:layout_width="match_parent"
+ android:layout_height="0dp"
+ android:visibility="gone"
+ android:layout_marginTop="@dimen/keyboard_quick_switch_view_small_spacing"
+
+ app:layout_constraintTop_toBottomOf="@id/thumbnail_1"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <ImageView
+ android:id="@+id/icon_1"
+ android:layout_width="@dimen/keyboard_quick_switch_taskview_icon_size"
+ android:layout_height="@dimen/keyboard_quick_switch_taskview_icon_size"
+ android:importantForAccessibility="no"
+ android:scaleType="centerCrop"
+
+ app:layout_constraintTop_toTopOf="@id/thumbnail_1"
+ app:layout_constraintBottom_toBottomOf="@id/thumbnail_1"
+ app:layout_constraintStart_toStartOf="@id/thumbnail_1"
+ app:layout_constraintEnd_toEndOf="@id/thumbnail_1"/>
+
+ <ImageView
+ android:id="@+id/icon_2"
+ android:layout_width="@dimen/keyboard_quick_switch_taskview_icon_size"
+ android:layout_height="@dimen/keyboard_quick_switch_taskview_icon_size"
+ android:importantForAccessibility="no"
+ android:visibility="gone"
+ android:scaleType="centerCrop"
+
+ app:layout_constraintTop_toTopOf="@id/thumbnail_2"
+ app:layout_constraintBottom_toBottomOf="@id/thumbnail_2"
+ app:layout_constraintStart_toStartOf="@id/thumbnail_2"
+ app:layout_constraintEnd_toEndOf="@id/thumbnail_2"/>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+</com.android.launcher3.taskbar.KeyboardQuickSwitchTaskView>
diff --git a/quickstep/res/layout/keyboard_quick_switch_textonly_taskview.xml b/quickstep/res/layout/keyboard_quick_switch_desktop_taskview.xml
similarity index 68%
rename from quickstep/res/layout/keyboard_quick_switch_textonly_taskview.xml
rename to quickstep/res/layout/keyboard_quick_switch_desktop_taskview.xml
index c76a2e3..c3f9e54 100644
--- a/quickstep/res/layout/keyboard_quick_switch_textonly_taskview.xml
+++ b/quickstep/res/layout/keyboard_quick_switch_desktop_taskview.xml
@@ -18,17 +18,20 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
- android:layout_width="@dimen/keyboard_quick_switch_taskview_width"
- android:layout_height="@dimen/keyboard_quick_switch_taskview_height"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:clipToOutline="true"
android:importantForAccessibility="yes"
- launcher:focusBorderColor="?attr/materialColorOutline">
+ launcher:focusBorderColor="?androidprv:attr/materialColorOutline"
+ launcher:focusBorderRadius="@dimen/keyboard_quick_switch_text_button_radius">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/keyboard_quick_switch_overview_button_background"
+ android:layout_width="@dimen/keyboard_quick_switch_text_button_width"
+ android:layout_height="@dimen/keyboard_quick_switch_taskview_height"
+ android:background="@drawable/keyboard_quick_switch_text_button_background"
+ android:backgroundTint="?androidprv:attr/materialColorSurfaceContainer"
+ android:paddingHorizontal="@dimen/keyboard_quick_switch_text_button_horizontal_padding"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
@@ -37,10 +40,11 @@
<ImageView
android:id="@+id/icon"
- android:layout_width="@dimen/keyboard_quick_switch_recents_icon_size"
- android:layout_height="@dimen/keyboard_quick_switch_recents_icon_size"
- android:layout_marginBottom="8dp"
- android:tint="?attr/materialColorOnSurface"
+ android:layout_width="@dimen/keyboard_quick_switch_desktop_icon_size"
+ android:layout_height="@dimen/keyboard_quick_switch_desktop_icon_size"
+ android:layout_marginBottom="4dp"
+ android:tint="?androidprv:attr/materialColorOnSurface"
+ android:src="@drawable/ic_desktop"
app:layout_constraintVertical_chainStyle="packed"
app:layout_constraintTop_toTopOf="parent"
@@ -49,9 +53,9 @@
app:layout_constraintEnd_toEndOf="parent"/>
<TextView
- style="@style/KeyboardQuickSwitchText"
+ style="@style/KeyboardQuickSwitchText.OnTaskView"
android:id="@+id/text"
- android:layout_width="wrap_content"
+ android:layout_width="match_parent"
android:layout_height="wrap_content"
android:textAlignment="center"
diff --git a/quickstep/res/layout/keyboard_quick_switch_textonly_taskview.xml b/quickstep/res/layout/keyboard_quick_switch_overview_taskview.xml
similarity index 62%
copy from quickstep/res/layout/keyboard_quick_switch_textonly_taskview.xml
copy to quickstep/res/layout/keyboard_quick_switch_overview_taskview.xml
index c76a2e3..0b44a2a 100644
--- a/quickstep/res/layout/keyboard_quick_switch_textonly_taskview.xml
+++ b/quickstep/res/layout/keyboard_quick_switch_overview_taskview.xml
@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2023 The Android Open Source Project
+<!-- Copyright (C) 2024 The Android Open Source Project
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -18,44 +18,47 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
- android:layout_width="@dimen/keyboard_quick_switch_taskview_width"
- android:layout_height="@dimen/keyboard_quick_switch_taskview_height"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:clipToOutline="true"
android:importantForAccessibility="yes"
- launcher:focusBorderColor="?attr/materialColorOutline">
+ launcher:focusBorderColor="?androidprv:attr/materialColorOutline"
+ launcher:focusBorderRadius="@dimen/keyboard_quick_switch_text_button_radius">
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
- android:background="@drawable/keyboard_quick_switch_overview_button_background"
+ android:layout_width="@dimen/keyboard_quick_switch_text_button_width"
+ android:layout_height="@dimen/keyboard_quick_switch_taskview_height"
+ android:background="@drawable/keyboard_quick_switch_text_button_background"
+ android:backgroundTint="?androidprv:attr/materialColorSurfaceBright"
+ android:paddingHorizontal="@dimen/keyboard_quick_switch_text_button_horizontal_padding"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent">
- <ImageView
- android:id="@+id/icon"
- android:layout_width="@dimen/keyboard_quick_switch_recents_icon_size"
- android:layout_height="@dimen/keyboard_quick_switch_recents_icon_size"
- android:layout_marginBottom="8dp"
- android:tint="?attr/materialColorOnSurface"
-
- app:layout_constraintVertical_chainStyle="packed"
- app:layout_constraintTop_toTopOf="parent"
- app:layout_constraintBottom_toTopOf="@id/text"
- app:layout_constraintStart_toStartOf="parent"
- app:layout_constraintEnd_toEndOf="parent"/>
-
<TextView
- style="@style/KeyboardQuickSwitchText"
- android:id="@+id/text"
+ style="@style/KeyboardQuickSwitchText.LargeText"
+ android:id="@+id/large_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textAlignment="center"
- app:layout_constraintTop_toBottomOf="@id/icon"
+ app:layout_constraintVertical_chainStyle="packed"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toTopOf="@id/small_text"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <TextView
+ style="@style/KeyboardQuickSwitchText.OnTaskView"
+ android:id="@+id/small_text"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:textAlignment="center"
+
+ app:layout_constraintTop_toBottomOf="@id/large_text"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintEnd_toEndOf="parent"/>
diff --git a/quickstep/res/layout/keyboard_quick_switch_taskview.xml b/quickstep/res/layout/keyboard_quick_switch_taskview.xml
index 8f09176..41eb623 100644
--- a/quickstep/res/layout/keyboard_quick_switch_taskview.xml
+++ b/quickstep/res/layout/keyboard_quick_switch_taskview.xml
@@ -18,8 +18,8 @@
xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:launcher="http://schemas.android.com/apk/res-auto"
- android:layout_width="@dimen/keyboard_quick_switch_taskview_width"
- android:layout_height="@dimen/keyboard_quick_switch_taskview_height"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
android:importantForAccessibility="yes"
android:background="@drawable/keyboard_quick_switch_task_view_background"
android:clipToOutline="true"
@@ -27,8 +27,8 @@
<androidx.constraintlayout.widget.ConstraintLayout
android:id="@+id/content"
- android:layout_width="match_parent"
- android:layout_height="match_parent"
+ android:layout_width="@dimen/keyboard_quick_switch_taskview_width"
+ android:layout_height="@dimen/keyboard_quick_switch_taskview_height"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
@@ -52,7 +52,7 @@
android:layout_width="match_parent"
android:layout_height="0dp"
android:visibility="gone"
- android:layout_marginTop="@dimen/keyboard_quick_switch_split_view_spacing"
+ android:layout_marginTop="@dimen/keyboard_quick_switch_view_small_spacing"
app:layout_constraintTop_toBottomOf="@id/thumbnail_1"
app:layout_constraintBottom_toBottomOf="parent"
diff --git a/quickstep/res/layout/keyboard_quick_switch_taskview_square.xml b/quickstep/res/layout/keyboard_quick_switch_taskview_square.xml
new file mode 100644
index 0000000..1474949
--- /dev/null
+++ b/quickstep/res/layout/keyboard_quick_switch_taskview_square.xml
@@ -0,0 +1,90 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- 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.
+-->
+<com.android.launcher3.taskbar.KeyboardQuickSwitchTaskView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:androidprv="http://schemas.android.com/apk/prv/res/android"
+ xmlns:app="http://schemas.android.com/apk/res-auto"
+ xmlns:launcher="http://schemas.android.com/apk/res-auto"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content"
+ android:importantForAccessibility="yes"
+ android:background="@drawable/keyboard_quick_switch_task_view_background"
+ android:clipToOutline="true"
+ launcher:focusBorderColor="?androidprv:attr/materialColorOutline">
+
+ <androidx.constraintlayout.widget.ConstraintLayout
+ android:id="@+id/content"
+ android:layout_width="0dp"
+ android:layout_height="@dimen/keyboard_quick_switch_taskview_height"
+
+ app:layout_constraintDimensionRatio="1:1"
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toEndOf="parent">
+
+ <include
+ layout="@layout/keyboard_quick_switch_taskview_thumbnail"
+ android:id="@+id/thumbnail_1"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toStartOf="parent"
+ app:layout_constraintEnd_toStartOf="@id/thumbnail_2"/>
+
+ <include
+ layout="@layout/keyboard_quick_switch_taskview_thumbnail"
+ android:id="@+id/thumbnail_2"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:visibility="gone"
+ android:layout_marginStart="@dimen/keyboard_quick_switch_view_small_spacing"
+
+ app:layout_constraintTop_toTopOf="parent"
+ app:layout_constraintBottom_toBottomOf="parent"
+ app:layout_constraintStart_toEndOf="@id/thumbnail_1"
+ app:layout_constraintEnd_toEndOf="parent"/>
+
+ <ImageView
+ android:id="@+id/icon_1"
+ android:layout_width="@dimen/keyboard_quick_switch_taskview_icon_size"
+ android:layout_height="@dimen/keyboard_quick_switch_taskview_icon_size"
+ android:importantForAccessibility="no"
+ android:scaleType="centerCrop"
+
+ app:layout_constraintTop_toTopOf="@id/thumbnail_1"
+ app:layout_constraintBottom_toBottomOf="@id/thumbnail_1"
+ app:layout_constraintStart_toStartOf="@id/thumbnail_1"
+ app:layout_constraintEnd_toEndOf="@id/thumbnail_1"/>
+
+ <ImageView
+ android:id="@+id/icon_2"
+ android:layout_width="@dimen/keyboard_quick_switch_taskview_icon_size"
+ android:layout_height="@dimen/keyboard_quick_switch_taskview_icon_size"
+ android:importantForAccessibility="no"
+ android:visibility="gone"
+ android:scaleType="centerCrop"
+
+ app:layout_constraintTop_toTopOf="@id/thumbnail_2"
+ app:layout_constraintBottom_toBottomOf="@id/thumbnail_2"
+ app:layout_constraintStart_toStartOf="@id/thumbnail_2"
+ app:layout_constraintEnd_toEndOf="@id/thumbnail_2"/>
+
+ </androidx.constraintlayout.widget.ConstraintLayout>
+
+</com.android.launcher3.taskbar.KeyboardQuickSwitchTaskView>
diff --git a/quickstep/res/values-land/dimens.xml b/quickstep/res/values-land/dimens.xml
index e862b9e..2239f8b 100644
--- a/quickstep/res/values-land/dimens.xml
+++ b/quickstep/res/values-land/dimens.xml
@@ -83,7 +83,7 @@
<dimen name="taskbar_suw_frame">96dp</dimen>
<dimen name="taskbar_suw_insets">24dp</dimen>
- <dimen name="keyboard_quick_switch_taskview_width">205dp</dimen>
- <dimen name="keyboard_quick_switch_taskview_height">119dp</dimen>
+ <!-- Keyboard Quick Switch -->
+ <dimen name="keyboard_quick_switch_taskview_width">217.6dp</dimen>
</resources>
diff --git a/quickstep/res/values-night/styles.xml b/quickstep/res/values-night/styles.xml
index 2cb633a..eb88310 100644
--- a/quickstep/res/values-night/styles.xml
+++ b/quickstep/res/values-night/styles.xml
@@ -14,16 +14,7 @@
See the License for the specific language governing permissions and
limitations under the License.
-->
-<resources
- xmlns:androidprv="http://schemas.android.com/apk/prv/res/android">
-
- <style name="AllSetTheme" parent="@android:style/Theme.DeviceDefault.NoActionBar">
- <item name="android:navigationBarColor">@android:color/transparent</item>
- <item name="android:statusBarColor">@android:color/transparent</item>
- <item name="android:enforceNavigationBarContrast">false</item>
- <item name="android:windowLightStatusBar">false</item>
- <item name="android:windowBackground">@android:color/transparent</item>
- </style>
+<resources>
<style name="TextAppearance.GestureTutorial.MainTitle.Home"
parent="TextAppearance.GestureTutorial.MainTitle">
diff --git a/quickstep/res/values/attrs.xml b/quickstep/res/values/attrs.xml
index ccc7f18..7fd6b5c 100644
--- a/quickstep/res/values/attrs.xml
+++ b/quickstep/res/values/attrs.xml
@@ -28,6 +28,7 @@
<!-- Border color for a keyboard quick switch task views -->
<attr name="focusBorderColor" format="color" />
<attr name="hoverBorderColor" format="color" />
+ <attr name="focusBorderRadius" format="dimension" />
</declare-styleable>
<declare-styleable name="ClearAllButton">
diff --git a/quickstep/res/values/dimens.xml b/quickstep/res/values/dimens.xml
index 9996367..ce3f3ac 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -488,17 +488,22 @@
<!-- Keyboard Quick Switch -->
<dimen name="keyboard_quick_switch_border_width">4dp</dimen>
<dimen name="keyboard_quick_switch_taskview_width">104dp</dimen>
- <dimen name="keyboard_quick_switch_taskview_height">134dp</dimen>
+ <dimen name="keyboard_quick_switch_taskview_height">136dp</dimen>
<dimen name="keyboard_quick_switch_taskview_icon_size">52dp</dimen>
<dimen name="keyboard_quick_switch_recents_icon_size">20dp</dimen>
+ <dimen name="keyboard_quick_switch_desktop_icon_size">32dp</dimen>
<dimen name="keyboard_quick_switch_margin_top">56dp</dimen>
<dimen name="keyboard_quick_switch_margin_ends">16dp</dimen>
<dimen name="keyboard_quick_switch_view_spacing">16dp</dimen>
- <dimen name="keyboard_quick_switch_split_view_spacing">2dp</dimen>
+ <dimen name="keyboard_quick_switch_view_small_spacing">4dp</dimen>
<dimen name="keyboard_quick_switch_view_radius">28dp</dimen>
<dimen name="keyboard_quick_switch_task_view_radius">16dp</dimen>
<dimen name="keyboard_quick_switch_no_recent_items_icon_size">24dp</dimen>
<dimen name="keyboard_quick_switch_no_recent_items_icon_margin">8dp</dimen>
+ <dimen name="keyboard_quick_switch_text_button_width">104dp</dimen>
+ <dimen name="keyboard_quick_switch_text_button_radius">360dp</dimen>
+ <dimen name="keyboard_quick_switch_text_button_horizontal_padding">16dp</dimen>
+ <dimen name="keyboard_quick_switch_text_button_fade_edge_length">20dp</dimen>
<!-- Digital Wellbeing -->
<dimen name="digital_wellbeing_toast_height">48dp</dimen>
diff --git a/quickstep/res/values/strings.xml b/quickstep/res/values/strings.xml
index d0f474f..f72f3c5 100644
--- a/quickstep/res/values/strings.xml
+++ b/quickstep/res/values/strings.xml
@@ -327,17 +327,14 @@
<!-- Label for moving drop target to the bottom or right side of the screen, depending on orientation (from the Taskbar only). -->
<string name="move_drop_target_bottom_or_right">Move to bottom/right</string>
- <!-- Label for quick switch tile showing how many more apps are available [CHAR LIMIT=NONE] -->
+ <!-- Label for quick switch tile showing how many more apps are available. The number will be displayed above this text. [CHAR LIMIT=NONE] -->
<string name="quick_switch_overflow">{count, plural,
- =1{Show # more app.}
- other{Show # more apps.}
+ =1{more app}
+ other{more apps}
}</string>
- <!-- Label for quick switch tile showing how many apps are available in desktop mode [CHAR LIMIT=NONE] -->
- <string name="quick_switch_desktop">{count, plural,
- =1{Show # desktop app.}
- other{Show # desktop apps.}
- }</string>
+ <!-- Label for quick switch tile to launch desktop mode [CHAR LIMIT=NONE] -->
+ <string name="quick_switch_desktop">Desktop</string>
<!-- Accessibility label for quick switch tiles showing split tasks [CHAR LIMIT=NONE] -->
<string name="quick_switch_split_task"><xliff:g id="app_name_1" example="Chrome">%1$s</xliff:g> and <xliff:g id="app_name_2" example="Gmail">%2$s</xliff:g></string>
diff --git a/quickstep/res/values/styles.xml b/quickstep/res/values/styles.xml
index 1f4720c..c423d09 100644
--- a/quickstep/res/values/styles.xml
+++ b/quickstep/res/values/styles.xml
@@ -205,7 +205,7 @@
<item name="android:textColor">?attr/tutorialSubtitle</item>
</style>
- <style name="AllSetTheme" parent="@android:style/Theme.DeviceDefault.Light.NoActionBar">
+ <style name="AllSetTheme" parent="@style/DynamicColorsBaseLauncherTheme.NoActionBar">
<item name="android:navigationBarColor">@android:color/transparent</item>
<item name="android:statusBarColor">@android:color/transparent</item>
<item name="android:enforceNavigationBarContrast">false</item>
@@ -272,10 +272,22 @@
<item name="lineHeight">20sp</item>
</style>
+ <style name="KeyboardQuickSwitchText.LargeText" parent="KeyboardQuickSwitchText">
+ <item name="android:textSize">32sp</item>
+ </style>
+
<style name="KeyboardQuickSwitchText.OnBackground" parent="KeyboardQuickSwitchText">
<item name="android:textColor">?attr/materialColorOnSurface</item>
</style>
+ <style name="KeyboardQuickSwitchText.OnTaskView" parent="KeyboardQuickSwitchText">
+ <item name="android:requiresFadingEdge">horizontal</item>
+ <item name="android:fadeScrollbars">false</item>
+ <item name="android:fadingEdgeLength">20dp</item>
+ <item name="android:ellipsize">none</item>
+ <item name="android:singleLine">true</item>
+ </style>
+
<style name="GestureTutorialActivity" parent="@style/AppTheme">
<item name="background">@android:color/transparent</item>
<item name="tutorialSubtitle">@android:color/black</item>
diff --git a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
index 4a1035f..e51c956 100644
--- a/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
+++ b/quickstep/src/com/android/launcher3/QuickstepTransitionManager.java
@@ -65,7 +65,6 @@
import static com.android.launcher3.util.window.RefreshRateTracker.getSingleFrameMs;
import static com.android.launcher3.views.FloatingIconView.SHAPE_PROGRESS_DURATION;
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.quickstep.util.AnimUtils.clampToDuration;
import static com.android.quickstep.util.AnimUtils.completeRunnableListCallback;
@@ -1228,9 +1227,7 @@
* Registers remote animations used when closing apps to home screen.
*/
public void registerRemoteTransitions() {
- if (ENABLE_SHELL_TRANSITIONS) {
- SystemUiProxy.INSTANCE.get(mLauncher).shareTransactionQueue();
- }
+ SystemUiProxy.INSTANCE.get(mLauncher).shareTransactionQueue();
if (SEPARATE_RECENTS_ACTIVITY.get()) {
return;
}
@@ -1294,9 +1291,7 @@
}
protected void unregisterRemoteTransitions() {
- if (ENABLE_SHELL_TRANSITIONS) {
- SystemUiProxy.INSTANCE.get(mLauncher).unshareTransactionQueue();
- }
+ SystemUiProxy.INSTANCE.get(mLauncher).unshareTransactionQueue();
if (SEPARATE_RECENTS_ACTIVITY.get()) {
return;
}
diff --git a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
index e925af6..50e8e5e 100644
--- a/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
+++ b/quickstep/src/com/android/launcher3/WidgetPickerActivity.java
@@ -20,7 +20,6 @@
import static android.view.WindowInsets.Type.navigationBars;
import static android.view.WindowInsets.Type.statusBars;
-import static com.android.launcher3.Flags.enablePredictiveBackGesture;
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
@@ -170,11 +169,6 @@
@Override
protected void registerBackDispatcher() {
- if (!enablePredictiveBackGesture()) {
- super.registerBackDispatcher();
- return;
- }
-
getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
OnBackInvokedDispatcher.PRIORITY_DEFAULT,
new BackAnimationCallback());
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
index 46501c4..e4cc6bb 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchController.java
@@ -29,6 +29,7 @@
import com.android.quickstep.RecentsModel;
import com.android.quickstep.util.DesktopTask;
import com.android.quickstep.util.GroupTask;
+import com.android.quickstep.util.LayoutUtils;
import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.recents.model.ThumbnailData;
import com.android.systemui.shared.system.ActivityManagerWrapper;
@@ -66,6 +67,9 @@
@Nullable private KeyboardQuickSwitchViewController mQuickSwitchViewController;
+ private boolean mHasDesktopTask = false;
+ private boolean mWasDesktopTaskFilteredOut = false;
+
/** Initialize the controller. */
public void init(@NonNull TaskbarControllers controllers) {
mControllers = controllers;
@@ -126,11 +130,15 @@
/* updateTasks= */ false,
currentFocusedIndex == -1 && !mControllerCallbacks.isFirstTaskRunning()
? 0 : currentFocusedIndex,
- onDesktop);
+ onDesktop,
+ mHasDesktopTask,
+ mWasDesktopTaskFilteredOut);
return;
}
mTaskListChangeId = mModel.getTasks((tasks) -> {
+ mHasDesktopTask = false;
+ mWasDesktopTaskFilteredOut = false;
if (onDesktop) {
processLoadedTasksOnDesktop(tasks);
} else {
@@ -144,7 +152,9 @@
/* updateTasks= */ true,
currentFocusedIndex == -1 && !mControllerCallbacks.isFirstTaskRunning()
? 0 : currentFocusedIndex,
- onDesktop);
+ onDesktop,
+ mHasDesktopTask,
+ mWasDesktopTaskFilteredOut);
});
}
@@ -152,9 +162,22 @@
// Only store MAX_TASK tasks, from most to least recent
Collections.reverse(tasks);
mTasks = tasks.stream()
+ .filter(task -> !(task instanceof DesktopTask))
.limit(MAX_TASKS)
.collect(Collectors.toList());
- mNumHiddenTasks = Math.max(0, tasks.size() - MAX_TASKS);
+
+ for (int i = 0; i < tasks.size(); i++) {
+ if (tasks.get(i) instanceof DesktopTask) {
+ mHasDesktopTask = true;
+ if (i < mTasks.size()) {
+ mWasDesktopTaskFilteredOut = true;
+ }
+ break;
+ }
+ }
+
+ mNumHiddenTasks = Math.max(0,
+ tasks.size() - (mWasDesktopTaskFilteredOut ? 1 : 0) - MAX_TASKS);
}
private void processLoadedTasksOnDesktop(List<GroupTask> tasks) {
@@ -214,6 +237,8 @@
pw.println(prefix + "\tisOpen=" + (mQuickSwitchViewController != null));
pw.println(prefix + "\tmNumHiddenTasks=" + mNumHiddenTasks);
pw.println(prefix + "\tmTaskListChangeId=" + mTaskListChangeId);
+ pw.println(prefix + "\tmHasDesktopTask=" + mHasDesktopTask);
+ pw.println(prefix + "\tmWasDesktopTaskFilteredOut=" + mWasDesktopTaskFilteredOut);
pw.println(prefix + "\tmTasks=[");
for (GroupTask task : mTasks) {
Task task1 = task.task1;
@@ -235,10 +260,6 @@
class ControllerCallbacks {
- int getTaskCount() {
- return mTasks.size() + (mNumHiddenTasks == 0 ? 0 : 1);
- }
-
@Nullable
GroupTask getTaskAt(int index) {
return index < 0 || index >= mTasks.size() ? null : mTasks.get(index);
@@ -279,5 +300,10 @@
boolean isFirstTaskRunning() {
return isTaskRunning(getTaskAt(0));
}
+
+ boolean isAspectRatioSquare() {
+ return mControllers != null && LayoutUtils.isAspectRatioSquare(
+ mControllers.taskbarActivityContext.getDeviceProfile().aspectRatio);
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
index 39b4f77..8ceb77d 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchTaskView.java
@@ -50,8 +50,10 @@
public class KeyboardQuickSwitchTaskView extends ConstraintLayout {
private static final float THUMBNAIL_BLUR_RADIUS = 1f;
+ private static final int INVALID_BORDER_RADIUS = -1;
@ColorInt private final int mBorderColor;
+ @ColorInt private final int mBorderRadius;
@Nullable private BorderAnimator mBorderAnimator;
@@ -87,6 +89,8 @@
mBorderColor = ta.getColor(
R.styleable.TaskView_focusBorderColor, DEFAULT_BORDER_COLOR);
+ mBorderRadius = ta.getDimensionPixelSize(
+ R.styleable.TaskView_focusBorderRadius, INVALID_BORDER_RADIUS);
ta.recycle();
}
@@ -103,8 +107,10 @@
Preconditions.assertNotNull(mContent);
mBorderAnimator = BorderAnimator.createScalingBorderAnimator(
- /* borderRadiusPx= */ resources.getDimensionPixelSize(
- R.dimen.keyboard_quick_switch_task_view_radius),
+ /* borderRadiusPx= */ mBorderRadius != INVALID_BORDER_RADIUS
+ ? mBorderRadius
+ : resources.getDimensionPixelSize(
+ R.dimen.keyboard_quick_switch_task_view_radius),
/* borderWidthPx= */ resources.getDimensionPixelSize(
R.dimen.keyboard_quick_switch_border_width),
/* boundsBuilder= */ bounds -> {
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
index dbd9c73..a527c82 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchView.java
@@ -36,14 +36,12 @@
import android.view.ViewTreeObserver;
import android.view.animation.Interpolator;
import android.widget.HorizontalScrollView;
-import android.widget.ImageView;
import android.widget.TextView;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.constraintlayout.widget.ConstraintLayout;
-import androidx.core.content.res.ResourcesCompat;
import com.android.app.animation.Interpolators;
import com.android.internal.jank.Cuj;
@@ -52,9 +50,7 @@
import com.android.launcher3.anim.AnimatedFloat;
import com.android.launcher3.testing.TestLogging;
import com.android.launcher3.testing.shared.TestProtocol;
-import com.android.quickstep.util.DesktopTask;
import com.android.quickstep.util.GroupTask;
-import com.android.systemui.shared.recents.model.Task;
import com.android.systemui.shared.system.InteractionJankMonitorWrapper;
import java.util.HashMap;
@@ -102,9 +98,13 @@
private int mTaskViewWidth;
private int mTaskViewHeight;
private int mSpacing;
+ private int mSmallSpacing;
private int mOutlineRadius;
private boolean mIsRtl;
+ private int mOverviewTaskIndex = -1;
+ private int mDesktopTaskIndex = -1;
+
@Nullable private AnimatorSet mOpenAnimation;
@Nullable private KeyboardQuickSwitchViewController.ViewCallbacks mViewCallbacks;
@@ -141,6 +141,8 @@
mTaskViewHeight = resources.getDimensionPixelSize(
R.dimen.keyboard_quick_switch_taskview_height);
mSpacing = resources.getDimensionPixelSize(R.dimen.keyboard_quick_switch_view_spacing);
+ mSmallSpacing = resources.getDimensionPixelSize(
+ R.dimen.keyboard_quick_switch_view_small_spacing);
mOutlineRadius = resources.getDimensionPixelSize(R.dimen.keyboard_quick_switch_view_radius);
mIsRtl = Utilities.isRtl(resources);
}
@@ -148,6 +150,7 @@
private KeyboardQuickSwitchTaskView createAndAddTaskView(
int index,
boolean isFinalView,
+ boolean useSmallStartSpacing,
@LayoutRes int resId,
@NonNull LayoutInflater layoutInflater,
@Nullable View previousView) {
@@ -156,7 +159,7 @@
taskView.setId(View.generateViewId());
taskView.setOnClickListener(v -> mViewCallbacks.launchTaskAt(index));
- LayoutParams lp = new LayoutParams(mTaskViewWidth, mTaskViewHeight);
+ LayoutParams lp = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
// Create a left-to-right ordering of views (or right-to-left in RTL locales)
if (previousView != null) {
lp.startToEnd = previousView.getId();
@@ -166,7 +169,7 @@
lp.topToTop = PARENT_ID;
lp.bottomToBottom = PARENT_ID;
// Add spacing between views
- lp.setMarginStart(mSpacing);
+ lp.setMarginStart(useSmallStartSpacing ? mSmallSpacing : mSpacing);
if (isFinalView) {
// Add spacing to the end of the final view so that scrolling ends with some padding.
lp.endToEnd = PARENT_ID;
@@ -185,7 +188,8 @@
int numHiddenTasks,
boolean updateTasks,
int currentFocusIndexOverride,
- @NonNull KeyboardQuickSwitchViewController.ViewCallbacks viewCallbacks) {
+ @NonNull KeyboardQuickSwitchViewController.ViewCallbacks viewCallbacks,
+ boolean useDesktopTaskView) {
mViewCallbacks = viewCallbacks;
Resources resources = context.getResources();
Resources.Theme theme = context.getTheme();
@@ -197,57 +201,62 @@
GroupTask groupTask = groupTasks.get(i);
KeyboardQuickSwitchTaskView currentTaskView = createAndAddTaskView(
i,
- /* isFinalView= */ i == tasksToDisplay - 1 && numHiddenTasks == 0,
- groupTask instanceof DesktopTask
- ? R.layout.keyboard_quick_switch_textonly_taskview
+ /* isFinalView= */ i == tasksToDisplay - 1
+ && numHiddenTasks == 0 && !useDesktopTaskView,
+ /* useSmallStartSpacing= */ false,
+ mViewCallbacks.isAspectRatioSquare()
+ ? R.layout.keyboard_quick_switch_taskview_square
: R.layout.keyboard_quick_switch_taskview,
layoutInflater,
previousTaskView);
- if (groupTask instanceof DesktopTask desktopTask) {
- HashMap<String, Integer> args = new HashMap<>();
- args.put("count", desktopTask.tasks.size());
+ final boolean firstTaskIsLeftTopTask =
+ groupTask.mSplitBounds == null
+ || groupTask.mSplitBounds.leftTopTaskId == groupTask.task1.key.id
+ || groupTask.task2 == null;
+ currentTaskView.setThumbnails(
+ firstTaskIsLeftTopTask ? groupTask.task1 : groupTask.task2,
+ firstTaskIsLeftTopTask ? groupTask.task2 : groupTask.task1,
+ updateTasks ? mViewCallbacks::updateThumbnailInBackground : null,
+ updateTasks ? mViewCallbacks::updateIconInBackground : null);
- currentTaskView.<ImageView>findViewById(R.id.icon).setImageDrawable(
- ResourcesCompat.getDrawable(resources, R.drawable.ic_desktop, theme));
- currentTaskView.<TextView>findViewById(R.id.text).setText(new MessageFormat(
- resources.getString(R.string.quick_switch_desktop),
- Locale.getDefault()).format(args));
- } else {
- final boolean firstTaskIsLeftTopTask =
- groupTask.mSplitBounds == null
- || groupTask.mSplitBounds.leftTopTaskId == groupTask.task1.key.id;
- final Task leftTopTask = firstTaskIsLeftTopTask
- ? groupTask.task1 : groupTask.task2;
- final Task rightBottomTask = firstTaskIsLeftTopTask
- ? groupTask.task2 : groupTask.task1;
- currentTaskView.setThumbnails(
- leftTopTask,
- rightBottomTask,
- updateTasks ? mViewCallbacks::updateThumbnailInBackground : null,
- updateTasks ? mViewCallbacks::updateIconInBackground : null);
- }
previousTaskView = currentTaskView;
}
-
if (numHiddenTasks > 0) {
HashMap<String, Integer> args = new HashMap<>();
args.put("count", numHiddenTasks);
+ mOverviewTaskIndex = getTaskCount();
View overviewButton = createAndAddTaskView(
- MAX_TASKS,
- /* isFinalView= */ true,
- R.layout.keyboard_quick_switch_textonly_taskview,
+ mOverviewTaskIndex,
+ /* isFinalView= */ !useDesktopTaskView,
+ /* useSmallStartSpacing= */ false,
+ R.layout.keyboard_quick_switch_overview_taskview,
layoutInflater,
previousTaskView);
- overviewButton.<ImageView>findViewById(R.id.icon).setImageDrawable(
- ResourcesCompat.getDrawable(resources, R.drawable.view_carousel, theme));
- overviewButton.<TextView>findViewById(R.id.text).setText(new MessageFormat(
+ overviewButton.<TextView>findViewById(R.id.large_text).setText(
+ String.format(Locale.getDefault(), "%d", numHiddenTasks));
+ overviewButton.<TextView>findViewById(R.id.small_text).setText(new MessageFormat(
resources.getString(R.string.quick_switch_overflow),
Locale.getDefault()).format(args));
+
+ previousTaskView = overviewButton;
}
- mDisplayingRecentTasks = !groupTasks.isEmpty();
+ if (useDesktopTaskView) {
+ mDesktopTaskIndex = getTaskCount();
+ View desktopButton = createAndAddTaskView(
+ mDesktopTaskIndex,
+ /* isFinalView= */ true,
+ /* useSmallStartSpacing= */ numHiddenTasks > 0,
+ R.layout.keyboard_quick_switch_desktop_taskview,
+ layoutInflater,
+ previousTaskView);
+
+ desktopButton.<TextView>findViewById(R.id.text).setText(
+ resources.getString(R.string.quick_switch_desktop));
+ }
+ mDisplayingRecentTasks = !groupTasks.isEmpty() || useDesktopTaskView;
getViewTreeObserver().addOnGlobalLayoutListener(
new ViewTreeObserver.OnGlobalLayoutListener() {
@@ -260,6 +269,14 @@
});
}
+ int getOverviewTaskIndex() {
+ return mOverviewTaskIndex;
+ }
+
+ int getDesktopTaskIndex() {
+ return mDesktopTaskIndex;
+ }
+
protected Animator getCloseAnimation() {
AnimatorSet closeAnimation = new AnimatorSet();
@@ -370,7 +387,7 @@
}
});
animateFocusMove(-1, Math.min(
- mContent.getChildCount() - 1,
+ getTaskCount() - 1,
currentFocusIndexOverride == -1 ? 1 : currentFocusIndexOverride));
displayedContent.setVisibility(VISIBLE);
setVisibility(VISIBLE);
@@ -577,7 +594,11 @@
@Nullable
protected KeyboardQuickSwitchTaskView getTaskAt(int index) {
- return !mDisplayingRecentTasks || index < 0 || index >= mContent.getChildCount()
+ return !mDisplayingRecentTasks || index < 0 || index >= getTaskCount()
? null : (KeyboardQuickSwitchTaskView) mContent.getChildAt(index);
}
+
+ public int getTaskCount() {
+ return mContent.getChildCount();
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
index d411ba6..40e77e2 100644
--- a/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/KeyboardQuickSwitchViewController.java
@@ -15,6 +15,8 @@
*/
package com.android.launcher3.taskbar;
+import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
+
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.view.KeyEvent;
@@ -28,6 +30,7 @@
import com.android.launcher3.Utilities;
import com.android.launcher3.anim.AnimatorListeners;
import com.android.launcher3.taskbar.overlay.TaskbarOverlayContext;
+import com.android.quickstep.SystemUiProxy;
import com.android.quickstep.util.GroupTask;
import com.android.quickstep.util.SlideInRemoteTransition;
import com.android.systemui.shared.recents.model.Task;
@@ -56,6 +59,7 @@
private int mCurrentFocusIndex = -1;
private boolean mOnDesktop;
+ private boolean mWasDesktopTaskFilteredOut;
protected KeyboardQuickSwitchViewController(
@NonNull TaskbarControllers controllers,
@@ -77,9 +81,12 @@
int numHiddenTasks,
boolean updateTasks,
int currentFocusIndexOverride,
- boolean onDesktop) {
+ boolean onDesktop,
+ boolean hasDesktopTask,
+ boolean wasDesktopTaskFilteredOut) {
mOverlayContext.getDragLayer().addView(mKeyboardQuickSwitchView);
mOnDesktop = onDesktop;
+ mWasDesktopTaskFilteredOut = wasDesktopTaskFilteredOut;
mKeyboardQuickSwitchView.applyLoadPlan(
mOverlayContext,
@@ -87,7 +94,8 @@
numHiddenTasks,
updateTasks,
currentFocusIndexOverride,
- mViewCallbacks);
+ mViewCallbacks,
+ /* useDesktopTaskView= */ !onDesktop && hasDesktopTask);
}
boolean isCloseAnimationRunning() {
@@ -136,7 +144,7 @@
}
// If the user quick switches too quickly, updateCurrentFocusIndex might not have run.
return launchTaskAt(mControllerCallbacks.isFirstTaskRunning()
- && mControllerCallbacks.getTaskCount() > 1 ? 1 : 0);
+ && mKeyboardQuickSwitchView.getTaskCount() > 1 ? 1 : 0);
}
private int launchTaskAt(int index) {
@@ -144,17 +152,11 @@
// Ignore taps on task views and alt key unpresses while the close animation is running.
return -1;
}
- // Even with a valid index, this can be null if the user tries to quick switch before the
- // views have been added in the KeyboardQuickSwitchView.
- GroupTask task = mControllerCallbacks.getTaskAt(index);
- if (task == null) {
- return mOnDesktop ? 1 : Math.max(0, index);
+ if (index == mKeyboardQuickSwitchView.getOverviewTaskIndex()) {
+ // If there is a desktop task view, then we should account for it when focusing the
+ // first hidden non-desktop task view in recents view
+ return mOnDesktop ? 1 : (mWasDesktopTaskFilteredOut ? index + 1 : index);
}
- if (mControllerCallbacks.isTaskRunning(task)) {
- // Ignore attempts to run the selected task if it is already running.
- return -1;
- }
-
Runnable onStartCallback = () -> InteractionJankMonitorWrapper.begin(
mKeyboardQuickSwitchView, Cuj.CUJ_LAUNCHER_KEYBOARD_QUICK_SWITCH_APP_LAUNCH);
Runnable onFinishCallback = () -> InteractionJankMonitorWrapper.end(
@@ -169,6 +171,24 @@
onStartCallback,
onFinishCallback),
"SlideInTransition");
+ if (index == mKeyboardQuickSwitchView.getDesktopTaskIndex()) {
+ UI_HELPER_EXECUTOR.execute(() ->
+ SystemUiProxy.INSTANCE.get(mKeyboardQuickSwitchView.getContext())
+ .showDesktopApps(
+ mKeyboardQuickSwitchView.getDisplay().getDisplayId(),
+ remoteTransition));
+ return -1;
+ }
+ // Even with a valid index, this can be null if the user tries to quick switch before the
+ // views have been added in the KeyboardQuickSwitchView.
+ GroupTask task = mControllerCallbacks.getTaskAt(index);
+ if (task == null) {
+ return mOnDesktop ? 1 : Math.max(0, index);
+ }
+ if (mControllerCallbacks.isTaskRunning(task)) {
+ // Ignore attempts to run the selected task if it is already running.
+ return -1;
+ }
mControllers.taskbarActivityContext.handleGroupTaskLaunch(
task,
remoteTransition,
@@ -195,6 +215,8 @@
pw.println(prefix + "\thasFocus=" + mKeyboardQuickSwitchView.hasFocus());
pw.println(prefix + "\tisCloseAnimationRunning=" + isCloseAnimationRunning());
pw.println(prefix + "\tmCurrentFocusIndex=" + mCurrentFocusIndex);
+ pw.println(prefix + "\tmOnDesktop=" + mOnDesktop);
+ pw.println(prefix + "\tmWasDesktopTaskFilteredOut=" + mWasDesktopTaskFilteredOut);
}
class ViewCallbacks {
@@ -222,7 +244,7 @@
boolean traverseBackwards = (keyCode == KeyEvent.KEYCODE_TAB && event.isShiftPressed())
|| (keyCode == KeyEvent.KEYCODE_DPAD_RIGHT && isRTL)
|| (keyCode == KeyEvent.KEYCODE_DPAD_LEFT && !isRTL);
- int taskCount = mControllerCallbacks.getTaskCount();
+ int taskCount = mKeyboardQuickSwitchView.getTaskCount();
int toIndex = mCurrentFocusIndex == -1
// Focus the second-most recent app if possible
? (taskCount > 1 ? 1 : 0)
@@ -257,5 +279,9 @@
void updateIconInBackground(Task task, Consumer<Task> callback) {
mControllerCallbacks.updateIconInBackground(task, callback);
}
+
+ boolean isAspectRatioSquare() {
+ return mControllerCallbacks.isAspectRatioSquare();
+ }
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
index 96a6d28..69da7b6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/LauncherTaskbarUIController.java
@@ -19,7 +19,6 @@
import static com.android.launcher3.statemanager.BaseState.FLAG_NON_INTERACTIVE;
import static com.android.launcher3.taskbar.TaskbarEduTooltipControllerKt.TOOLTIP_STEP_FEATURES;
import static com.android.launcher3.taskbar.TaskbarLauncherStateController.FLAG_VISIBLE;
-import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
import static com.android.wm.shell.shared.desktopmode.DesktopModeFlags.WALLPAPER_ACTIVITY;
import android.animation.Animator;
@@ -232,9 +231,7 @@
LauncherState state = mLauncher.getStateManager().getState();
boolean nonInteractiveState = state.hasFlag(FLAG_NON_INTERACTIVE)
&& !state.isTaskbarAlignedWithHotseat(mLauncher);
- if ((ENABLE_SHELL_TRANSITIONS
- && isVisible
- && (nonInteractiveState || mSkipLauncherVisibilityChange))) {
+ if (isVisible && (nonInteractiveState || mSkipLauncherVisibilityChange)) {
return null;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
index 475b516..ec710c5 100644
--- a/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/StashedHandleViewController.java
@@ -41,8 +41,8 @@
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.MultiValueAlpha;
import com.android.quickstep.NavHandle;
-import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
import com.android.systemui.shared.system.QuickStepContract.SystemUiStateFlags;
+import com.android.wm.shell.shared.handles.RegionSamplingHelper;
import java.io.PrintWriter;
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
index acf976f..2845cee 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDragLayerController.java
@@ -171,6 +171,10 @@
}
private void updateBackgroundAlpha() {
+ if (mActivity.isPhoneMode()) {
+ return;
+ }
+
final float bgNavbar = mBgNavbar.value;
final float bgTaskbar = mBgTaskbar.value * mKeyguardBgTaskbar.value
* mNotificationShadeBgTaskbar.value * mImeBgTaskbar.value
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
index 43960a1..6b1173a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarUIController.java
@@ -20,7 +20,6 @@
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT;
import static com.android.launcher3.LauncherSettings.Favorites.CONTAINER_HOTSEAT_PREDICTION;
import static com.android.launcher3.taskbar.TaskbarStashController.FLAG_IN_APP;
-import static com.android.quickstep.OverviewCommandHelper.TYPE_HIDE;
import android.content.Intent;
import android.graphics.drawable.BitmapDrawable;
@@ -40,6 +39,7 @@
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.SplitConfigurationOptions;
import com.android.quickstep.OverviewCommandHelper;
+import com.android.quickstep.OverviewCommandHelper.CommandType;
import com.android.quickstep.util.GroupTask;
import com.android.quickstep.util.TISBindHelper;
import com.android.quickstep.views.RecentsView;
@@ -394,7 +394,7 @@
if (overviewCommandHelper == null) {
return;
}
- overviewCommandHelper.addCommand(TYPE_HIDE);
+ overviewCommandHelper.addCommand(CommandType.HIDE);
}
/**
diff --git a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
index 90ac872..f5ac66f 100644
--- a/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/allapps/TaskbarAllAppsSlideInView.java
@@ -16,7 +16,6 @@
package com.android.launcher3.taskbar.allapps;
import static com.android.app.animation.Interpolators.EMPHASIZED;
-import static com.android.launcher3.Flags.enablePredictiveBackGesture;
import static com.android.launcher3.touch.AllAppsSwipeController.ALL_APPS_FADE_MANUAL;
import static com.android.launcher3.touch.AllAppsSwipeController.SCRIM_FADE_MANUAL;
@@ -193,14 +192,12 @@
protected void onAttachedToWindow() {
super.onAttachedToWindow();
mActivityContext.addOnDeviceProfileChangeListener(this);
- if (enablePredictiveBackGesture()) {
- mAppsView.getAppsRecyclerViewContainer().setOutlineProvider(mViewOutlineProvider);
- mAppsView.getAppsRecyclerViewContainer().setClipToOutline(true);
- OnBackInvokedDispatcher dispatcher = findOnBackInvokedDispatcher();
- if (dispatcher != null) {
- dispatcher.registerOnBackInvokedCallback(
- OnBackInvokedDispatcher.PRIORITY_DEFAULT, this);
- }
+ mAppsView.getAppsRecyclerViewContainer().setOutlineProvider(mViewOutlineProvider);
+ mAppsView.getAppsRecyclerViewContainer().setClipToOutline(true);
+ OnBackInvokedDispatcher dispatcher = findOnBackInvokedDispatcher();
+ if (dispatcher != null) {
+ dispatcher.registerOnBackInvokedCallback(
+ OnBackInvokedDispatcher.PRIORITY_DEFAULT, this);
}
}
@@ -208,13 +205,11 @@
protected void onDetachedFromWindow() {
super.onDetachedFromWindow();
mActivityContext.removeOnDeviceProfileChangeListener(this);
- if (enablePredictiveBackGesture()) {
- mAppsView.getAppsRecyclerViewContainer().setOutlineProvider(null);
- mAppsView.getAppsRecyclerViewContainer().setClipToOutline(false);
- OnBackInvokedDispatcher dispatcher = findOnBackInvokedDispatcher();
- if (dispatcher != null) {
- dispatcher.unregisterOnBackInvokedCallback(this);
- }
+ mAppsView.getAppsRecyclerViewContainer().setOutlineProvider(null);
+ mAppsView.getAppsRecyclerViewContainer().setClipToOutline(false);
+ OnBackInvokedDispatcher dispatcher = findOnBackInvokedDispatcher();
+ if (dispatcher != null) {
+ dispatcher.unregisterOnBackInvokedCallback(this);
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
index e45d700..dc7600a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
@@ -1476,8 +1476,9 @@
pw.println("BubbleBarView state:");
pw.println(" visibility: " + getVisibility());
pw.println(" alpha: " + getAlpha());
- pw.println(" translation Y: " + getTranslationY());
- pw.println(" bubbles in bar (childCount = " + getChildCount() + ")");
+ pw.println(" translationY: " + getTranslationY());
+ pw.println(" childCount: " + getChildCount());
+ pw.println(" hasOverflow: " + hasOverflow());
for (BubbleView bubbleView: getBubbles()) {
BubbleBarItem bubble = bubbleView.getBubble();
String key = bubble == null ? "null" : bubble.getKey();
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
index 2c27933..c55faa6 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -840,6 +840,7 @@
pw.println(" mShouldShowEducation: " + mShouldShowEducation);
pw.println(" mBubbleBarTranslationY.value: " + mBubbleBarTranslationY.value);
pw.println(" mBubbleBarSwipeUpTranslationY: " + mBubbleBarSwipeUpTranslationY);
+ pw.println(" mOverflowAdded: " + mOverflowAdded);
if (mBarView != null) {
mBarView.dump(pw);
} else {
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
index 577a70b..73984ea 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
@@ -39,9 +39,9 @@
import com.android.launcher3.util.Executors;
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.MultiValueAlpha;
-import com.android.systemui.shared.navigationbar.RegionSamplingHelper;
import com.android.wm.shell.common.bubbles.BubbleBarLocation;
import com.android.wm.shell.shared.animation.PhysicsAnimator;
+import com.android.wm.shell.shared.handles.RegionSamplingHelper;
/**
* Handles properties/data collection, then passes the results to our stashed handle View to render.
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
index eb3b24b..6265ec3 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleView.java
@@ -237,7 +237,11 @@
mBubble = bubble;
mIcon = bubble.getIcon();
updateBubbleIcon();
- mAppIcon.setImageBitmap(bubble.getBadge());
+ if (bubble.getInfo().showAppBadge()) {
+ mAppIcon.setImageBitmap(bubble.getBadge());
+ } else {
+ mAppIcon.setVisibility(GONE);
+ }
mDotColor = bubble.getDotColor();
mDotRenderer = new DotRenderer(mBubbleSize, bubble.getDotPath(), DEFAULT_PATH_SIZE);
String contentDesc = bubble.getInfo().getTitle();
@@ -302,8 +306,10 @@
}
void setBadgeScale(float fraction) {
- mAppIcon.setScaleX(fraction);
- mAppIcon.setScaleY(fraction);
+ if (mAppIcon.getVisibility() == VISIBLE) {
+ mAppIcon.setScaleX(fraction);
+ mAppIcon.setScaleY(fraction);
+ }
}
boolean hasUnseenContent() {
diff --git a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
index 37e0034..4590efe 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/PredictedAppIcon.java
@@ -379,12 +379,7 @@
}
@Override
- public void setIconVisible(boolean visible) {
- setForceHideRing(!visible);
- super.setIconVisible(visible);
- }
-
- private void setForceHideRing(boolean forceHideRing) {
+ public void setForceHideRing(boolean forceHideRing) {
if (mForceHideRing == forceHideRing) {
return;
}
@@ -417,7 +412,7 @@
private void drawEffect(Canvas canvas) {
// Don't draw ring effect if item is about to be dragged or if the icon is not visible.
- if (mDrawForDrag || !mIsIconVisible) {
+ if (mDrawForDrag || !mIsIconVisible || mForceHideRing) {
return;
}
mIconRingPaint.setColor(RING_SHADOW_COLOR);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
index 17735e1..55c1885 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/QuickstepLauncher.java
@@ -22,7 +22,6 @@
import static com.android.app.animation.Interpolators.EMPHASIZED;
import static com.android.internal.jank.Cuj.CUJ_LAUNCHER_LAUNCH_APP_PAIR_FROM_WORKSPACE;
-import static com.android.launcher3.Flags.enablePredictiveBackGesture;
import static com.android.launcher3.Flags.enableUnfoldStateAnimation;
import static com.android.launcher3.LauncherConstants.SavedInstanceKeys.PENDING_SPLIT_SELECT_INFO;
import static com.android.launcher3.LauncherConstants.SavedInstanceKeys.RUNTIME_STATE;
@@ -499,10 +498,8 @@
boolean started = ((getActivityFlags() & ACTIVITY_STATE_STARTED)) != 0;
if (started) {
DeviceProfile profile = getDeviceProfile();
- boolean willUserBeActive =
- (getActivityFlags() & ACTIVITY_STATE_USER_WILL_BE_ACTIVE) != 0;
boolean visible = (state == NORMAL || state == OVERVIEW)
- && (willUserBeActive || isUserActive())
+ && isUserActive()
&& !profile.isVerticalBarLayout()
&& !mIsOverlayVisible;
SystemUiProxy.INSTANCE.get(this)
@@ -696,9 +693,7 @@
// Back dispatcher is registered in {@link BaseActivity#onCreate}. For predictive back to
// work, we must opt-in BEFORE registering back dispatcher. So we need to call
// setEnableOnBackInvokedCallback() before super.onCreate()
- if (Utilities.ATLEAST_U && enablePredictiveBackGesture()) {
- getApplicationInfo().setEnableOnBackInvokedCallback(true);
- }
+ getApplicationInfo().setEnableOnBackInvokedCallback(true);
super.onCreate(savedInstanceState);
if (savedInstanceState != null) {
mPendingSplitSelectInfo = ObjectWrapper.unwrap(
@@ -910,8 +905,7 @@
// event won't go through ViewRootImpl#InputStage#onProcess.
// So when receive back key, try to do the same check thing in
// ViewRootImpl#NativePreImeInputStage#onProcess
- if (!Utilities.ATLEAST_U || !enablePredictiveBackGesture()
- || event.getKeyCode() != KeyEvent.KEYCODE_BACK
+ if (event.getKeyCode() != KeyEvent.KEYCODE_BACK
|| event.getAction() != KeyEvent.ACTION_UP || event.isCanceled()) {
return false;
}
@@ -922,10 +916,6 @@
@Override
protected void registerBackDispatcher() {
- if (!enablePredictiveBackGesture()) {
- super.registerBackDispatcher();
- return;
- }
getOnBackInvokedDispatcher().registerOnBackInvokedCallback(
OnBackInvokedDispatcher.PRIORITY_DEFAULT,
new OnBackAnimationCallback() {
@@ -1279,10 +1269,6 @@
return ObjectWrapper.wrap(new Integer(info.id));
}
- public void setHintUserWillBeActive() {
- addActivityFlags(ACTIVITY_STATE_USER_WILL_BE_ACTIVE);
- }
-
@Override
public void onDisplayInfoChanged(Context context, DisplayController.Info info, int flags) {
super.onDisplayInfoChanged(context, info, flags);
diff --git a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
index 2625646..1ba784b 100644
--- a/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
+++ b/quickstep/src/com/android/launcher3/uioverrides/states/BackgroundAppState.java
@@ -17,7 +17,6 @@
import static com.android.launcher3.Flags.enableScalingRevealHomeAnimation;
import static com.android.launcher3.logging.StatsLogManager.LAUNCHER_STATE_BACKGROUND;
-import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
import android.content.Context;
import android.graphics.Color;
@@ -107,8 +106,7 @@
@Override
public boolean isTaskbarAlignedWithHotseat(Launcher launcher) {
- if (ENABLE_SHELL_TRANSITIONS) return false;
- return super.isTaskbarAlignedWithHotseat(launcher);
+ return false;
}
@Override
diff --git a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
index 3d94442..38d08e0 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -97,6 +97,7 @@
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.annotation.UiThread;
+import androidx.annotation.VisibleForTesting;
import com.android.internal.jank.Cuj;
import com.android.internal.util.LatencyTracker;
@@ -170,10 +171,12 @@
/**
* Handles the navigation gestures when Launcher is the default home activity.
*/
-public abstract class AbsSwipeUpHandler<T extends RecentsViewContainer,
- Q extends RecentsView, S extends BaseState<S>>
- extends SwipeUpAnimationLogic implements OnApplyWindowInsetsListener,
- RecentsAnimationCallbacks.RecentsAnimationListener {
+public abstract class AbsSwipeUpHandler<
+ RECENTS_CONTAINER extends Context & RecentsViewContainer,
+ RECENTS_VIEW extends RecentsView<RECENTS_CONTAINER, STATE>,
+ STATE extends BaseState<STATE>>
+ extends SwipeUpAnimationLogic
+ implements OnApplyWindowInsetsListener, RecentsAnimationCallbacks.RecentsAnimationListener {
private static final String TAG = "AbsSwipeUpHandler";
private static final ArrayList<String> STATE_NAMES = new ArrayList<>();
@@ -181,7 +184,7 @@
// Fraction of the scroll and transform animation in which the current task fades out
private static final float KQS_TASK_FADE_ANIMATION_FRACTION = 0.4f;
- protected final BaseContainerInterface<S, T> mContainerInterface;
+ protected final BaseContainerInterface<STATE, RECENTS_CONTAINER> mContainerInterface;
protected final InputConsumerProxy mInputConsumerProxy;
protected final ActivityInitListener mActivityInitListener;
// Callbacks to be made once the recents animation starts
@@ -192,8 +195,8 @@
protected @Nullable RecentsAnimationController mRecentsAnimationController;
protected @Nullable RecentsAnimationController mDeferredCleanupRecentsAnimationController;
protected RecentsAnimationTargets mRecentsAnimationTargets;
- protected @Nullable T mContainer;
- protected @Nullable Q mRecentsView;
+ protected @Nullable RECENTS_CONTAINER mContainer;
+ protected @Nullable RECENTS_VIEW mRecentsView;
protected Runnable mGestureEndCallback;
protected MultiStateCallback mStateCallback;
protected boolean mCanceled;
@@ -486,11 +489,11 @@
return false;
}
- T createdContainer = (T) mContainerInterface.getCreatedContainer();
+ RECENTS_CONTAINER createdContainer = mContainerInterface.getCreatedContainer();
if (createdContainer != null) {
initTransitionEndpoints(createdContainer.getDeviceProfile());
}
- final T container = (T) mContainerInterface.getCreatedContainer();
+ final RECENTS_CONTAINER container = mContainerInterface.getCreatedContainer();
if (mContainer == container) {
return true;
}
@@ -564,7 +567,7 @@
}
private void onLauncherStart() {
- final T container = (T) mContainerInterface.getCreatedContainer();
+ final RECENTS_CONTAINER container = mContainerInterface.getCreatedContainer();
if (container == null || mContainer != container) {
return;
}
@@ -949,7 +952,6 @@
// We will handle the sysui flags based on the centermost task view.
mRecentsAnimationController.setUseLauncherSystemBarFlags(swipeUpThresholdPassed
|| (quickswitchThresholdPassed && centermostTaskFlags != 0));
- mRecentsAnimationController.setSplitScreenMinimized(mContext, swipeUpThresholdPassed);
// Provide a hint to WM the direction that we will be settling in case the animation
// needs to be canceled
mRecentsAnimationController.setWillFinishToHome(swipeUpThresholdPassed);
@@ -1097,7 +1099,7 @@
*/
@UiThread
private void notifyGestureStarted() {
- final T curActivity = mContainer;
+ final RECENTS_CONTAINER curActivity = mContainer;
if (curActivity != null) {
// Once the gesture starts, we can no longer transition home through the button, so
// reset the force override of the activity visibility
@@ -1168,7 +1170,8 @@
/**
* Called if the end target has been set and the recents animation is started.
*/
- private void onCalculateEndTarget() {
+ @VisibleForTesting
+ protected void onCalculateEndTarget() {
final GestureEndTarget endTarget = mGestureState.getEndTarget();
switch (endTarget) {
@@ -1181,7 +1184,8 @@
}
}
- private void onSettledOnEndTarget() {
+ @VisibleForTesting
+ protected void onSettledOnEndTarget() {
// Fast-finish the attaching animation if it's still running.
maybeUpdateRecentsAttachedState(false);
final GestureEndTarget endTarget = mGestureState.getEndTarget();
@@ -1417,7 +1421,7 @@
}
}
Interpolator interpolator;
- S state = mContainerInterface.stateFromGestureEndTarget(endTarget);
+ STATE state = mContainerInterface.stateFromGestureEndTarget(endTarget);
if (isKeyboardTaskFocusPending()) {
interpolator = EMPHASIZED;
} else if (state.displayOverviewTasksAsGrid(mDp)) {
@@ -1767,8 +1771,7 @@
private int calculateWindowRotation(RemoteAnimationTarget runningTaskTarget,
RecentsOrientedState orientationState) {
- if (runningTaskTarget.rotationChange != 0
- && TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
+ if (runningTaskTarget.rotationChange != 0) {
return Math.abs(runningTaskTarget.rotationChange) == ROTATION_90
? ROTATION_270 : ROTATION_90;
} else {
@@ -2499,7 +2502,7 @@
}
private void animateSplashScreenExit(
- @NonNull T activity,
+ @NonNull RECENTS_CONTAINER activity,
@NonNull RemoteAnimationTarget[] appearedTaskTargets,
@NonNull RemoteAnimationTarget[] animatingTargets) {
ViewGroup splashView = activity.getDragLayer();
diff --git a/quickstep/src/com/android/quickstep/BaseContainerInterface.java b/quickstep/src/com/android/quickstep/BaseContainerInterface.java
index 3a8c141..777761b 100644
--- a/quickstep/src/com/android/quickstep/BaseContainerInterface.java
+++ b/quickstep/src/com/android/quickstep/BaseContainerInterface.java
@@ -68,8 +68,6 @@
public abstract void onAssistantVisibilityChanged(float assistantVisibility);
- public abstract boolean allowMinimizeSplitScreen();
-
public abstract boolean isResumed();
public abstract boolean isStarted();
diff --git a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
index 89fbf4a..94a4527 100644
--- a/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/FallbackActivityInterface.java
@@ -133,12 +133,6 @@
}
@Override
- public boolean allowMinimizeSplitScreen() {
- // TODO: Remove this once b/77875376 is fixed
- return false;
- }
-
- @Override
public boolean allowAllAppsFromOverview() {
return false;
}
diff --git a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
index b564fa7..e9fe2f7 100644
--- a/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
+++ b/quickstep/src/com/android/quickstep/LauncherActivityInterface.java
@@ -271,11 +271,6 @@
}
@Override
- public boolean allowMinimizeSplitScreen() {
- return true;
- }
-
- @Override
public boolean allowAllAppsFromOverview() {
return FeatureFlags.ENABLE_ALL_APPS_FROM_OVERVIEW.get()
// If floating search bar would not show in overview, don't allow all apps gesture.
diff --git a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
index e17cdcd..f653e60 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -62,8 +62,8 @@
/**
* Temporary class to allow easier refactoring
*/
-public class LauncherSwipeHandlerV2 extends
- AbsSwipeUpHandler<QuickstepLauncher, RecentsView, LauncherState> {
+public class LauncherSwipeHandlerV2 extends AbsSwipeUpHandler<
+ QuickstepLauncher, RecentsView<QuickstepLauncher, LauncherState>, LauncherState> {
public LauncherSwipeHandlerV2(Context context, RecentsAnimationDeviceState deviceState,
TaskAnimationManager taskAnimationManager, GestureState gestureState, long touchTimeMs,
@@ -107,9 +107,6 @@
|| !mContainer.getDesktopVisibilityController().areDesktopTasksVisible());
mContainer.getRootView().setForceHideBackArrow(true);
- if (!TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
- mContainer.setHintUserWillBeActive();
- }
if (!canUseWorkspaceView || appCanEnterPip || mIsSwipeForSplit) {
return new LauncherHomeAnimationFactory() {
diff --git a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
index f6b9e4e..80ed5ae 100644
--- a/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
+++ b/quickstep/src/com/android/quickstep/OverviewCommandHelper.kt
@@ -33,6 +33,8 @@
import com.android.launcher3.logging.StatsLogManager.LauncherEvent.*
import com.android.launcher3.util.Executors
import com.android.launcher3.util.RunnableList
+import com.android.quickstep.OverviewCommandHelper.CommandInfo.CommandStatus
+import com.android.quickstep.OverviewCommandHelper.CommandType.*
import com.android.quickstep.util.ActiveGestureLog
import com.android.quickstep.views.RecentsView
import com.android.quickstep.views.RecentsViewContainer
@@ -40,6 +42,7 @@
import com.android.systemui.shared.recents.model.ThumbnailData
import com.android.systemui.shared.system.InteractionJankMonitorWrapper
import java.io.PrintWriter
+import java.util.concurrent.ConcurrentLinkedDeque
/** Helper class to handle various atomic commands for switching between Overview. */
class OverviewCommandHelper(
@@ -47,7 +50,7 @@
private val overviewComponentObserver: OverviewComponentObserver,
private val taskAnimationManager: TaskAnimationManager
) {
- private val pendingCommands = mutableListOf<CommandInfo>()
+ private val commandQueue = ConcurrentLinkedDeque<CommandInfo>()
/**
* Index of the TaskView that should be focused when launching Overview. Persisted so that we do
@@ -64,23 +67,39 @@
*/
private var waitForToggleCommandComplete = false
- /** Called when the command finishes execution. */
- private fun scheduleNextTask(command: CommandInfo) {
- if (pendingCommands.isEmpty()) {
- Log.d(TAG, "no pending commands to schedule")
+ private val activityInterface: BaseActivityInterface<*, *>
+ get() = overviewComponentObserver.activityInterface
+
+ private val visibleRecentsView: RecentsView<*, *>?
+ get() = activityInterface.getVisibleRecentsView<RecentsView<*, *>>()
+
+ /**
+ * Adds a command to be executed next, after all pending tasks are completed. Max commands that
+ * can be queued is [.MAX_QUEUE_SIZE]. Requests after reaching that limit will be silently
+ * dropped.
+ */
+ @BinderThread
+ fun addCommand(type: CommandType) {
+ if (commandQueue.size >= MAX_QUEUE_SIZE) {
+ Log.d(TAG, "commands queue is full ($commandQueue). command not added: $type")
return
}
- if (pendingCommands.first() !== command) {
- Log.d(
- TAG,
- "next task not scheduled. First pending command type " +
- "is ${pendingCommands.first()} - command type is: $command"
- )
- return
+
+ val command = CommandInfo(type)
+ commandQueue.add(command)
+ Log.d(TAG, "command added: $command")
+
+ if (commandQueue.size == 1) {
+ Executors.MAIN_EXECUTOR.execute { executeNext() }
}
- Log.d(TAG, "scheduleNextTask called: $command")
- pendingCommands.removeFirst()
- executeNext()
+ }
+
+ fun canStartHomeSafely(): Boolean = commandQueue.isEmpty() || commandQueue.first().type == HOME
+
+ /** Clear pending commands from the queue */
+ fun clearPendingCommands() {
+ Log.d(TAG, "clearing pending commands: $commandQueue")
+ commandQueue.clear()
}
/**
@@ -90,67 +109,76 @@
*/
@UiThread
private fun executeNext() {
- if (pendingCommands.isEmpty()) {
- Log.d(TAG, "executeNext - pendingCommands is empty")
- return
- }
- val command = pendingCommands.first()
- val result = executeCommand(command)
- Log.d(TAG, "executeNext command type: $command, result: $result")
- if (result) {
- scheduleNextTask(command)
- }
- }
+ val command: CommandInfo =
+ commandQueue.firstOrNull()
+ ?: run {
+ Log.d(TAG, "no pending commands to be executed.")
+ return
+ }
- @UiThread
- private fun addCommand(command: CommandInfo) {
- val wasEmpty = pendingCommands.isEmpty()
- pendingCommands.add(command)
- if (wasEmpty) {
- executeNext()
+ command.status = CommandStatus.PROCESSING
+ Log.d(TAG, "executing command: $command")
+
+ val result = executeCommand(command)
+ Log.d(TAG, "command executed: $command with result: $result")
+ if (result) {
+ onCommandFinished(command)
+ } else {
+ Log.d(TAG, "waiting for command callback: $command")
}
}
/**
- * Adds a command to be executed next, after all pending tasks are completed. Max commands that
- * can be queued is [.MAX_QUEUE_SIZE]. Requests after reaching that limit will be silently
- * dropped.
+ * Executes the task and returns true if next task can be executed. If false, then the next task
+ * is deferred until [.scheduleNextTask] is called
*/
- @BinderThread
- fun addCommand(type: Int) {
- if (pendingCommands.size >= MAX_QUEUE_SIZE) {
- Log.d(
- TAG,
- "the pending command queue is full (${pendingCommands.size}). command not added: $type"
- )
- return
+ private fun executeCommand(command: CommandInfo): Boolean {
+ if (waitForToggleCommandComplete && command.type == TOGGLE) {
+ Log.d(TAG, "executeCommand: $command - waiting for toggle command complete")
+ return true
}
- Log.d(TAG, "adding command type: $type")
- val command = CommandInfo(type)
- Executors.MAIN_EXECUTOR.execute { addCommand(command) }
- }
- @UiThread
- fun clearPendingCommands() {
- Log.d(TAG, "clearing pending commands - size: ${pendingCommands.size}")
- pendingCommands.clear()
- }
-
- @UiThread
- fun canStartHomeSafely(): Boolean =
- pendingCommands.isEmpty() || pendingCommands.first().type == TYPE_HOME
-
- private fun getNextTask(view: RecentsView<*, *>): TaskView? {
- val runningTaskView = view.runningTaskView
-
- return if (runningTaskView == null) {
- view.getTaskViewAt(0)
+ val recentsView = visibleRecentsView
+ Log.d(TAG, "executeCommand: $command - visibleRecentsView: $recentsView")
+ return if (recentsView != null) {
+ executeWhenRecentsIsVisible(command, recentsView)
} else {
- val nextTask = view.nextTaskView
- nextTask ?: runningTaskView
+ executeWhenRecentsIsNotVisible(command)
}
}
+ private fun executeWhenRecentsIsVisible(
+ command: CommandInfo,
+ recentsView: RecentsView<*, *>,
+ ): Boolean =
+ when (command.type) {
+ SHOW -> true // already visible
+ KEYBOARD_INPUT,
+ HIDE -> {
+ if (recentsView.isHandlingTouch) {
+ true
+ } else {
+ keyboardTaskFocusIndex = PagedView.INVALID_PAGE
+ val currentPage = recentsView.nextPage
+ val taskView = recentsView.getTaskViewAt(currentPage)
+ launchTask(recentsView, taskView, command)
+ }
+ }
+ TOGGLE -> {
+ val taskView =
+ if (recentsView.runningTaskView == null) {
+ recentsView.getTaskViewAt(0)
+ } else {
+ recentsView.nextTaskView ?: recentsView.runningTaskView
+ }
+ launchTask(recentsView, taskView, command)
+ }
+ HOME -> {
+ recentsView.startHome()
+ true
+ }
+ }
+
private fun launchTask(
recents: RecentsView<*, *>,
taskView: TaskView?,
@@ -166,7 +194,7 @@
if (callbackList != null) {
callbackList.add {
Log.d(TAG, "launching task callback: $command")
- scheduleNextTask(command)
+ onCommandFinished(command)
waitForToggleCommandComplete = false
}
Log.d(TAG, "launching task - waiting for callback: $command")
@@ -178,94 +206,54 @@
}
}
- /**
- * Executes the task and returns true if next task can be executed. If false, then the next task
- * is deferred until [.scheduleNextTask] is called
- */
- private fun executeCommand(command: CommandInfo): Boolean {
- if (waitForToggleCommandComplete && command.type == TYPE_TOGGLE) {
- Log.d(TAG, "executeCommand: $command - waiting for toggle command complete")
- return true
- }
- val activityInterface: BaseActivityInterface<*, *> =
- overviewComponentObserver.activityInterface
+ private fun executeWhenRecentsIsNotVisible(command: CommandInfo): Boolean {
+ val recentsViewContainer = activityInterface.getCreatedContainer() as? RecentsViewContainer
+ val recentsView: RecentsView<*, *>? = recentsViewContainer?.getOverviewPanel()
+ val deviceProfile = recentsViewContainer?.getDeviceProfile()
+ val uiController = activityInterface.getTaskbarController()
+ val allowQuickSwitch =
+ FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH.get() &&
+ uiController != null &&
+ deviceProfile != null &&
+ (deviceProfile.isTablet || deviceProfile.isTwoPanels)
- val visibleRecentsView: RecentsView<*, *>? =
- activityInterface.getVisibleRecentsView<RecentsView<*, *>>()
- val createdRecentsView: RecentsView<*, *>?
-
- Log.d(TAG, "executeCommand: $command - visibleRecentsView: $visibleRecentsView")
- if (visibleRecentsView == null) {
- val activity = activityInterface.getCreatedContainer() as? RecentsViewContainer
- createdRecentsView = activity?.getOverviewPanel()
- val deviceProfile = activity?.getDeviceProfile()
- val uiController = activityInterface.getTaskbarController()
- val allowQuickSwitch =
- FeatureFlags.ENABLE_KEYBOARD_QUICK_SWITCH.get() &&
- uiController != null &&
- deviceProfile != null &&
- (deviceProfile.isTablet || deviceProfile.isTwoPanels)
-
- when (command.type) {
- TYPE_HIDE -> {
- if (!allowQuickSwitch) return true
- keyboardTaskFocusIndex = uiController!!.launchFocusedTask()
- if (keyboardTaskFocusIndex == -1) return true
- }
- TYPE_KEYBOARD_INPUT ->
- if (allowQuickSwitch) {
- uiController!!.openQuickSwitchView()
- return true
- } else {
- keyboardTaskFocusIndex = 0
- }
- TYPE_HOME -> {
- ActiveGestureLog.INSTANCE.addLog(
- "OverviewCommandHelper.executeCommand(TYPE_HOME)"
- )
- // Although IActivityTaskManager$Stub$Proxy.startActivity is a slow binder call,
- // we should still call it on main thread because launcher is waiting for
- // ActivityTaskManager to resume it. Also calling startActivity() on bg thread
- // could potentially delay resuming launcher. See b/348668521 for more details.
- touchInteractionService.startActivity(overviewComponentObserver.homeIntent)
+ when (command.type) {
+ HIDE -> {
+ if (!allowQuickSwitch) return true
+ keyboardTaskFocusIndex = uiController!!.launchFocusedTask()
+ if (keyboardTaskFocusIndex == -1) return true
+ }
+ KEYBOARD_INPUT ->
+ if (allowQuickSwitch) {
+ uiController!!.openQuickSwitchView()
return true
- }
- TYPE_SHOW ->
- // When Recents is not currently visible, the command's type is
- // TYPE_SHOW
- // when overview is triggered via the keyboard overview button or Action+Tab
- // keys (Not Alt+Tab which is KQS). The overview button on-screen in 3-button
- // nav is TYPE_TOGGLE.
+ } else {
keyboardTaskFocusIndex = 0
- else -> {}
- }
- } else {
- createdRecentsView = visibleRecentsView
- when (command.type) {
- TYPE_SHOW -> return true // already visible
- TYPE_KEYBOARD_INPUT,
- TYPE_HIDE -> {
- if (visibleRecentsView.isHandlingTouch) return true
-
- keyboardTaskFocusIndex = PagedView.INVALID_PAGE
- val currentPage = visibleRecentsView.nextPage
- val taskView = visibleRecentsView.getTaskViewAt(currentPage)
- return launchTask(visibleRecentsView, taskView, command)
}
- TYPE_TOGGLE ->
- return launchTask(visibleRecentsView, getNextTask(visibleRecentsView), command)
- TYPE_HOME -> {
- visibleRecentsView.startHome()
- return true
- }
+ HOME -> {
+ ActiveGestureLog.INSTANCE.addLog("OverviewCommandHelper.executeCommand(HOME)")
+ // Although IActivityTaskManager$Stub$Proxy.startActivity is a slow binder call,
+ // we should still call it on main thread because launcher is waiting for
+ // ActivityTaskManager to resume it. Also calling startActivity() on bg thread
+ // could potentially delay resuming launcher. See b/348668521 for more details.
+ touchInteractionService.startActivity(overviewComponentObserver.homeIntent)
+ return true
}
+ SHOW ->
+ // When Recents is not currently visible, the command's type is SHOW
+ // when overview is triggered via the keyboard overview button or Action+Tab
+ // keys (Not Alt+Tab which is KQS). The overview button on-screen in 3-button
+ // nav is TYPE_TOGGLE.
+ keyboardTaskFocusIndex = 0
+ TOGGLE -> {}
}
- createdRecentsView?.setKeyboardTaskFocusIndex(keyboardTaskFocusIndex)
+ recentsView?.setKeyboardTaskFocusIndex(keyboardTaskFocusIndex)
// Handle recents view focus when launching from home
val animatorListener: Animator.AnimatorListener =
object : AnimatorListenerAdapter() {
override fun onAnimationStart(animation: Animator) {
+ Log.d(TAG, "switching to Overview state - onAnimationStart: $command")
super.onAnimationStart(animation)
updateRecentsViewFocus(command)
logShowOverviewFrom(command.type)
@@ -275,7 +263,7 @@
Log.d(TAG, "switching to Overview state - onAnimationEnd: $command")
super.onAnimationEnd(animation)
onRecentsViewFocusUpdated(command)
- scheduleNextTask(command)
+ onCommandFinished(command)
}
}
if (activityInterface.switchToRecentsIfVisible(animatorListener)) {
@@ -311,9 +299,11 @@
controller: RecentsAnimationController,
targets: RecentsAnimationTargets
) {
+ Log.d(TAG, "recents animation started: $command")
updateRecentsViewFocus(command)
logShowOverviewFrom(command.type)
activityInterface.runOnInitBackgroundStateUI {
+ Log.d(TAG, "recents animation started - onInitBackgroundStateUI: $command")
interactionHandler.onGestureEnded(0f, PointF())
}
command.removeListener(this)
@@ -322,11 +312,12 @@
override fun onRecentsAnimationCanceled(
thumbnailDatas: HashMap<Int, ThumbnailData>
) {
+ Log.d(TAG, "recents animation canceled: $command")
interactionHandler.onGestureCancelled()
command.removeListener(this)
activityInterface.getCreatedContainer() ?: return
- createdRecentsView?.onRecentsAnimationComplete()
+ recentsView?.onRecentsAnimationComplete()
}
}
@@ -347,7 +338,7 @@
taskAnimationManager.notifyRecentsAnimationState(recentAnimListener)
} else {
val intent =
- Intent(interactionHandler.launchIntent)
+ Intent(interactionHandler.getLaunchIntent())
.putExtra(ActiveGestureLog.INTENT_EXTRA_LOG_TRACE_ID, gestureState.gestureId)
command.setAnimationCallbacks(
taskAnimationManager.startRecentsAnimation(gestureState, intent, interactionHandler)
@@ -365,17 +356,29 @@
command.removeListener(handler)
Trace.endAsyncSection(TRANSITION_NAME, 0)
onRecentsViewFocusUpdated(command)
- scheduleNextTask(command)
+ onCommandFinished(command)
+ }
+
+ /** Called when the command finishes execution. */
+ private fun onCommandFinished(command: CommandInfo) {
+ command.status = CommandStatus.COMPLETED
+ if (commandQueue.first() !== command) {
+ Log.d(
+ TAG,
+ "next task not scheduled. First pending command type " +
+ "is ${commandQueue.first()} - command type is: $command"
+ )
+ return
+ }
+
+ Log.d(TAG, "command executed successfully! $command")
+ commandQueue.remove(command)
+ executeNext()
}
private fun updateRecentsViewFocus(command: CommandInfo) {
- val recentsView: RecentsView<*, *> =
- overviewComponentObserver.activityInterface.getVisibleRecentsView() ?: return
- if (
- command.type != TYPE_KEYBOARD_INPUT &&
- command.type != TYPE_HIDE &&
- command.type != TYPE_SHOW
- ) {
+ val recentsView: RecentsView<*, *> = visibleRecentsView ?: return
+ if (command.type != KEYBOARD_INPUT && command.type != HIDE && command.type != SHOW) {
return
}
@@ -387,16 +390,16 @@
// here we launch overview with live tile.
recentsView.viewRootImpl.touchModeChanged(false)
// Ensure that recents view has focus so that it receives the followup key inputs
- if (requestFocus(recentsView.getTaskViewAt(keyboardTaskFocusIndex))) return
- if (requestFocus(recentsView.nextTaskView)) return
- if (requestFocus(recentsView.getTaskViewAt(0))) return
- requestFocus(recentsView)
+ // Stops requesting focused after first view gets focused.
+ recentsView.getTaskViewAt(keyboardTaskFocusIndex).requestFocus() ||
+ recentsView.nextTaskView.requestFocus() ||
+ recentsView.getTaskViewAt(0).requestFocus() ||
+ recentsView.requestFocus()
}
private fun onRecentsViewFocusUpdated(command: CommandInfo) {
- val recentsView: RecentsView<*, *> =
- overviewComponentObserver.activityInterface.getVisibleRecentsView() ?: return
- if (command.type != TYPE_HIDE || keyboardTaskFocusIndex == PagedView.INVALID_PAGE) {
+ val recentsView: RecentsView<*, *> = visibleRecentsView ?: return
+ if (command.type != HIDE || keyboardTaskFocusIndex == PagedView.INVALID_PAGE) {
return
}
recentsView.setKeyboardTaskFocusIndex(PagedView.INVALID_PAGE)
@@ -404,24 +407,22 @@
keyboardTaskFocusIndex = PagedView.INVALID_PAGE
}
- private fun requestFocus(taskView: View?): Boolean {
- if (taskView == null) return false
- taskView.post {
- taskView.requestFocus()
- taskView.requestAccessibilityFocus()
+ private fun View?.requestFocus(): Boolean {
+ if (this == null) return false
+ post {
+ requestFocus()
+ requestAccessibilityFocus()
}
return true
}
- private fun logShowOverviewFrom(commandType: Int) {
- val activityInterface: BaseActivityInterface<*, *> =
- overviewComponentObserver.activityInterface
+ private fun logShowOverviewFrom(commandType: CommandType) {
val container = activityInterface.getCreatedContainer() as? RecentsViewContainer ?: return
val event =
when (commandType) {
- TYPE_SHOW -> LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_KEYBOARD_SHORTCUT
- TYPE_HIDE -> LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_KEYBOARD_QUICK_SWITCH
- TYPE_TOGGLE -> LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_3_BUTTON
+ SHOW -> LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_KEYBOARD_SHORTCUT
+ HIDE -> LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_KEYBOARD_QUICK_SWITCH
+ TOGGLE -> LAUNCHER_OVERVIEW_SHOW_OVERVIEW_FROM_3_BUTTON
else -> return
}
StatsLogManager.newInstance(container.asContext())
@@ -438,16 +439,17 @@
fun dump(pw: PrintWriter) {
pw.println("OverviewCommandHelper:")
- pw.println(" pendingCommands=${pendingCommands.size}")
- if (pendingCommands.isNotEmpty()) {
- pw.println(" pendingCommandType=${pendingCommands.first().type}")
+ pw.println(" pendingCommands=${commandQueue.size}")
+ if (commandQueue.isNotEmpty()) {
+ pw.println(" pendingCommandType=${commandQueue.first().type}")
}
- pw.println(" mKeyboardTaskFocusIndex=$keyboardTaskFocusIndex")
- pw.println(" mWaitForToggleCommandComplete=$waitForToggleCommandComplete")
+ pw.println(" keyboardTaskFocusIndex=$keyboardTaskFocusIndex")
+ pw.println(" waitForToggleCommandComplete=$waitForToggleCommandComplete")
}
private data class CommandInfo(
- val type: Int,
+ val type: CommandType,
+ var status: CommandStatus = CommandStatus.IDLE,
val createTime: Long = SystemClock.elapsedRealtime(),
private var animationCallbacks: RecentsAnimationCallbacks? = null
) {
@@ -462,23 +464,30 @@
fun removeListener(listener: RecentsAnimationCallbacks.RecentsAnimationListener?) {
animationCallbacks?.removeListener(listener)
}
+
+ enum class CommandStatus {
+ IDLE,
+ PROCESSING,
+ COMPLETED
+ }
+ }
+
+ enum class CommandType {
+ SHOW,
+ KEYBOARD_INPUT,
+ HIDE,
+ TOGGLE, // Navigate to Overview
+ HOME, // Navigate to Home
}
companion object {
private const val TAG = "OverviewCommandHelper"
-
- const val TYPE_SHOW: Int = 1
- const val TYPE_KEYBOARD_INPUT: Int = 2
- const val TYPE_HIDE: Int = 3
- const val TYPE_TOGGLE: Int = 4
- const val TYPE_HOME: Int = 5
+ private const val TRANSITION_NAME = "Transition:toOverview"
/**
* Use case for needing a queue is double tapping recents button in 3 button nav. Size of 2
* should be enough. We'll toss in one more because we're kind hearted.
*/
private const val MAX_QUEUE_SIZE = 3
-
- private const val TRANSITION_NAME = "Transition:toOverview"
}
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
index 32e2389..7b9b560 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationCallbacks.java
@@ -54,17 +54,14 @@
private final Set<RecentsAnimationListener> mListeners = new ArraySet<>();
private final SystemUiProxy mSystemUiProxy;
- private final boolean mAllowMinimizeSplitScreen;
// TODO(141886704): Remove these references when they are no longer needed
private RecentsAnimationController mController;
private boolean mCancelled;
- public RecentsAnimationCallbacks(SystemUiProxy systemUiProxy,
- boolean allowMinimizeSplitScreen) {
+ public RecentsAnimationCallbacks(SystemUiProxy systemUiProxy) {
mSystemUiProxy = systemUiProxy;
- mAllowMinimizeSplitScreen = allowMinimizeSplitScreen;
}
@UiThread
@@ -122,7 +119,7 @@
}
mController = new RecentsAnimationController(animationController,
- mAllowMinimizeSplitScreen, this::onAnimationFinished);
+ this::onAnimationFinished);
if (mCancelled) {
Utilities.postAsyncCallback(MAIN_EXECUTOR.getHandler(),
mController::finishAnimationToApp);
@@ -219,7 +216,6 @@
public void dump(String prefix, PrintWriter pw) {
pw.println(prefix + "RecentsAnimationCallbacks:");
- pw.println(prefix + "\tmAllowMinimizeSplitScreen=" + mAllowMinimizeSplitScreen);
pw.println(prefix + "\tmCancelled=" + mCancelled);
}
diff --git a/quickstep/src/com/android/quickstep/RecentsAnimationController.java b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
index 1b05e28..adcf4ef 100644
--- a/quickstep/src/com/android/quickstep/RecentsAnimationController.java
+++ b/quickstep/src/com/android/quickstep/RecentsAnimationController.java
@@ -17,7 +17,6 @@
import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import static com.android.launcher3.util.Executors.UI_HELPER_EXECUTOR;
-import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
import static com.android.quickstep.util.ActiveGestureErrorDetector.GestureEvent.FINISH_RECENTS_ANIMATION;
import android.content.Context;
@@ -52,21 +51,17 @@
private static final String TAG = "RecentsAnimationController";
private final RecentsAnimationControllerCompat mController;
private final Consumer<RecentsAnimationController> mOnFinishedListener;
- private final boolean mAllowMinimizeSplitScreen;
private boolean mUseLauncherSysBarFlags = false;
- private boolean mSplitScreenMinimized = false;
private boolean mFinishRequested = false;
// Only valid when mFinishRequested == true.
private boolean mFinishTargetIsLauncher;
private RunnableList mPendingFinishCallbacks = new RunnableList();
public RecentsAnimationController(RecentsAnimationControllerCompat controller,
- boolean allowMinimizeSplitScreen,
Consumer<RecentsAnimationController> onFinishedListener) {
mController = controller;
mOnFinishedListener = onFinishedListener;
- mAllowMinimizeSplitScreen = allowMinimizeSplitScreen;
}
/**
@@ -85,34 +80,17 @@
if (mUseLauncherSysBarFlags != useLauncherSysBarFlags) {
mUseLauncherSysBarFlags = useLauncherSysBarFlags;
UI_HELPER_EXECUTOR.execute(() -> {
- if (!ENABLE_SHELL_TRANSITIONS) {
- mController.setAnimationTargetsBehindSystemBars(!useLauncherSysBarFlags);
- } else {
- try {
- WindowManagerGlobal.getWindowManagerService().setRecentsAppBehindSystemBars(
- useLauncherSysBarFlags);
- } catch (RemoteException e) {
- Log.e(TAG, "Unable to reach window manager", e);
- }
+ try {
+ WindowManagerGlobal.getWindowManagerService().setRecentsAppBehindSystemBars(
+ useLauncherSysBarFlags);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Unable to reach window manager", e);
}
});
}
}
/**
- * Indicates that the gesture has crossed the window boundary threshold and we should minimize
- * if we are in splitscreen.
- */
- public void setSplitScreenMinimized(Context context, boolean splitScreenMinimized) {
- if (!mAllowMinimizeSplitScreen) {
- return;
- }
- if (mSplitScreenMinimized != splitScreenMinimized) {
- mSplitScreenMinimized = splitScreenMinimized;
- }
- }
-
- /**
* Remove task remote animation target from
* {@link RecentsAnimationCallbacks#onTasksAppeared}}.
*/
@@ -272,9 +250,7 @@
public void dump(String prefix, PrintWriter pw) {
pw.println(prefix + "RecentsAnimationController:");
- pw.println(prefix + "\tmAllowMinimizeSplitScreen=" + mAllowMinimizeSplitScreen);
pw.println(prefix + "\tmUseLauncherSysBarFlags=" + mUseLauncherSysBarFlags);
- pw.println(prefix + "\tmSplitScreenMinimized=" + mSplitScreenMinimized);
pw.println(prefix + "\tmFinishRequested=" + mFinishRequested);
pw.println(prefix + "\tmFinishTargetIsLauncher=" + mFinishTargetIsLauncher);
}
diff --git a/quickstep/src/com/android/quickstep/TaskAnimationManager.java b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
index 85eea3b..49ec597 100644
--- a/quickstep/src/com/android/quickstep/TaskAnimationManager.java
+++ b/quickstep/src/com/android/quickstep/TaskAnimationManager.java
@@ -60,9 +60,8 @@
import java.util.HashMap;
public class TaskAnimationManager implements RecentsAnimationCallbacks.RecentsAnimationListener {
- public static final boolean ENABLE_SHELL_TRANSITIONS = true;
- public static final boolean SHELL_TRANSITIONS_ROTATION = ENABLE_SHELL_TRANSITIONS
- && SystemProperties.getBoolean("persist.wm.debug.shell_transit_rotate", false);
+ public static final boolean SHELL_TRANSITIONS_ROTATION =
+ SystemProperties.getBoolean("persist.wm.debug.shell_transit_rotate", false);
private final Context mCtx;
private RecentsAnimationController mController;
@@ -160,8 +159,7 @@
final BaseContainerInterface containerInterface = gestureState.getContainerInterface();
mLastGestureState = gestureState;
- RecentsAnimationCallbacks newCallbacks = new RecentsAnimationCallbacks(
- getSystemUiProxy(), containerInterface.allowMinimizeSplitScreen());
+ RecentsAnimationCallbacks newCallbacks = new RecentsAnimationCallbacks(getSystemUiProxy());
mCallbacks = newCallbacks;
mCallbacks.addListener(new RecentsAnimationCallbacks.RecentsAnimationListener() {
@Override
@@ -191,7 +189,7 @@
}
mLastGestureState.updateLastAppearedTaskTargets(mLastAppearedTaskTargets);
- if (ENABLE_SHELL_TRANSITIONS && mTargets.hasRecents
+ if (mTargets.hasRecents
// The filtered (MODE_CLOSING) targets only contain 1 home activity.
&& mTargets.apps.length == 1
&& mTargets.apps[0].windowConfiguration.getActivityType()
diff --git a/quickstep/src/com/android/quickstep/TouchInteractionService.java b/quickstep/src/com/android/quickstep/TouchInteractionService.java
index b321b3e..4587bdd 100644
--- a/quickstep/src/com/android/quickstep/TouchInteractionService.java
+++ b/quickstep/src/com/android/quickstep/TouchInteractionService.java
@@ -109,6 +109,7 @@
import com.android.launcher3.util.SafeCloseable;
import com.android.launcher3.util.ScreenOnTracker;
import com.android.launcher3.util.TraceHelper;
+import com.android.quickstep.OverviewCommandHelper.CommandType;
import com.android.quickstep.inputconsumers.AccessibilityInputConsumer;
import com.android.quickstep.inputconsumers.AssistantInputConsumer;
import com.android.quickstep.inputconsumers.BubbleBarInputConsumer;
@@ -246,7 +247,7 @@
return;
}
TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
- tis.mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_TOGGLE);
+ tis.mOverviewCommandHelper.addCommand(CommandType.TOGGLE);
});
}
@@ -256,10 +257,9 @@
executeForTouchInteractionService(tis -> {
if (triggeredFromAltTab) {
TaskUtils.closeSystemWindowsAsync(CLOSE_SYSTEM_WINDOWS_REASON_RECENTS);
- tis.mOverviewCommandHelper.addCommand(
- OverviewCommandHelper.TYPE_KEYBOARD_INPUT);
+ tis.mOverviewCommandHelper.addCommand(CommandType.KEYBOARD_INPUT);
} else {
- tis.mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_SHOW);
+ tis.mOverviewCommandHelper.addCommand(CommandType.SHOW);
}
});
}
@@ -270,7 +270,7 @@
executeForTouchInteractionService(tis -> {
if (triggeredFromAltTab && !triggeredFromHomeKey) {
// onOverviewShownFromAltTab hides the overview and ends at the target app
- tis.mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_HIDE);
+ tis.mOverviewCommandHelper.addCommand(CommandType.HIDE);
}
});
}
@@ -595,12 +595,12 @@
private final TaskbarNavButtonCallbacks mNavCallbacks = new TaskbarNavButtonCallbacks() {
@Override
public void onNavigateHome() {
- mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_HOME);
+ mOverviewCommandHelper.addCommand(CommandType.HOME);
}
@Override
public void onToggleOverview() {
- mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_TOGGLE);
+ mOverviewCommandHelper.addCommand(CommandType.TOGGLE);
}
};
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/BubbleBarInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/BubbleBarInputConsumer.java
index dbe2068..92031c5 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/BubbleBarInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/BubbleBarInputConsumer.java
@@ -45,6 +45,7 @@
private boolean mSwipeUpOnBubbleHandle;
private boolean mPassedTouchSlop;
+ private boolean mStashedOrCollapsedOnDown;
private final int mTouchSlop;
private final PointF mDownPos = new PointF();
@@ -69,13 +70,13 @@
@Override
public void onMotionEvent(MotionEvent ev) {
- final boolean isStashed = mBubbleStashController.isStashed();
final int action = ev.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
mActivePointerId = ev.getPointerId(0);
mDownPos.set(ev.getX(), ev.getY());
mLastPos.set(mDownPos);
+ mStashedOrCollapsedOnDown = mBubbleStashController.isStashed() || isCollapsed();
break;
case MotionEvent.ACTION_MOVE:
int pointerIndex = ev.findPointerIndex(mActivePointerId);
@@ -89,7 +90,7 @@
if (!mPassedTouchSlop) {
mPassedTouchSlop = Math.abs(dY) > mTouchSlop || Math.abs(dX) > mTouchSlop;
}
- if ((isCollapsed() || isStashed) && !mSwipeUpOnBubbleHandle && mPassedTouchSlop) {
+ if (mStashedOrCollapsedOnDown && !mSwipeUpOnBubbleHandle && mPassedTouchSlop) {
boolean verticalGesture = Math.abs(dY) > Math.abs(dX);
if (verticalGesture && !mBubbleDragController.isDragging()) {
mSwipeUpOnBubbleHandle = true;
@@ -102,11 +103,10 @@
break;
case MotionEvent.ACTION_UP:
boolean isWithinTapTime = ev.getEventTime() - ev.getDownTime() <= mTimeForTap;
- if (isWithinTapTime && !mSwipeUpOnBubbleHandle && !mPassedTouchSlop) {
+ if (isWithinTapTime && !mSwipeUpOnBubbleHandle && !mPassedTouchSlop
+ && mStashedOrCollapsedOnDown) {
// Taps on the handle / collapsed state should open the bar
- if (isStashed || isCollapsed()) {
- mBubbleStashController.showBubbleBar(/* expandBubbles= */ true);
- }
+ mBubbleStashController.showBubbleBar(/* expandBubbles= */ true);
}
break;
}
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
index 14f47d1..b66d4cb 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/DeviceLockedInputConsumer.java
@@ -24,7 +24,6 @@
import static com.android.quickstep.AbsSwipeUpHandler.MIN_PROGRESS_FOR_OVERVIEW;
import static com.android.quickstep.MultiStateCallback.DEBUG_STATES;
import static com.android.quickstep.OverviewComponentObserver.startHomeIntentSafely;
-import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
import static com.android.quickstep.util.ActiveGestureLog.INTENT_EXTRA_LOG_TRACE_ID;
import android.animation.Animator;
@@ -212,15 +211,13 @@
// This will come back and cancel the interaction.
startHomeIntentSafely(mContext, mGestureState.getHomeIntent(), null, TAG);
mHomeLaunched = true;
- } else if (ENABLE_SHELL_TRANSITIONS) {
- if (mTaskAnimationManager.getCurrentCallbacks() != null) {
- if (mRecentsAnimationController != null) {
- finishRecentsAnimationForShell(dismissTask);
- } else {
- // the transition of recents animation hasn't started, wait for it
- mCancelWhenRecentsStart = true;
- mDismissTask = dismissTask;
- }
+ } else if (mTaskAnimationManager.getCurrentCallbacks() != null) {
+ if (mRecentsAnimationController != null) {
+ finishRecentsAnimationForShell(dismissTask);
+ } else {
+ // the transition of recents animation hasn't started, wait for it
+ mCancelWhenRecentsStart = true;
+ mDismissTask = dismissTask;
}
}
mStateCallback.setState(STATE_HANDLER_INVALIDATED);
diff --git a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarUnstashInputConsumer.java b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarUnstashInputConsumer.java
index 17a97fa..9284e13 100644
--- a/quickstep/src/com/android/quickstep/inputconsumers/TaskbarUnstashInputConsumer.java
+++ b/quickstep/src/com/android/quickstep/inputconsumers/TaskbarUnstashInputConsumer.java
@@ -46,6 +46,7 @@
import com.android.quickstep.GestureState;
import com.android.quickstep.InputConsumer;
import com.android.quickstep.OverviewCommandHelper;
+import com.android.quickstep.OverviewCommandHelper.CommandType;
import com.android.systemui.shared.system.InputMonitorCompat;
/**
@@ -200,7 +201,7 @@
break;
case MotionEvent.ACTION_BUTTON_RELEASE:
if (isStashedTaskbarHovered) {
- mOverviewCommandHelper.addCommand(OverviewCommandHelper.TYPE_HOME);
+ mOverviewCommandHelper.addCommand(CommandType.HOME);
}
break;
}
diff --git a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
index 36ea926..acc9959 100644
--- a/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
+++ b/quickstep/src/com/android/quickstep/interaction/GestureSandboxActivity.java
@@ -41,6 +41,7 @@
import com.android.launcher3.logging.StatsLogManager;
import com.android.quickstep.TouchInteractionService.TISBinder;
import com.android.quickstep.interaction.TutorialController.TutorialType;
+import com.android.quickstep.util.LayoutUtils;
import com.android.quickstep.util.TISBindHelper;
import java.util.ArrayList;
@@ -54,8 +55,6 @@
static final String KEY_TUTORIAL_TYPE = "tutorial_type";
static final String KEY_GESTURE_COMPLETE = "gesture_complete";
static final String KEY_USE_TUTORIAL_MENU = "use_tutorial_menu";
- public static final double SQUARE_ASPECT_RATIO_BOTTOM_BOUND = 0.95;
- public static final double SQUARE_ASPECT_RATIO_UPPER_BOUND = 1.05;
@Nullable private TutorialType[] mTutorialSteps;
private GestureSandboxFragment mCurrentFragment;
@@ -170,10 +169,7 @@
getApplicationContext()).getDeviceProfile(this);
if (deviceProfile.isTablet) {
// The tutorial will work in either orientation if the height and width are similar
- boolean isAspectRatioSquare =
- deviceProfile.aspectRatio > SQUARE_ASPECT_RATIO_BOTTOM_BOUND
- && deviceProfile.aspectRatio < SQUARE_ASPECT_RATIO_UPPER_BOUND;
- boolean showRotationPrompt = !isAspectRatioSquare
+ boolean showRotationPrompt = !LayoutUtils.isAspectRatioSquare(deviceProfile.aspectRatio)
&& getResources().getConfiguration().orientation
== ActivityInfo.SCREEN_ORIENTATION_PORTRAIT;
diff --git a/quickstep/src/com/android/quickstep/util/LayoutUtils.java b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
index ec1eeb1..b9338a3 100644
--- a/quickstep/src/com/android/quickstep/util/LayoutUtils.java
+++ b/quickstep/src/com/android/quickstep/util/LayoutUtils.java
@@ -28,6 +28,8 @@
public class LayoutUtils {
+ private static final float SQUARE_ASPECT_RATIO_TOLERANCE = 0.05f;
+
/**
* The height for the swipe up motion
*/
@@ -61,4 +63,13 @@
}
}
}
+
+ /**
+ * Returns true iff the device's aspect ratio is within
+ * {@link LayoutUtils#SQUARE_ASPECT_RATIO_TOLERANCE} of 1:1
+ */
+ public static boolean isAspectRatioSquare(float aspectRatio) {
+ return Float.compare(aspectRatio, 1f - SQUARE_ASPECT_RATIO_TOLERANCE) >= 0
+ && Float.compare(aspectRatio, 1f + SQUARE_ASPECT_RATIO_TOLERANCE) <= 0;
+ }
}
diff --git a/quickstep/src/com/android/quickstep/util/RecentsViewUtils.kt b/quickstep/src/com/android/quickstep/util/RecentsViewUtils.kt
index 0a01d8b..cf08391 100644
--- a/quickstep/src/com/android/quickstep/util/RecentsViewUtils.kt
+++ b/quickstep/src/com/android/quickstep/util/RecentsViewUtils.kt
@@ -17,9 +17,11 @@
package com.android.quickstep.util
import com.android.launcher3.Flags.enableLargeDesktopWindowingTile
+import com.android.quickstep.RecentsAnimationController
import com.android.quickstep.views.DesktopTaskView
import com.android.quickstep.views.TaskView
import com.android.quickstep.views.TaskViewType
+import com.android.systemui.shared.recents.model.ThumbnailData
/**
* Helper class for [com.android.quickstep.views.RecentsView]. This util class contains refactored
@@ -68,4 +70,12 @@
if (taskView?.isLargeTile == true) taskView else null
}
}
+
+ fun screenshotTasks(
+ taskView: TaskView,
+ recentsAnimationController: RecentsAnimationController
+ ): Map<Int, ThumbnailData> =
+ taskView.taskContainers.associate {
+ it.task.key.id to recentsAnimationController.screenshotTask(it.task.key.id)
+ }
}
diff --git a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
index ae6757f..1af12f1 100644
--- a/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitSelectStateController.java
@@ -886,8 +886,7 @@
Log.w(TAG, "Package not found: " + packageName, e);
}
RecentsAnimationCallbacks callbacks = new RecentsAnimationCallbacks(
- SystemUiProxy.INSTANCE.get(mLauncher.getApplicationContext()),
- false /* allowMinimizeSplitScreen */);
+ SystemUiProxy.INSTANCE.get(mLauncher.getApplicationContext()));
DesktopSplitRecentsAnimationListener listener =
new DesktopSplitRecentsAnimationListener(splitPosition, taskBounds);
diff --git a/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java b/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java
index 1c417eb..4c6e4ff 100644
--- a/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java
+++ b/quickstep/src/com/android/quickstep/util/SplitWithKeyboardShortcutController.java
@@ -84,8 +84,7 @@
return;
}
RecentsAnimationCallbacks callbacks = new RecentsAnimationCallbacks(
- SystemUiProxy.INSTANCE.get(mLauncher.getApplicationContext()),
- false /* allowMinimizeSplitScreen */);
+ SystemUiProxy.INSTANCE.get(mLauncher.getApplicationContext()));
SplitWithKeyboardShortcutRecentsAnimationListener listener =
new SplitWithKeyboardShortcutRecentsAnimationListener(leftOrTop);
diff --git a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
index e5c54bb..c7777d8 100644
--- a/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
+++ b/quickstep/src/com/android/quickstep/util/TaskViewSimulator.java
@@ -24,7 +24,6 @@
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_TOP_OR_LEFT;
import static com.android.launcher3.util.SplitConfigurationOptions.STAGE_POSITION_UNDEFINED;
import static com.android.launcher3.util.SplitConfigurationOptions.StagePosition;
-import static com.android.quickstep.TaskAnimationManager.ENABLE_SHELL_TRANSITIONS;
import static com.android.quickstep.util.RecentsOrientedState.postDisplayRotation;
import static com.android.quickstep.util.RecentsOrientedState.preDisplayRotation;
@@ -535,21 +534,12 @@
// If mDrawsBelowRecents is unset, no reordering will be enforced.
if (mDrawsBelowRecents != null) {
- // In legacy transitions, the animation leashes remain in same hierarchy in the
- // TaskDisplayArea, so we don't want to bump the layer too high otherwise it will
- // conflict with layers that WM core positions (ie. the input consumers). For shell
- // transitions, the animation leashes are reparented to an animation container so we
- // can bump layers as needed.
- if (ENABLE_SHELL_TRANSITIONS) {
- builder.setLayer(mDrawsBelowRecents
- ? Integer.MIN_VALUE + app.prefixOrderIndex
- // 1000 is an arbitrary number to give room for multiple layers.
- : Integer.MAX_VALUE - 1000 + app.prefixOrderIndex);
- } else {
- builder.setLayer(mDrawsBelowRecents
- ? Integer.MIN_VALUE + app.prefixOrderIndex
- : 0);
- }
+ // In shell transitions, the animation leashes are reparented to an animation container
+ // so we can bump layers as needed.
+ builder.setLayer(mDrawsBelowRecents
+ ? Integer.MIN_VALUE + app.prefixOrderIndex
+ // 1000 is an arbitrary number to give room for multiple layers.
+ : Integer.MAX_VALUE - 1000 + app.prefixOrderIndex);
}
}
diff --git a/quickstep/src/com/android/quickstep/views/RecentsView.java b/quickstep/src/com/android/quickstep/views/RecentsView.java
index 255619a..226ecf5 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsView.java
+++ b/quickstep/src/com/android/quickstep/views/RecentsView.java
@@ -3058,14 +3058,15 @@
}
private void setRunningTaskViewShowScreenshot(boolean showScreenshot) {
+ setRunningTaskViewShowScreenshot(showScreenshot, /*updatedThumbnails=*/null);
+ }
+
+ private void setRunningTaskViewShowScreenshot(boolean showScreenshot,
+ @Nullable Map<Integer, ThumbnailData> updatedThumbnails) {
mRunningTaskShowScreenshot = showScreenshot;
TaskView runningTaskView = getRunningTaskView();
if (runningTaskView != null) {
- runningTaskView.setShouldShowScreenshot(mRunningTaskShowScreenshot);
- if (!enableRefactorTaskThumbnail()) {
- runningTaskView.getTaskContainers().forEach(
- taskContainer -> taskContainer.getThumbnailViewDeprecated().refresh());
- }
+ runningTaskView.setShouldShowScreenshot(mRunningTaskShowScreenshot, updatedThumbnails);
}
if (enableRefactorTaskThumbnail()) {
mRecentsViewModel.setRunningTaskShowScreenshot(showScreenshot);
@@ -6154,20 +6155,12 @@
return;
}
+ Map<Integer, ThumbnailData> updatedThumbnails = mRecentsViewUtils.screenshotTasks(taskView,
+ mRecentsAnimationController);
if (enableRefactorTaskThumbnail()) {
- mHelper.switchToScreenshot(taskView, mRecentsAnimationController, onFinishRunnable);
+ mHelper.switchToScreenshot(taskView, updatedThumbnails, onFinishRunnable);
} else {
- setRunningTaskViewShowScreenshot(true);
- for (TaskContainer container : taskView.getTaskContainers()) {
- ThumbnailData thumbnailData =
- mRecentsAnimationController.screenshotTask(container.getTask().key.id);
- TaskThumbnailViewDeprecated thumbnailView = container.getThumbnailViewDeprecated();
- if (thumbnailData != null) {
- thumbnailView.setThumbnail(container.getTask(), thumbnailData);
- } else {
- thumbnailView.refresh();
- }
- }
+ setRunningTaskViewShowScreenshot(true, updatedThumbnails);
ViewUtils.postFrameDrawn(taskView, onFinishRunnable);
}
}
@@ -6186,8 +6179,7 @@
if (enableRefactorTaskThumbnail()) {
mHelper.switchToScreenshot(taskView, thumbnailDatas, onFinishRunnable);
} else {
- taskView.setShouldShowScreenshot(true);
- taskView.refreshThumbnails(thumbnailDatas);
+ taskView.setShouldShowScreenshot(true, thumbnailDatas);
ViewUtils.postFrameDrawn(taskView, onFinishRunnable);
}
} else {
diff --git a/quickstep/src/com/android/quickstep/views/RecentsViewModelHelper.kt b/quickstep/src/com/android/quickstep/views/RecentsViewModelHelper.kt
index f5b2176..4604b70 100644
--- a/quickstep/src/com/android/quickstep/views/RecentsViewModelHelper.kt
+++ b/quickstep/src/com/android/quickstep/views/RecentsViewModelHelper.kt
@@ -16,7 +16,6 @@
package com.android.quickstep.views
-import com.android.quickstep.RecentsAnimationController
import com.android.quickstep.ViewUtils
import com.android.quickstep.recents.viewmodel.RecentsViewModel
import com.android.systemui.shared.recents.model.ThumbnailData
@@ -42,18 +41,6 @@
fun switchToScreenshot(
taskView: TaskView,
- recentsAnimationController: RecentsAnimationController,
- onFinishRunnable: Runnable,
- ) {
- val updatedThumbnails =
- taskView.taskContainers.associate {
- it.task.key.id to recentsAnimationController.screenshotTask(it.task.key.id)
- }
- switchToScreenshot(taskView, updatedThumbnails, onFinishRunnable)
- }
-
- fun switchToScreenshot(
- taskView: TaskView,
updatedThumbnails: Map<Int, ThumbnailData>?,
onFinishRunnable: Runnable,
) {
diff --git a/quickstep/src/com/android/quickstep/views/TaskView.kt b/quickstep/src/com/android/quickstep/views/TaskView.kt
index 815f8fa..d2cdfa2 100644
--- a/quickstep/src/com/android/quickstep/views/TaskView.kt
+++ b/quickstep/src/com/android/quickstep/views/TaskView.kt
@@ -79,7 +79,6 @@
import com.android.launcher3.views.ActivityContext
import com.android.quickstep.RecentsModel
import com.android.quickstep.RemoteAnimationTargets
-import com.android.quickstep.TaskAnimationManager
import com.android.quickstep.TaskOverlayFactory
import com.android.quickstep.TaskViewUtils
import com.android.quickstep.orientation.RecentsPagedOrientationHandler
@@ -408,6 +407,7 @@
protected var shouldShowScreenshot = false
get() = !isRunningTask || field
+ private set
/** Enable or disable showing border on hover and focus change */
@VisibleForTesting(otherwise = VisibleForTesting.PROTECTED)
@@ -974,7 +974,13 @@
iconView.setText(text)
}
- open fun refreshThumbnails(thumbnailDatas: Map<Int, ThumbnailData?>?) {
+ @JvmOverloads
+ open fun setShouldShowScreenshot(
+ shouldShowScreenshot: Boolean,
+ thumbnailDatas: Map<Int, ThumbnailData?>? = null
+ ) {
+ if (this.shouldShowScreenshot == shouldShowScreenshot) return
+ this.shouldShowScreenshot = shouldShowScreenshot
if (enableRefactorTaskThumbnail()) {
return
}
@@ -1041,14 +1047,12 @@
// triggered by QuickstepTransitionManager.AppLaunchAnimationRunner.
return RunnableList().also { recentsView.addSideTaskLaunchCallback(it) }
}
- if (TaskAnimationManager.ENABLE_SHELL_TRANSITIONS) {
- // If the recents transition is running (ie. in live tile mode), then the start
- // of a new task will merge into the existing transition and it currently will
- // not be run independently, so we need to rely on the onTaskAppeared() call
- // for the new task to trigger the side launch callback to flush this runnable
- // list (which is usually flushed when the app launch animation finishes)
- recentsView.addSideTaskLaunchCallback(opts.onEndCallback)
- }
+ // If the recents transition is running (ie. in live tile mode), then the start
+ // of a new task will merge into the existing transition and it currently will
+ // not be run independently, so we need to rely on the onTaskAppeared() call
+ // for the new task to trigger the side launch callback to flush this runnable
+ // list (which is usually flushed when the app launch animation finishes)
+ recentsView.addSideTaskLaunchCallback(opts.onEndCallback)
return opts.onEndCallback
} else {
notifyTaskLaunchFailed()
diff --git a/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/BubbleViewScreenshotTest.kt b/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/BubbleViewScreenshotTest.kt
index d77ac5c..1d92d7e 100644
--- a/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/BubbleViewScreenshotTest.kt
+++ b/quickstep/tests/multivalentScreenshotTests/src/com/android/launcher3/taskbar/bubbles/BubbleViewScreenshotTest.kt
@@ -99,7 +99,7 @@
val flags =
if (suppressNotification) Notification.BubbleMetadata.FLAG_SUPPRESS_NOTIFICATION else 0
val bubbleInfo =
- BubbleInfo("key", flags, null, null, 0, context.packageName, null, null, false)
+ BubbleInfo("key", flags, null, null, 0, context.packageName, null, null, false, true)
val bubbleView = inflater.inflate(R.layout.bubblebar_item_view, null) as BubbleView
val dotPath =
PathParser.createPathFromPathData(
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/BubbleViewTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/BubbleViewTest.kt
index 8bad3b9..cb5488c 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/BubbleViewTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/BubbleViewTest.kt
@@ -65,7 +65,7 @@
overflowView.setOverflow(BubbleBarOverflow(overflowView), bitmap)
val bubbleInfo =
- BubbleInfo("key", 0, null, null, 0, context.packageName, null, null, false)
+ BubbleInfo("key", 0, null, null, 0, context.packageName, null, null, false, true)
bubbleView = inflater.inflate(R.layout.bubblebar_item_view, null, false) as BubbleView
bubble =
BubbleBarBubble(bubbleInfo, bubbleView, bitmap, bitmap, Color.WHITE, Path(), "")
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
index 7928ce9..2bca74a 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/animation/BubbleBarViewAnimatorTest.kt
@@ -870,7 +870,7 @@
bubbleBarView.addView(overflowView)
val bubbleInfo =
- BubbleInfo("key", 0, null, null, 0, context.packageName, null, null, false)
+ BubbleInfo("key", 0, null, null, 0, context.packageName, null, null, false, true)
bubbleView =
inflater.inflate(R.layout.bubblebar_item_view, bubbleBarView, false) as BubbleView
bubble =
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java
new file mode 100644
index 0000000..2a0aa4c
--- /dev/null
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/AbsSwipeUpHandlerTestCase.java
@@ -0,0 +1,276 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.doNothing;
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.app.ActivityManager;
+import android.content.Context;
+import android.content.Intent;
+import android.content.res.Configuration;
+import android.graphics.PointF;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.SystemClock;
+import android.view.RemoteAnimationTarget;
+import android.view.SurfaceControl;
+import android.view.ViewTreeObserver;
+
+import androidx.annotation.NonNull;
+import androidx.test.platform.app.InstrumentationRegistry;
+
+import com.android.launcher3.DeviceProfile;
+import com.android.launcher3.LauncherRootView;
+import com.android.launcher3.dragndrop.DragLayer;
+import com.android.launcher3.statemanager.BaseState;
+import com.android.launcher3.statemanager.StatefulActivity;
+import com.android.launcher3.util.SystemUiController;
+import com.android.quickstep.util.ActivityInitListener;
+import com.android.quickstep.views.RecentsView;
+import com.android.quickstep.views.RecentsViewContainer;
+import com.android.systemui.shared.system.InputConsumerController;
+
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.mockito.Mock;
+import org.mockito.junit.MockitoJUnit;
+import org.mockito.junit.MockitoRule;
+
+import java.util.Collections;
+import java.util.HashMap;
+
+public abstract class AbsSwipeUpHandlerTestCase<
+ RECENTS_CONTAINER extends Context & RecentsViewContainer,
+ STATE extends BaseState<STATE>,
+ RECENTS_VIEW extends RecentsView<RECENTS_CONTAINER, STATE>,
+ ACTIVITY_TYPE extends StatefulActivity<STATE> & RecentsViewContainer,
+ ACTIVITY_INTERFACE extends BaseActivityInterface<STATE, ACTIVITY_TYPE>,
+ SWIPE_HANDLER extends AbsSwipeUpHandler<RECENTS_CONTAINER, RECENTS_VIEW, STATE>> {
+
+ protected final Context mContext =
+ InstrumentationRegistry.getInstrumentation().getTargetContext();
+ protected final TaskAnimationManager mTaskAnimationManager = new TaskAnimationManager(mContext);
+ protected final RecentsAnimationDeviceState mRecentsAnimationDeviceState =
+ new RecentsAnimationDeviceState(mContext, true);
+ protected final InputConsumerController mInputConsumerController =
+ InputConsumerController.getRecentsAnimationInputConsumer();
+ protected final ActivityManager.RunningTaskInfo mRunningTaskInfo =
+ new ActivityManager.RunningTaskInfo();
+ protected final TopTaskTracker.CachedTaskInfo mCachedTaskInfo =
+ new TopTaskTracker.CachedTaskInfo(Collections.singletonList(mRunningTaskInfo));
+ protected final RemoteAnimationTarget mRemoteAnimationTarget = new RemoteAnimationTarget(
+ /* taskId= */ 0,
+ /* mode= */ RemoteAnimationTarget.MODE_CLOSING,
+ /* leash= */ new SurfaceControl(),
+ /* isTranslucent= */ false,
+ /* clipRect= */ null,
+ /* contentInsets= */ null,
+ /* prefixOrderIndex= */ 0,
+ /* position= */ null,
+ /* localBounds= */ null,
+ /* screenSpaceBounds= */ null,
+ new Configuration().windowConfiguration,
+ /* isNotInRecents= */ false,
+ /* startLeash= */ null,
+ /* startBounds= */ null,
+ /* taskInfo= */ mRunningTaskInfo,
+ /* allowEnterPip= */ false);
+ protected final RecentsAnimationTargets mRecentsAnimationTargets = new RecentsAnimationTargets(
+ new RemoteAnimationTarget[] {mRemoteAnimationTarget},
+ new RemoteAnimationTarget[] {mRemoteAnimationTarget},
+ new RemoteAnimationTarget[] {mRemoteAnimationTarget},
+ /* homeContentInsets= */ new Rect(),
+ /* minimizedHomeBounds= */ null,
+ new Bundle());
+
+ @Mock protected ACTIVITY_INTERFACE mActivityInterface;
+ @Mock protected ActivityInitListener<?> mActivityInitListener;
+ @Mock protected RecentsAnimationController mRecentsAnimationController;
+ @Mock protected STATE mState;
+ @Mock protected ViewTreeObserver mViewTreeObserver;
+ @Mock protected DragLayer mDragLayer;
+ @Mock protected LauncherRootView mRootView;
+ @Mock protected SystemUiController mSystemUiController;
+ @Mock protected GestureState mGestureState;
+
+ @Rule
+ public final MockitoRule mMockitoRule = MockitoJUnit.rule();
+
+ @Before
+ public void setUpRunningTaskInfo() {
+ mRunningTaskInfo.baseIntent = new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_HOME)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
+ }
+
+ @Before
+ public void setUpGestureState() {
+ when(mGestureState.getRunningTask()).thenReturn(mCachedTaskInfo);
+ when(mGestureState.getLastAppearedTaskIds()).thenReturn(new int[0]);
+ when(mGestureState.getLastStartedTaskIds()).thenReturn(new int[1]);
+ when(mGestureState.getHomeIntent()).thenReturn(new Intent(Intent.ACTION_MAIN)
+ .addCategory(Intent.CATEGORY_HOME)
+ .setFlags(Intent.FLAG_ACTIVITY_NEW_TASK));
+ doReturn(mActivityInterface).when(mGestureState).getContainerInterface();
+ }
+
+ @Before
+ public void setUpRecentsView() {
+ RECENTS_VIEW recentsView = getRecentsView();
+ when(recentsView.getViewTreeObserver()).thenReturn(mViewTreeObserver);
+ doAnswer(answer -> {
+ runOnMainSync(() -> answer.<Runnable>getArgument(0).run());
+ return this;
+ }).when(recentsView).runOnPageScrollsInitialized(any());
+ }
+
+ @Before
+ public void setUpRecentsContainer() {
+ RecentsViewContainer recentsContainer = getRecentsContainer();
+ RECENTS_VIEW recentsView = getRecentsView();
+
+ when(recentsContainer.getDeviceProfile()).thenReturn(new DeviceProfile());
+ when(recentsContainer.getOverviewPanel()).thenReturn(recentsView);
+ when(recentsContainer.getDragLayer()).thenReturn(mDragLayer);
+ when(recentsContainer.getRootView()).thenReturn(mRootView);
+ when(recentsContainer.getSystemUiController()).thenReturn(mSystemUiController);
+ when(mActivityInterface.createActivityInitListener(any()))
+ .thenReturn(mActivityInitListener);
+ doReturn(recentsContainer).when(mActivityInterface).getCreatedContainer();
+ doAnswer(answer -> {
+ answer.<Runnable>getArgument(0).run();
+ return this;
+ }).when(recentsContainer).runOnBindToTouchInteractionService(any());
+ }
+
+ @Test
+ public void testInitWhenReady_registersActivityInitListener() {
+ String reasonString = "because i said so";
+
+ createSwipeHandler().initWhenReady(reasonString);
+ verify(mActivityInitListener).register(eq(reasonString));
+ }
+
+ @Test
+ public void testOnRecentsAnimationCanceled_unregistersActivityInitListener() {
+ createSwipeHandler()
+ .onRecentsAnimationCanceled(new HashMap<>());
+
+ runOnMainSync(() -> verify(mActivityInitListener)
+ .unregister(eq("AbsSwipeUpHandler.onRecentsAnimationCanceled")));
+ }
+
+ @Test
+ public void testOnConsumerAboutToBeSwitched_unregistersActivityInitListener() {
+ createSwipeHandler().onConsumerAboutToBeSwitched();
+
+ runOnMainSync(() -> verify(mActivityInitListener)
+ .unregister("AbsSwipeUpHandler.invalidateHandler"));
+ }
+
+ @Test
+ public void testOnConsumerAboutToBeSwitched_midQuickSwitch_unregistersActivityInitListener() {
+ createSwipeUpHandlerForGesture(GestureState.GestureEndTarget.NEW_TASK)
+ .onConsumerAboutToBeSwitched();
+
+ runOnMainSync(() -> verify(mActivityInitListener)
+ .unregister(eq("AbsSwipeUpHandler.cancelCurrentAnimation")));
+ }
+
+ @Test
+ public void testStartNewTask_finishesRecentsAnimationController() {
+ SWIPE_HANDLER absSwipeUpHandler = createSwipeHandler();
+
+ onRecentsAnimationStart(absSwipeUpHandler);
+
+ runOnMainSync(() -> {
+ absSwipeUpHandler.startNewTask(unused -> {});
+ verify(mRecentsAnimationController).finish(anyBoolean(), any());
+ });
+ }
+
+ @Test
+ public void testHomeGesture_finishesRecentsAnimationController() {
+ createSwipeUpHandlerForGesture(GestureState.GestureEndTarget.HOME);
+
+ runOnMainSync(() -> {
+ verify(mRecentsAnimationController).detachNavigationBarFromApp(true);
+ verify(mRecentsAnimationController).finish(anyBoolean(), any(), anyBoolean());
+ });
+ }
+
+ private SWIPE_HANDLER createSwipeUpHandlerForGesture(GestureState.GestureEndTarget endTarget) {
+ boolean isQuickSwitch = endTarget == GestureState.GestureEndTarget.NEW_TASK;
+
+ doReturn(mState).when(mActivityInterface).stateFromGestureEndTarget(any());
+
+ SWIPE_HANDLER swipeHandler = createSwipeHandler(SystemClock.uptimeMillis(), isQuickSwitch);
+
+ swipeHandler.onActivityInit(/* alreadyOnHome= */ false);
+ swipeHandler.onGestureStarted(isQuickSwitch);
+ onRecentsAnimationStart(swipeHandler);
+
+ when(mGestureState.getRunningTaskIds(anyBoolean())).thenReturn(new int[0]);
+ runOnMainSync(swipeHandler::switchToScreenshot);
+
+ when(mGestureState.getEndTarget()).thenReturn(endTarget);
+ when(mGestureState.isRecentsAnimationRunning()).thenReturn(isQuickSwitch);
+ float xVelocityPxPerMs = isQuickSwitch ? 100 : 0;
+ float yVelocityPxPerMs = isQuickSwitch ? 0 : -100;
+ swipeHandler.onGestureEnded(
+ yVelocityPxPerMs, new PointF(xVelocityPxPerMs, yVelocityPxPerMs));
+ swipeHandler.onCalculateEndTarget();
+ runOnMainSync(swipeHandler::onSettledOnEndTarget);
+
+ return swipeHandler;
+ }
+
+ private void onRecentsAnimationStart(SWIPE_HANDLER absSwipeUpHandler) {
+ when(mActivityInterface.getOverviewWindowBounds(any(), any())).thenReturn(new Rect());
+ doNothing().when(mActivityInterface).setOnDeferredActivityLaunchCallback(any());
+
+ runOnMainSync(() -> absSwipeUpHandler.onRecentsAnimationStart(
+ mRecentsAnimationController, mRecentsAnimationTargets));
+ }
+
+ private static void runOnMainSync(Runnable runnable) {
+ InstrumentationRegistry.getInstrumentation().runOnMainSync(runnable);
+ }
+
+ @NonNull
+ private SWIPE_HANDLER createSwipeHandler() {
+ return createSwipeHandler(SystemClock.uptimeMillis(), false);
+ }
+
+ @NonNull
+ protected abstract SWIPE_HANDLER createSwipeHandler(
+ long touchTimeMs, boolean continuingLastGesture);
+
+ @NonNull
+ protected abstract RecentsViewContainer getRecentsContainer();
+
+ @NonNull
+ protected abstract RECENTS_VIEW getRecentsView();
+}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/FallbackSwipeHandlerTestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/FallbackSwipeHandlerTestCase.java
new file mode 100644
index 0000000..dd0b4b3
--- /dev/null
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/FallbackSwipeHandlerTestCase.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.launcher3.util.LauncherMultivalentJUnit;
+import com.android.quickstep.fallback.FallbackRecentsView;
+import com.android.quickstep.fallback.RecentsState;
+
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+@SmallTest
+@RunWith(LauncherMultivalentJUnit.class)
+public class FallbackSwipeHandlerTestCase extends AbsSwipeUpHandlerTestCase<
+ RecentsActivity,
+ RecentsState,
+ FallbackRecentsView,
+ RecentsActivity,
+ FallbackActivityInterface,
+ FallbackSwipeHandler> {
+
+ @Mock private RecentsActivity mRecentsActivity;
+ @Mock private FallbackRecentsView mRecentsView;
+
+
+ @Override
+ protected FallbackSwipeHandler createSwipeHandler(
+ long touchTimeMs, boolean continuingLastGesture) {
+ return new FallbackSwipeHandler(
+ mContext,
+ mRecentsAnimationDeviceState,
+ mTaskAnimationManager,
+ mGestureState,
+ touchTimeMs,
+ continuingLastGesture,
+ mInputConsumerController);
+ }
+
+ @Override
+ protected RecentsActivity getRecentsContainer() {
+ return mRecentsActivity;
+ }
+
+ @Override
+ protected FallbackRecentsView getRecentsView() {
+ return mRecentsView;
+ }
+}
diff --git a/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2TestCase.java b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2TestCase.java
new file mode 100644
index 0000000..653dc01
--- /dev/null
+++ b/quickstep/tests/multivalentTests/src/com/android/quickstep/LauncherSwipeHandlerV2TestCase.java
@@ -0,0 +1,92 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.quickstep;
+
+import static org.mockito.Mockito.doReturn;
+import static org.mockito.Mockito.when;
+
+import androidx.test.filters.SmallTest;
+
+import com.android.launcher3.Hotseat;
+import com.android.launcher3.LauncherState;
+import com.android.launcher3.Workspace;
+import com.android.launcher3.WorkspaceStateTransitionAnimation;
+import com.android.launcher3.statemanager.StateManager;
+import com.android.launcher3.statemanager.StateManager.AtomicAnimationFactory;
+import com.android.launcher3.uioverrides.QuickstepLauncher;
+import com.android.launcher3.util.LauncherMultivalentJUnit;
+import com.android.quickstep.views.RecentsView;
+
+import org.junit.Before;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+
+@SmallTest
+@RunWith(LauncherMultivalentJUnit.class)
+public class LauncherSwipeHandlerV2TestCase extends AbsSwipeUpHandlerTestCase<
+ QuickstepLauncher,
+ LauncherState,
+ RecentsView<QuickstepLauncher, LauncherState>,
+ QuickstepLauncher,
+ LauncherActivityInterface,
+ LauncherSwipeHandlerV2> {
+
+ @Mock private QuickstepLauncher mQuickstepLauncher;
+ @Mock private RecentsView<QuickstepLauncher, LauncherState> mRecentsView;
+ @Mock private Workspace<?> mWorkspace;
+ @Mock private Hotseat mHotseat;
+ @Mock private WorkspaceStateTransitionAnimation mTransitionAnimation;
+
+ @Before
+ public void setUpQuickStepLauncher() {
+ when(mQuickstepLauncher.createAtomicAnimationFactory())
+ .thenReturn(new AtomicAnimationFactory<>(0));
+ when(mQuickstepLauncher.getHotseat()).thenReturn(mHotseat);
+ doReturn(mWorkspace).when(mQuickstepLauncher).getWorkspace();
+ doReturn(new StateManager(mQuickstepLauncher, LauncherState.NORMAL))
+ .when(mQuickstepLauncher).getStateManager();
+
+ }
+
+ @Before
+ public void setUpWorkspace() {
+ when(mWorkspace.getStateTransitionAnimation()).thenReturn(mTransitionAnimation);
+ }
+
+ @Override
+ protected LauncherSwipeHandlerV2 createSwipeHandler(
+ long touchTimeMs, boolean continuingLastGesture) {
+ return new LauncherSwipeHandlerV2(
+ mContext,
+ mRecentsAnimationDeviceState,
+ mTaskAnimationManager,
+ mGestureState,
+ touchTimeMs,
+ continuingLastGesture,
+ mInputConsumerController);
+ }
+
+ @Override
+ protected QuickstepLauncher getRecentsContainer() {
+ return mQuickstepLauncher;
+ }
+
+ @Override
+ protected RecentsView<QuickstepLauncher, LauncherState> getRecentsView() {
+ return mRecentsView;
+ }
+}
diff --git a/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java b/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java
index 3a83ae3..28c8a4a 100644
--- a/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java
+++ b/quickstep/tests/src/com/android/quickstep/TaskAnimationManagerTest.java
@@ -59,8 +59,6 @@
@Test
public void startRecentsActivity_allowBackgroundLaunch() {
- assumeTrue(TaskAnimationManager.ENABLE_SHELL_TRANSITIONS);
-
final LauncherActivityInterface activityInterface = mock(LauncherActivityInterface.class);
final GestureState gestureState = mock(GestureState.class);
final RecentsAnimationCallbacks.RecentsAnimationListener listener =
diff --git a/res/values/styles.xml b/res/values/styles.xml
index ee7ed26..2d7808b 100644
--- a/res/values/styles.xml
+++ b/res/values/styles.xml
@@ -77,6 +77,10 @@
<item name="materialColorError">@color/system_error_light</item>
</style>
+ <style name="DynamicColorsBaseLauncherTheme.NoActionBar">
+ <item name="windowActionBar">false</item>
+ <item name="windowNoTitle">true</item>
+ </style>
<style name="LauncherTheme" parent="@style/DynamicColorsBaseLauncherTheme">
<item name="android:textColorSecondary">#DE000000</item>
diff --git a/src/com/android/launcher3/BaseActivity.java b/src/com/android/launcher3/BaseActivity.java
index 633091d..fec94fe 100644
--- a/src/com/android/launcher3/BaseActivity.java
+++ b/src/com/android/launcher3/BaseActivity.java
@@ -110,11 +110,6 @@
public static final int ACTIVITY_STATE_USER_ACTIVE = 1 << 4;
/**
- * State flag indicating if the user will be active shortly.
- */
- public static final int ACTIVITY_STATE_USER_WILL_BE_ACTIVE = 1 << 5;
-
- /**
* State flag indicating that a state transition is in progress
*/
public static final int ACTIVITY_STATE_TRANSITION_ACTIVE = 1 << 6;
@@ -316,7 +311,6 @@
*/
public void setResumed() {
addActivityFlags(ACTIVITY_STATE_RESUMED | ACTIVITY_STATE_USER_ACTIVE);
- removeActivityFlags(ACTIVITY_STATE_USER_WILL_BE_ACTIVE);
}
public boolean isUserActive() {
diff --git a/src/com/android/launcher3/BubbleTextView.java b/src/com/android/launcher3/BubbleTextView.java
index 26e900d..8121e53 100644
--- a/src/com/android/launcher3/BubbleTextView.java
+++ b/src/com/android/launcher3/BubbleTextView.java
@@ -89,7 +89,7 @@
import com.android.launcher3.util.ShortcutUtil;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.views.IconLabelDotView;
+import com.android.launcher3.views.FloatingIconViewCompanion;
import java.text.NumberFormat;
import java.util.HashMap;
@@ -101,7 +101,7 @@
* too aggressive.
*/
public class BubbleTextView extends TextView implements ItemInfoUpdateReceiver,
- IconLabelDotView, DraggableView, Reorderable {
+ FloatingIconViewCompanion, DraggableView, Reorderable {
public static final String TAG = "BubbleTextView";
diff --git a/src/com/android/launcher3/DeviceProfile.java b/src/com/android/launcher3/DeviceProfile.java
index 5cbf6fb..8ae6d73 100644
--- a/src/com/android/launcher3/DeviceProfile.java
+++ b/src/com/android/launcher3/DeviceProfile.java
@@ -316,6 +316,74 @@
// DragController
public int flingToDeleteThresholdVelocity;
+ /** Used only as an alternative to mocking when null values cannot be used. */
+ @VisibleForTesting
+ public DeviceProfile() {
+ inv = null;
+ mInfo = null;
+ mMetrics = null;
+ mIconSizeSteps = null;
+ isTablet = false;
+ isPhone = false;
+ transposeLayoutWithOrientation = false;
+ isMultiDisplay = false;
+ isTwoPanels = false;
+ isPredictiveBackSwipe = false;
+ isQsbInline = false;
+ isLandscape = false;
+ isMultiWindowMode = false;
+ isGestureMode = false;
+ isLeftRightSplit = false;
+ windowX = 0;
+ windowY = 0;
+ widthPx = 0;
+ heightPx = 0;
+ availableWidthPx = 0;
+ availableHeightPx = 0;
+ rotationHint = 0;
+ aspectRatio = 1;
+ mIsScalableGrid = false;
+ mTypeIndex = 0;
+ mIsResponsiveGrid = false;
+ desiredWorkspaceHorizontalMarginOriginalPx = 0;
+ edgeMarginPx = 0;
+ workspaceContentScale = 0;
+ workspaceSpringLoadedMinNextPageVisiblePx = 0;
+ extraSpace = 0;
+ workspacePageIndicatorHeight = 0;
+ mWorkspacePageIndicatorOverlapWorkspace = 0;
+ numFolderRows = 0;
+ numFolderColumns = 0;
+ folderLabelTextScale = 0;
+ areNavButtonsInline = false;
+ mHotseatBarEdgePaddingPx = 0;
+ mHotseatBarWorkspaceSpacePx = 0;
+ hotseatQsbWidth = 0;
+ hotseatQsbHeight = 0;
+ hotseatQsbVisualHeight = 0;
+ hotseatQsbShadowHeight = 0;
+ hotseatBorderSpace = 0;
+ mMinHotseatIconSpacePx = 0;
+ mMinHotseatQsbWidthPx = 0;
+ mMaxHotseatIconSpacePx = 0;
+ inlineNavButtonsEndSpacingPx = 0;
+ mBubbleBarSpaceThresholdPx = 0;
+ numShownAllAppsColumns = 0;
+ overviewActionsHeight = 0;
+ overviewActionsTopMarginPx = 0;
+ overviewActionsButtonSpacing = 0;
+ mViewScaleProvider = null;
+ mDotRendererWorkSpace = null;
+ mDotRendererAllApps = null;
+ taskbarHeight = 0;
+ stashedTaskbarHeight = 0;
+ taskbarBottomMargin = 0;
+ taskbarIconSize = 0;
+ mTransientTaskbarClaimedSpace = 0;
+ startAlignTaskbar = false;
+ isTransientTaskbar = false;
+ }
+
/** TODO: Once we fully migrate to staged split, remove "isMultiWindowMode" */
DeviceProfile(Context context, InvariantDeviceProfile inv, Info info, WindowBounds windowBounds,
SparseArray<DotRenderer> dotRendererCache, boolean isMultiWindowMode,
diff --git a/src/com/android/launcher3/debug/TestEventsEmitterProduction.kt b/src/com/android/launcher3/debug/TestEventsEmitterProduction.kt
index e218b4d..52b454f 100644
--- a/src/com/android/launcher3/debug/TestEventsEmitterProduction.kt
+++ b/src/com/android/launcher3/debug/TestEventsEmitterProduction.kt
@@ -27,6 +27,8 @@
WORKSPACE_ON_DROP("WORKSPACE_ON_DROP"),
RESIZE_FRAME_SHOWING("RESIZE_FRAME_SHOWING"),
WORKSPACE_FINISH_LOADING("WORKSPACE_FINISH_LOADING"),
+ SPRING_LOADED_STATE_STARTED("SPRING_LOADED_STATE_STARTED"),
+ SPRING_LOADED_STATE_COMPLETED("SPRING_LOADED_STATE_COMPLETED"),
}
/** Interface to create TestEventEmitters. */
diff --git a/src/com/android/launcher3/folder/FolderIcon.java b/src/com/android/launcher3/folder/FolderIcon.java
index a0b695a..de1bcc3 100644
--- a/src/com/android/launcher3/folder/FolderIcon.java
+++ b/src/com/android/launcher3/folder/FolderIcon.java
@@ -83,7 +83,7 @@
import com.android.launcher3.util.MultiTranslateDelegate;
import com.android.launcher3.util.Thunk;
import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.views.IconLabelDotView;
+import com.android.launcher3.views.FloatingIconViewCompanion;
import com.android.launcher3.widget.PendingAddShortcutInfo;
import java.util.ArrayList;
@@ -93,7 +93,7 @@
/**
* An icon that can appear on in the workspace representing an {@link Folder}.
*/
-public class FolderIcon extends FrameLayout implements FolderListener, IconLabelDotView,
+public class FolderIcon extends FrameLayout implements FolderListener, FloatingIconViewCompanion,
DraggableView, Reorderable {
private final MultiTranslateDelegate mTranslateDelegate = new MultiTranslateDelegate(this);
diff --git a/src/com/android/launcher3/views/BubbleTextHolder.java b/src/com/android/launcher3/views/BubbleTextHolder.java
index 84f8049..d2ae93b 100644
--- a/src/com/android/launcher3/views/BubbleTextHolder.java
+++ b/src/com/android/launcher3/views/BubbleTextHolder.java
@@ -20,7 +20,7 @@
/**
* Views that contain {@link BubbleTextView} should implement this interface.
*/
-public interface BubbleTextHolder extends IconLabelDotView {
+public interface BubbleTextHolder extends FloatingIconViewCompanion {
BubbleTextView getBubbleText();
@Override
diff --git a/src/com/android/launcher3/views/FloatingIconView.java b/src/com/android/launcher3/views/FloatingIconView.java
index 37482ac..4ee6aff 100644
--- a/src/com/android/launcher3/views/FloatingIconView.java
+++ b/src/com/android/launcher3/views/FloatingIconView.java
@@ -22,7 +22,7 @@
import static com.android.launcher3.Utilities.getFullDrawable;
import static com.android.launcher3.Utilities.mapToRange;
import static com.android.launcher3.util.Executors.MODEL_EXECUTOR;
-import static com.android.launcher3.views.IconLabelDotView.setIconAndDotVisible;
+import static com.android.launcher3.views.FloatingIconViewCompanion.setPropertiesVisible;
import android.animation.Animator;
import android.content.Context;
@@ -516,6 +516,10 @@
// When closing an app, we want the item on the workspace to be invisible immediately
updateViewsVisibility(false /* isVisible */);
}
+ if (mFadeOutView instanceof FloatingIconViewCompanion fivc) {
+ fivc.setForceHideDot(true);
+ fivc.setForceHideRing(true);
+ }
}
@Override
@@ -653,6 +657,10 @@
if (view.mFadeOutView != null) {
view.mFadeOutView.setAlpha(1f);
}
+ if (view.mFadeOutView instanceof FloatingIconViewCompanion fivc) {
+ fivc.setForceHideDot(false);
+ fivc.setForceHideRing(false);
+ }
if (hideOriginal) {
view.updateViewsVisibility(true /* isVisible */);
@@ -674,10 +682,10 @@
private void updateViewsVisibility(boolean isVisible) {
if (mOriginalIcon != null) {
- setIconAndDotVisible(mOriginalIcon, isVisible);
+ setPropertiesVisible(mOriginalIcon, isVisible);
}
if (mMatchVisibilityView != null) {
- setIconAndDotVisible(mMatchVisibilityView, isVisible);
+ setPropertiesVisible(mMatchVisibilityView, isVisible);
}
}
diff --git a/src/com/android/launcher3/views/FloatingIconViewCompanion.java b/src/com/android/launcher3/views/FloatingIconViewCompanion.java
new file mode 100644
index 0000000..fc23903
--- /dev/null
+++ b/src/com/android/launcher3/views/FloatingIconViewCompanion.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (C) 2019 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.views;
+
+import android.view.View;
+
+/**
+ * A view that can be drawn (in some capacity) via) {@link FloatingIconView}.
+ * This interface allows us to hide certain properties of the view that the FloatingIconView
+ * cannot draw, which allows us to make a seamless handoff between the FloatingIconView and
+ * the companion view.
+ */
+public interface FloatingIconViewCompanion {
+ void setIconVisible(boolean visible);
+ void setForceHideDot(boolean hide);
+ default void setForceHideRing(boolean hide) {}
+
+ /**
+ * Sets the visibility of icon and dot of the view
+ */
+ static void setPropertiesVisible(View view, boolean visible) {
+ if (view instanceof FloatingIconViewCompanion) {
+ ((FloatingIconViewCompanion) view).setIconVisible(visible);
+ ((FloatingIconViewCompanion) view).setForceHideDot(!visible);
+ ((FloatingIconViewCompanion) view).setForceHideRing(!visible);
+ } else {
+ view.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+ }
+ }
+}
diff --git a/src/com/android/launcher3/views/FloatingSurfaceView.java b/src/com/android/launcher3/views/FloatingSurfaceView.java
index cab7982..7fa7517 100644
--- a/src/com/android/launcher3/views/FloatingSurfaceView.java
+++ b/src/com/android/launcher3/views/FloatingSurfaceView.java
@@ -17,7 +17,7 @@
import static com.android.launcher3.model.data.ItemInfo.NO_MATCHING_ID;
import static com.android.launcher3.views.FloatingIconView.getLocationBoundsForView;
-import static com.android.launcher3.views.IconLabelDotView.setIconAndDotVisible;
+import static com.android.launcher3.views.FloatingIconViewCompanion.setPropertiesVisible;
import android.content.Context;
import android.graphics.Canvas;
@@ -237,7 +237,7 @@
private void setCurrentIconVisible(boolean isVisible) {
if (mIcon != null) {
- setIconAndDotVisible(mIcon, isVisible);
+ setPropertiesVisible(mIcon, isVisible);
}
}
}
diff --git a/src/com/android/launcher3/views/IconLabelDotView.java b/src/com/android/launcher3/views/IconLabelDotView.java
deleted file mode 100644
index e9113cf..0000000
--- a/src/com/android/launcher3/views/IconLabelDotView.java
+++ /dev/null
@@ -1,38 +0,0 @@
-/*
- * Copyright (C) 2019 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.views;
-
-import android.view.View;
-
-/**
- * A view that has an icon, label, and notification dot.
- */
-public interface IconLabelDotView {
- void setIconVisible(boolean visible);
- void setForceHideDot(boolean hide);
-
- /**
- * Sets the visibility of icon and dot of the view
- */
- static void setIconAndDotVisible(View view, boolean visible) {
- if (view instanceof IconLabelDotView) {
- ((IconLabelDotView) view).setIconVisible(visible);
- ((IconLabelDotView) view).setForceHideDot(!visible);
- } else {
- view.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
- }
- }
-}
diff --git a/tests/Android.bp b/tests/Android.bp
index 1fa6e05..9f62d02 100644
--- a/tests/Android.bp
+++ b/tests/Android.bp
@@ -127,9 +127,9 @@
"com_android_launcher3_flags_lib",
],
libs: [
- "android.test.base",
- "android.test.runner",
- "android.test.mock",
+ "android.test.base.stubs.system",
+ "android.test.runner.stubs.system",
+ "android.test.mock.stubs.system",
],
// Libraries used by mockito inline extended
jni_libs: [
@@ -229,9 +229,9 @@
"android.appwidget.flags-aconfig-java",
],
libs: [
- "android.test.runner",
- "android.test.base",
- "android.test.mock",
+ "android.test.runner.stubs.system",
+ "android.test.base.stubs.system",
+ "android.test.mock.stubs.system",
"truth",
],
instrumentation_for: "Launcher3",
diff --git a/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java b/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java
index 9b184ae..9c916fa 100644
--- a/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java
+++ b/tests/src/com/android/launcher3/ui/widget/TaplAddWidgetTest.java
@@ -15,9 +15,6 @@
*/
package com.android.launcher3.ui.widget;
-import static com.android.launcher3.util.rule.TestStabilityRule.LOCAL;
-import static com.android.launcher3.util.rule.TestStabilityRule.PLATFORM_POSTSUBMIT;
-
import static org.junit.Assert.assertNotNull;
import android.platform.test.annotations.PlatinumTest;
@@ -33,7 +30,6 @@
import com.android.launcher3.ui.PortraitLandscapeRunner.PortraitLandscape;
import com.android.launcher3.ui.TestViewHelpers;
import com.android.launcher3.util.rule.ShellCommandRule;
-import com.android.launcher3.util.rule.TestStabilityRule.Stability;
import com.android.launcher3.widget.LauncherAppWidgetProviderInfo;
import org.junit.Assume;
@@ -102,7 +98,6 @@
/**
* Test dragging a widget to the workspace and resize it.
*/
- @Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT) // b/316910614
@PlatinumTest(focusArea = "launcher")
@Test
public void testResizeWidget() throws Throwable {