Merge "Add a test base for AbsSwipeUpHandler and its subclasses" 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 d981882..ce3f3ac 100644
--- a/quickstep/res/values/dimens.xml
+++ b/quickstep/res/values/dimens.xml
@@ -437,6 +437,7 @@
<dimen name="bubblebar_stashed_handle_width">55dp</dimen>
<dimen name="bubblebar_stashed_size">@dimen/transient_taskbar_stashed_height</dimen>
<dimen name="bubblebar_stashed_handle_height">@dimen/taskbar_stashed_handle_height</dimen>
+ <dimen name="bubblebar_stashed_handle_spring_velocity_dp_per_s">@dimen/transient_taskbar_stash_spring_velocity_dp_per_s</dimen>
<!-- this is a pointer height minus 1dp to ensure the pointer overlaps with the bubblebar
background appropriately when close to the rounded corner -->
<dimen name="bubblebar_pointer_visible_size">9dp</dimen>
@@ -487,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/TaskbarActivityContext.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
index 0c1235c..47ae741 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarActivityContext.java
@@ -29,7 +29,6 @@
import static com.android.launcher3.AbstractFloatingView.TYPE_REBIND_SAFE;
import static com.android.launcher3.AbstractFloatingView.TYPE_TASKBAR_OVERLAY_PROXY;
import static com.android.launcher3.Flags.enableCursorHoverStates;
-import static com.android.launcher3.Flags.enableTaskbarCustomization;
import static com.android.launcher3.Utilities.calculateTextHeight;
import static com.android.launcher3.Utilities.isRunningInTestHarness;
import static com.android.launcher3.config.FeatureFlags.ENABLE_TASKBAR_NAVBAR_UNIFICATION;
@@ -230,15 +229,12 @@
mNavigationBarPanelContext = navigationBarPanelContext;
applyDeviceProfile(launcherDp);
final Resources resources = getResources();
-
- if (enableTaskbarCustomization()) {
- mTaskbarFeatureEvaluator = TaskbarFeatureEvaluator.getInstance(this);
- mTaskbarSpecsEvaluator = new TaskbarSpecsEvaluator(
- this,
- mTaskbarFeatureEvaluator,
- mDeviceProfile.inv.numRows,
- mDeviceProfile.inv.numColumns);
- }
+ mTaskbarFeatureEvaluator = TaskbarFeatureEvaluator.getInstance(this);
+ mTaskbarSpecsEvaluator = new TaskbarSpecsEvaluator(
+ this,
+ mTaskbarFeatureEvaluator,
+ mDeviceProfile.inv.numRows,
+ mDeviceProfile.inv.numColumns);
mImeDrawsImeNavBar = getBoolByName(IME_DRAWS_IME_NAV_BAR_RES_NAME, resources, false);
mIsSafeModeEnabled = TraceHelper.allowIpcs("isSafeMode",
@@ -287,7 +283,7 @@
TaskbarHotseatDimensionsProvider dimensionsProvider =
new DeviceProfileDimensionsProviderAdapter(this);
BubbleStashController bubbleStashController = isTransientTaskbar
- ? new TransientBubbleStashController(dimensionsProvider, getResources())
+ ? new TransientBubbleStashController(dimensionsProvider, this)
: new PersistentBubbleStashController(dimensionsProvider);
bubbleControllersOptional = Optional.of(new BubbleControllers(
new BubbleBarController(this, bubbleBarView),
@@ -1761,12 +1757,10 @@
return mControllers.taskbarStashController.isInStashedLauncherState();
}
- @Nullable
public TaskbarFeatureEvaluator getTaskbarFeatureEvaluator() {
return mTaskbarFeatureEvaluator;
}
- @Nullable
public TaskbarSpecsEvaluator getTaskbarSpecsEvaluator() {
return mTaskbarSpecsEvaluator;
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
index a635537..b5a3314 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarDividerPopupView.kt
@@ -169,8 +169,11 @@
override fun addArrow() {
super.addArrow()
+ val location = IntArray(2)
+ popupContainer.getLocationInDragLayer(dividerView, location)
+ val dividerViewX = location[0].toFloat()
// Change arrow location to the middle of popup.
- mArrow.x = (dividerView.x + dividerView.width / 2) - (mArrowWidth / 2)
+ mArrow.x = (dividerViewX + dividerView.width / 2) - (mArrowWidth / 2)
}
override fun updateArrowColor() {
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/TaskbarView.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
index 54a7fdc..8b8b4da 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarView.java
@@ -22,10 +22,8 @@
import static com.android.launcher3.Flags.enableRecentsInTaskbar;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_APP_PAIR;
import static com.android.launcher3.LauncherSettings.Favorites.ITEM_TYPE_FOLDER;
-import static com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_SEARCH_IN_TASKBAR;
import static com.android.launcher3.config.FeatureFlags.enableTaskbarPinning;
import static com.android.launcher3.icons.IconNormalizer.ICON_VISIBLE_AREA_FACTOR;
-import static com.android.launcher3.util.Executors.MAIN_EXECUTOR;
import android.content.Context;
import android.content.res.Resources;
@@ -39,12 +37,9 @@
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
-import android.view.ViewConfiguration;
import android.view.accessibility.AccessibilityNodeInfo;
import android.widget.FrameLayout;
-import androidx.annotation.DimenRes;
-import androidx.annotation.DrawableRes;
import androidx.annotation.LayoutRes;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -62,13 +57,12 @@
import com.android.launcher3.model.data.FolderInfo;
import com.android.launcher3.model.data.ItemInfo;
import com.android.launcher3.model.data.WorkspaceItemInfo;
+import com.android.launcher3.taskbar.customization.TaskbarAllAppsButtonContainer;
+import com.android.launcher3.taskbar.customization.TaskbarDividerContainer;
import com.android.launcher3.util.DisplayController;
import com.android.launcher3.util.LauncherBindableItemsContainer;
import com.android.launcher3.util.Themes;
import com.android.launcher3.views.ActivityContext;
-import com.android.launcher3.views.IconButtonView;
-import com.android.quickstep.DeviceConfigWrapper;
-import com.android.quickstep.util.AssistStateManager;
import com.android.quickstep.util.DesktopTask;
import com.android.quickstep.util.GroupTask;
import com.android.systemui.shared.recents.model.Task;
@@ -100,16 +94,13 @@
private View.OnLongClickListener mIconLongClickListener;
// Only non-null when the corresponding Folder is open.
- private @Nullable FolderIcon mLeaveBehindFolderIcon;
+ @Nullable private FolderIcon mLeaveBehindFolderIcon;
// Only non-null when device supports having an All Apps button.
- private @Nullable IconButtonView mAllAppsButton;
- private Runnable mAllAppsTouchRunnable;
- private long mAllAppsButtonTouchDelayMs;
- private boolean mAllAppsTouchTriggered;
+ @Nullable private final TaskbarAllAppsButtonContainer mAllAppsButtonContainer;
- // Only non-null when device supports having an All Apps button, or Recent Apps.
- private @Nullable IconButtonView mTaskbarDivider;
+ // Only non-null when device supports having an All Apps button.
+ @Nullable private TaskbarDividerContainer mTaskbarDividerContainer;
/**
* Whether the divider is between Hotseat icons and Recents,
@@ -173,55 +164,14 @@
// Needed to draw folder leave-behind when opening one.
setWillNotDraw(false);
- mAllAppsButton = (IconButtonView) LayoutInflater.from(context)
- .inflate(R.layout.taskbar_all_apps_button, this, false);
- mAllAppsButton.setIconDrawable(resources.getDrawable(
- getAllAppsButton(isTransientTaskbar)));
- mAllAppsButton.setPadding(mItemPadding, mItemPadding, mItemPadding, mItemPadding);
- mAllAppsButton.setForegroundTint(
- mActivityContext.getColor(R.color.all_apps_button_color));
+ mAllAppsButtonContainer = new TaskbarAllAppsButtonContainer(context);
if (enableTaskbarPinning() || enableRecentsInTaskbar()) {
- mTaskbarDivider = (IconButtonView) LayoutInflater.from(context).inflate(
- R.layout.taskbar_divider,
- this, false);
- mTaskbarDivider.setIconDrawable(
- resources.getDrawable(R.drawable.taskbar_divider_button));
- mTaskbarDivider.setPadding(mItemPadding, mItemPadding, mItemPadding, mItemPadding);
+ mTaskbarDividerContainer = new TaskbarDividerContainer(context);
}
// TODO: Disable touch events on QSB otherwise it can crash.
mQsb = LayoutInflater.from(context).inflate(R.layout.search_container_hotseat, this, false);
-
- // Default long press (touch) delay = 400ms
- mAllAppsButtonTouchDelayMs = ViewConfiguration.getLongPressTimeout();
- }
-
- @DrawableRes
- private int getAllAppsButton(boolean isTransientTaskbar) {
- boolean shouldSelectTransientIcon =
- (isTransientTaskbar || enableTaskbarPinning())
- && !mActivityContext.isThreeButtonNav();
- if (ENABLE_ALL_APPS_SEARCH_IN_TASKBAR.get()) {
- return shouldSelectTransientIcon
- ? R.drawable.ic_transient_taskbar_all_apps_search_button
- : R.drawable.ic_taskbar_all_apps_search_button;
- } else {
- return shouldSelectTransientIcon
- ? R.drawable.ic_transient_taskbar_all_apps_button
- : R.drawable.ic_taskbar_all_apps_button;
- }
- }
-
- @DimenRes
- public int getAllAppsButtonTranslationXOffset(boolean isTransientTaskbar) {
- if (isTransientTaskbar) {
- return R.dimen.transient_taskbar_all_apps_button_translation_x_offset;
- } else {
- return ENABLE_ALL_APPS_SEARCH_IN_TASKBAR.get()
- ? R.dimen.taskbar_all_apps_search_button_translation_x_offset
- : R.dimen.taskbar_all_apps_button_translation_x_offset;
- }
}
@Override
@@ -306,27 +256,11 @@
mIconClickListener = mControllerCallbacks.getIconOnClickListener();
mIconLongClickListener = mControllerCallbacks.getIconOnLongClickListener();
- if (mAllAppsButton != null) {
- mAllAppsButton.setOnClickListener(this::onAllAppsButtonClick);
- mAllAppsButton.setOnLongClickListener(this::onAllAppsButtonLongClick);
- mAllAppsButton.setOnTouchListener(this::onAllAppsButtonTouch);
- mAllAppsButton.setHapticFeedbackEnabled(
- mControllerCallbacks.isAllAppsButtonHapticFeedbackEnabled());
- mAllAppsTouchRunnable = () -> {
- mControllerCallbacks.triggerAllAppsButtonLongClick();
- mAllAppsTouchTriggered = true;
- };
- AssistStateManager assistStateManager = AssistStateManager.INSTANCE.get(mContext);
- if (DeviceConfigWrapper.get().getCustomLpaaThresholds()
- && assistStateManager.getLPNHDurationMillis().isPresent()) {
- mAllAppsButtonTouchDelayMs = assistStateManager.getLPNHDurationMillis().get();
- }
+ if (mAllAppsButtonContainer != null) {
+ mAllAppsButtonContainer.setUpCallbacks(callbacks);
}
- if (mTaskbarDivider != null && !mActivityContext.isThreeButtonNav()) {
- mTaskbarDivider.setOnLongClickListener(
- mControllerCallbacks.getTaskbarDividerLongClickListener());
- mTaskbarDivider.setOnTouchListener(
- mControllerCallbacks.getTaskbarDividerRightClickListener());
+ if (mTaskbarDividerContainer != null && callbacks.supportsDividerLongPress()) {
+ mTaskbarDividerContainer.setUpCallbacks(callbacks);
}
}
@@ -348,11 +282,11 @@
int numViewsAnimated = 0;
mAddedDividerForRecents = false;
- if (mAllAppsButton != null) {
- removeView(mAllAppsButton);
+ if (mAllAppsButtonContainer != null) {
+ removeView(mAllAppsButtonContainer);
- if (mTaskbarDivider != null) {
- removeView(mTaskbarDivider);
+ if (mTaskbarDividerContainer != null) {
+ removeView(mTaskbarDividerContainer);
}
}
removeView(mQsb);
@@ -439,8 +373,8 @@
nextViewIndex++;
}
- if (mTaskbarDivider != null && !recentTasks.isEmpty()) {
- addView(mTaskbarDivider, nextViewIndex++);
+ if (mTaskbarDividerContainer != null && !recentTasks.isEmpty()) {
+ addView(mTaskbarDividerContainer, nextViewIndex++);
mAddedDividerForRecents = true;
}
@@ -504,12 +438,14 @@
removeAndRecycle(getChildAt(nextViewIndex));
}
- if (mAllAppsButton != null) {
- addView(mAllAppsButton, mIsRtl ? hotseatItemInfos.length : 0);
+ if (mAllAppsButtonContainer != null) {
+ addView(mAllAppsButtonContainer, mIsRtl ? hotseatItemInfos.length : 0);
// If there are no recent tasks, add divider after All Apps (unless it's the only view).
- if (!mAddedDividerForRecents && mTaskbarDivider != null && getChildCount() > 1) {
- addView(mTaskbarDivider, mIsRtl ? (getChildCount() - 1) : 1);
+ if (!mAddedDividerForRecents
+ && mTaskbarDividerContainer != null
+ && getChildCount() > 1) {
+ addView(mTaskbarDividerContainer, mIsRtl ? (getChildCount() - 1) : 1);
}
}
if (mActivityContext.getDeviceProfile().isQsbInline) {
@@ -637,7 +573,7 @@
int qsbTop = (bottom - top - deviceProfile.hotseatQsbHeight) / 2;
int qsbBottom = qsbTop + deviceProfile.hotseatQsbHeight;
child.layout(qsbStart, qsbTop, qsbEnd, qsbBottom);
- } else if (child == mTaskbarDivider) {
+ } else if (child == mTaskbarDividerContainer) {
iconEnd += mItemMarginLeftRight;
int iconStart = iconEnd - mIconTouchSize;
child.layout(iconStart, mIconLayoutBounds.top, iconEnd, mIconLayoutBounds.bottom);
@@ -727,16 +663,16 @@
* Returns the all apps button in the taskbar.
*/
@Nullable
- public View getAllAppsButtonView() {
- return mAllAppsButton;
+ public TaskbarAllAppsButtonContainer getAllAppsButtonContainer() {
+ return mAllAppsButtonContainer;
}
/**
* Returns the taskbar divider in the taskbar.
*/
@Nullable
- public View getTaskbarDividerView() {
- return mTaskbarDivider;
+ public TaskbarDividerContainer getTaskbarDividerViewContainer() {
+ return mTaskbarDividerContainer;
}
/**
@@ -832,48 +768,6 @@
}
}
}
- return mAllAppsButton;
- }
-
- private boolean onAllAppsButtonTouch(View view, MotionEvent ev) {
- switch (ev.getAction()) {
- case MotionEvent.ACTION_DOWN:
- mAllAppsTouchTriggered = false;
- MAIN_EXECUTOR.getHandler().postDelayed(
- mAllAppsTouchRunnable, mAllAppsButtonTouchDelayMs);
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- cancelAllAppsButtonTouch();
- }
- return false;
- }
-
- private void cancelAllAppsButtonTouch() {
- MAIN_EXECUTOR.getHandler().removeCallbacks(mAllAppsTouchRunnable);
- // ACTION_UP is first triggered, then click listener / long-click listener is triggered on
- // the next frame, so we need to post twice and delay the reset.
- if (mAllAppsButton != null) {
- mAllAppsButton.post(() -> {
- mAllAppsButton.post(() -> {
- mAllAppsTouchTriggered = false;
- });
- });
- }
- }
-
- private void onAllAppsButtonClick(View view) {
- if (!mAllAppsTouchTriggered) {
- mControllerCallbacks.triggerAllAppsButtonClick(view);
- }
- }
-
- // Handle long click from Switch Access and Voice Access
- private boolean onAllAppsButtonLongClick(View view) {
- if (!MAIN_EXECUTOR.getHandler().hasCallbacks(mAllAppsTouchRunnable)
- && !mAllAppsTouchTriggered) {
- mControllerCallbacks.triggerAllAppsButtonLongClick();
- }
- return true;
+ return mAllAppsButtonContainer;
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
index e6cac2f..296d379 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewCallbacks.java
@@ -51,7 +51,7 @@
}
/** Trigger All Apps button click action. */
- protected void triggerAllAppsButtonClick(View v) {
+ public void triggerAllAppsButtonClick(View v) {
InteractionJankMonitorWrapper.begin(v, Cuj.CUJ_LAUNCHER_OPEN_ALL_APPS,
/* tag= */ "TASKBAR_BUTTON");
mActivity.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_ALLAPPS_BUTTON_TAP);
@@ -59,7 +59,7 @@
}
/** Trigger All Apps button long click action. */
- protected void triggerAllAppsButtonLongClick() {
+ public void triggerAllAppsButtonLongClick() {
mActivity.getStatsLogManager().logger().log(LAUNCHER_TASKBAR_ALLAPPS_BUTTON_LONG_PRESS);
}
@@ -74,6 +74,11 @@
};
}
+ /** Check to see if we support long press on taskbar divider */
+ public boolean supportsDividerLongPress() {
+ return !mActivity.isThreeButtonNav();
+ }
+
public View.OnTouchListener getTaskbarDividerRightClickListener() {
return (v, event) -> {
if (event.isFromSource(InputDevice.SOURCE_MOUSE)
diff --git a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
index 27c1d9c..aa3e6bf 100644
--- a/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/TaskbarViewController.java
@@ -72,7 +72,6 @@
import com.android.launcher3.util.MultiPropertyFactory;
import com.android.launcher3.util.MultiTranslateDelegate;
import com.android.launcher3.util.MultiValueAlpha;
-import com.android.launcher3.views.IconButtonView;
import com.android.quickstep.util.GroupTask;
import com.android.systemui.shared.recents.model.Task;
@@ -299,7 +298,7 @@
@Nullable
public View getAllAppsButtonView() {
- return mTaskbarView.getAllAppsButtonView();
+ return mTaskbarView.getAllAppsButtonContainer();
}
public AnimatedFloat getTaskbarIconScaleForStash() {
@@ -366,9 +365,9 @@
View[] iconViews = mTaskbarView.getIconViews();
float scale = mTaskbarIconTranslationXForPinning.value;
float transientTaskbarAllAppsOffset = mActivity.getResources().getDimension(
- mTaskbarView.getAllAppsButtonTranslationXOffset(true));
+ mTaskbarView.getAllAppsButtonContainer().getAllAppsButtonTranslationXOffset(true));
float persistentTaskbarAllAppsOffset = mActivity.getResources().getDimension(
- mTaskbarView.getAllAppsButtonTranslationXOffset(false));
+ mTaskbarView.getAllAppsButtonContainer().getAllAppsButtonTranslationXOffset(false));
float allAppIconTranslateRange = mapRange(scale, transientTaskbarAllAppsOffset,
persistentTaskbarAllAppsOffset);
@@ -383,7 +382,7 @@
}
if (mActivity.isThreeButtonNav()) {
- ((IconButtonView) mTaskbarView.getAllAppsButtonView())
+ mTaskbarView.getAllAppsButtonContainer()
.setTranslationXForTaskbarAllAppsIcon(allAppIconTranslateRange);
return;
}
@@ -408,8 +407,8 @@
-finalMarginScale * (iconIndex - halfIconCount));
}
- if (iconView.equals(mTaskbarView.getAllAppsButtonView())) {
- ((IconButtonView) iconView).setTranslationXForTaskbarAllAppsIcon(
+ if (iconView.equals(mTaskbarView.getAllAppsButtonContainer())) {
+ mTaskbarView.getAllAppsButtonContainer().setTranslationXForTaskbarAllAppsIcon(
allAppIconTranslateRange);
}
}
@@ -537,7 +536,7 @@
}
public View getTaskbarDividerView() {
- return mTaskbarView.getTaskbarDividerView();
+ return mTaskbarView.getTaskbarDividerViewContainer();
}
/**
@@ -753,8 +752,8 @@
int firstRecentTaskIndex = -1;
for (int i = 0; i < mTaskbarView.getChildCount(); i++) {
View child = mTaskbarView.getChildAt(i);
- boolean isAllAppsButton = child == mTaskbarView.getAllAppsButtonView();
- boolean isTaskbarDividerView = child == mTaskbarView.getTaskbarDividerView();
+ boolean isAllAppsButton = child == mTaskbarView.getAllAppsButtonContainer();
+ boolean isTaskbarDividerView = child == mTaskbarView.getTaskbarDividerViewContainer();
boolean isRecentTask = child.getTag() instanceof GroupTask;
// TODO(b/343522351): show recents on the home screen.
final boolean isRecentsInHotseat = false;
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 c458936..71867fe 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarView.java
@@ -1473,8 +1473,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 5c1a546..2502e4a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleBarViewController.java
@@ -80,12 +80,14 @@
// These are exposed to {@link BubbleStashController} to animate for stashing/un-stashing
private final MultiValueAlpha mBubbleBarAlpha;
- private final AnimatedFloat mBubbleBarScale = new AnimatedFloat(this::updateScale);
+ private final AnimatedFloat mBubbleBarScaleY = new AnimatedFloat(this::updateScaleY);
private final AnimatedFloat mBubbleBarTranslationY = new AnimatedFloat(
this::updateTranslationY);
// Modified when swipe up is happening on the bubble bar or task bar.
private float mBubbleBarSwipeUpTranslationY;
+ // Modified when bubble bar is springing back into the stash handle.
+ private float mBubbleBarStashTranslationY;
// Whether the bar is hidden for a sysui state.
private boolean mHiddenForSysui;
@@ -125,7 +127,7 @@
onBubbleBarConfigurationChanged(/* animate= */ false);
mActivity.addOnDeviceProfileChangeListener(
dp -> onBubbleBarConfigurationChanged(/* animate= */ true));
- mBubbleBarScale.updateValue(1f);
+ mBubbleBarScaleY.updateValue(1f);
mBubbleClickListener = v -> onBubbleClicked((BubbleView) v);
mBubbleBarClickListener = v -> expandBubbleBar();
mBubbleDragController.setupBubbleBarView(mBarView);
@@ -255,8 +257,8 @@
return mBubbleBarAlpha;
}
- public AnimatedFloat getBubbleBarScale() {
- return mBubbleBarScale;
+ public AnimatedFloat getBubbleBarScaleY() {
+ return mBubbleBarScaleY;
}
public AnimatedFloat getBubbleBarTranslationY() {
@@ -268,6 +270,27 @@
}
/**
+ * @see BubbleBarView#getRelativePivotX()
+ */
+ public float getBubbleBarRelativePivotX() {
+ return mBarView.getRelativePivotX();
+ }
+
+ /**
+ * @see BubbleBarView#getRelativePivotY()
+ */
+ public float getBubbleBarRelativePivotY() {
+ return mBarView.getRelativePivotY();
+ }
+
+ /**
+ * @see BubbleBarView#setRelativePivot(float, float)
+ */
+ public void setBubbleBarRelativePivot(float x, float y) {
+ mBarView.setRelativePivot(x, y);
+ }
+
+ /**
* Whether the bubble bar is visible or not.
*/
public boolean isBubbleBarVisible() {
@@ -474,17 +497,20 @@
updateTranslationY();
}
- private void updateTranslationY() {
- mBarView.setTranslationY(mBubbleBarTranslationY.value
- + mBubbleBarSwipeUpTranslationY);
+ /**
+ * Sets the translation of the bubble bar during the stash animation.
+ */
+ public void setTranslationYForStash(float transY) {
+ mBubbleBarStashTranslationY = transY;
+ updateTranslationY();
}
- /**
- * Applies scale properties for the entire bubble bar.
- */
- private void updateScale() {
- float scale = mBubbleBarScale.value;
- mBarView.setScaleX(scale);
+ private void updateTranslationY() {
+ mBarView.setTranslationY(mBubbleBarTranslationY.value + mBubbleBarSwipeUpTranslationY
+ + mBubbleBarStashTranslationY);
+ }
+
+ private void updateScaleY(float scale) {
mBarView.setScaleY(scale);
}
@@ -793,6 +819,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 6bfe8f4..16af248 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/BubbleStashedHandleViewController.java
@@ -21,6 +21,7 @@
import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.ValueAnimator;
+import android.annotation.Nullable;
import android.content.res.Resources;
import android.graphics.Outline;
import android.graphics.Rect;
@@ -28,6 +29,7 @@
import android.view.View;
import android.view.ViewOutlineProvider;
+import com.android.launcher3.DeviceProfile;
import com.android.launcher3.R;
import com.android.launcher3.anim.RevealOutlineAnimation;
import com.android.launcher3.anim.RoundedRectRevealOutlineProvider;
@@ -37,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.
@@ -49,23 +51,29 @@
private final TaskbarActivityContext mActivity;
private final StashedHandleView mStashedHandleView;
private final MultiValueAlpha mStashedHandleAlpha;
+ private float mTranslationForSwipeY;
+ private float mTranslationForStashY;
// Initialized in init.
private BubbleBarViewController mBarViewController;
private BubbleStashController mBubbleStashController;
private RegionSamplingHelper mRegionSamplingHelper;
- private int mBarSize;
- private int mStashedTaskbarHeight;
+ // Height of the area for the stash handle. Handle will be drawn in the center of this.
+ // This is also the area where touch is handled on the handle.
+ private int mStashedBubbleBarHeight;
private int mStashedHandleWidth;
private int mStashedHandleHeight;
- // The bounds we want to clip to in the settled state when showing the stashed handle.
+ // The bounds of the stashed handle in settled state.
private final Rect mStashedHandleBounds = new Rect();
+ private float mStashedHandleRadius;
// When the reveal animation is cancelled, we can assume it's about to create a new animation,
// which should start off at the same point the cancelled one left off.
private float mStartProgressForNextRevealAnim;
- private boolean mWasLastRevealAnimReversed;
+ // Use a nullable boolean to handle initial case where the last animation direction is not known
+ @Nullable
+ private Boolean mWasLastRevealAnimReversed = null;
// XXX: if there are more of these maybe do state flags instead
private boolean mHiddenForSysui;
@@ -77,6 +85,7 @@
mActivity = activity;
mStashedHandleView = stashedHandleView;
mStashedHandleAlpha = new MultiValueAlpha(mStashedHandleView, 1);
+ mStashedHandleAlpha.setUpdateVisibility(true);
}
/** Initialize controller. */
@@ -84,26 +93,31 @@
mBarViewController = bubbleControllers.bubbleBarViewController;
mBubbleStashController = bubbleControllers.bubbleStashController;
+ DeviceProfile deviceProfile = mActivity.getDeviceProfile();
Resources resources = mActivity.getResources();
mStashedHandleHeight = resources.getDimensionPixelSize(
R.dimen.bubblebar_stashed_handle_height);
mStashedHandleWidth = resources.getDimensionPixelSize(
R.dimen.bubblebar_stashed_handle_width);
- mBarSize = resources.getDimensionPixelSize(R.dimen.bubblebar_size);
- final int bottomMargin = resources.getDimensionPixelSize(
- R.dimen.transient_taskbar_bottom_margin);
- mStashedHandleView.getLayoutParams().height = mBarSize + bottomMargin;
+ int barSize = resources.getDimensionPixelSize(R.dimen.bubblebar_size);
+ // Use the max translation for bubble bar whether it is on the home screen or in app.
+ // Use values directly from device profile to avoid referencing other bubble controllers
+ // during init flow.
+ int maxTy = Math.max(deviceProfile.hotseatBarBottomSpacePx,
+ deviceProfile.taskbarBottomMargin);
+ // Adjust handle view size to accommodate the handle morphing into the bubble bar
+ mStashedHandleView.getLayoutParams().height = barSize + maxTy;
mStashedHandleAlpha.get(0).setValue(0);
- mStashedTaskbarHeight = resources.getDimensionPixelSize(
+ mStashedBubbleBarHeight = resources.getDimensionPixelSize(
R.dimen.bubblebar_stashed_size);
mStashedHandleView.setOutlineProvider(new ViewOutlineProvider() {
@Override
public void getOutline(View view, Outline outline) {
- float stashedHandleRadius = view.getHeight() / 2f;
- outline.setRoundRect(mStashedHandleBounds, stashedHandleRadius);
+ mStashedHandleRadius = view.getHeight() / 2f;
+ outline.setRoundRect(mStashedHandleBounds, mStashedHandleRadius);
}
});
@@ -132,28 +146,25 @@
private void updateBounds(BubbleBarLocation bubbleBarLocation) {
// As more bubbles get added, the icon bounds become larger. To ensure a consistent
// handle bar position, we pin it to the edge of the screen.
- final int stashedCenterY = mStashedHandleView.getHeight() - mStashedTaskbarHeight / 2;
+ final int stashedCenterY = mStashedHandleView.getHeight() - mStashedBubbleBarHeight / 2;
+ final int stashedCenterX;
if (bubbleBarLocation.isOnLeft(mStashedHandleView.isLayoutRtl())) {
final int left = mBarViewController.getHorizontalMargin();
- mStashedHandleBounds.set(
- left,
- stashedCenterY - mStashedHandleHeight / 2,
- left + mStashedHandleWidth,
- stashedCenterY + mStashedHandleHeight / 2);
- mStashedHandleView.setPivotX(0);
+ stashedCenterX = left + mStashedHandleWidth / 2;
} else {
final int right =
- mActivity.getDeviceProfile().widthPx - mBarViewController.getHorizontalMargin();
- mStashedHandleBounds.set(
- right - mStashedHandleWidth,
- stashedCenterY - mStashedHandleHeight / 2,
- right,
- stashedCenterY + mStashedHandleHeight / 2);
- mStashedHandleView.setPivotX(mStashedHandleView.getWidth());
+ mStashedHandleView.getRight() - mBarViewController.getHorizontalMargin();
+ stashedCenterX = right - mStashedHandleWidth / 2;
}
-
+ mStashedHandleBounds.set(
+ stashedCenterX - mStashedHandleWidth / 2,
+ stashedCenterY - mStashedHandleHeight / 2,
+ stashedCenterX + mStashedHandleWidth / 2,
+ stashedCenterY + mStashedHandleHeight / 2
+ );
mStashedHandleView.updateSampledRegion(mStashedHandleBounds);
- mStashedHandleView.setPivotY(mStashedHandleView.getHeight() - mStashedTaskbarHeight / 2f);
+ mStashedHandleView.setPivotX(stashedCenterX);
+ mStashedHandleView.setPivotY(stashedCenterY);
}
public void onDestroy() {
@@ -169,13 +180,6 @@
}
/**
- * Returns the height when the bubble bar is unstashed (so the height of the bubble bar).
- */
- public int getUnstashedHeight() {
- return mBarSize;
- }
-
- /**
* Called when system ui state changes. Bubbles don't show when the device is locked.
*/
public void setHiddenForSysui(boolean hidden) {
@@ -242,7 +246,20 @@
* Sets the translation of the stashed handle during the swipe up gesture.
*/
public void setTranslationYForSwipe(float transY) {
- mStashedHandleView.setTranslationY(transY);
+ mTranslationForSwipeY = transY;
+ updateTranslationY();
+ }
+
+ /**
+ * Sets the translation of the stashed handle during the spring on stash animation.
+ */
+ public void setTranslationYForStash(float transY) {
+ mTranslationForStashY = transY;
+ updateTranslationY();
+ }
+
+ private void updateTranslationY() {
+ mStashedHandleView.setTranslationY(mTranslationForSwipeY + mTranslationForStashY);
}
/** Returns the translation of the stashed handle. */
@@ -263,18 +280,17 @@
* the size of where the bubble bar icons will be.
*/
public Animator createRevealAnimToIsStashed(boolean isStashed) {
- Rect bubbleBarBounds = new Rect(mBarViewController.getBubbleBarBounds());
+ Rect bubbleBarBounds = getLocalBubbleBarBounds();
- // Account for the full visual height of the bubble bar
- int heightDiff = (mBarSize - bubbleBarBounds.height()) / 2;
- bubbleBarBounds.top -= heightDiff;
- bubbleBarBounds.bottom += heightDiff;
- float stashedHandleRadius = mStashedHandleView.getHeight() / 2f;
+ float bubbleBarRadius = bubbleBarBounds.height() / 2f;
final RevealOutlineAnimation handleRevealProvider = new RoundedRectRevealOutlineProvider(
- stashedHandleRadius, stashedHandleRadius, bubbleBarBounds, mStashedHandleBounds);
+ bubbleBarRadius, mStashedHandleRadius, bubbleBarBounds, mStashedHandleBounds);
boolean isReversed = !isStashed;
- boolean changingDirection = mWasLastRevealAnimReversed != isReversed;
+ // We are only changing direction when mWasLastRevealAnimReversed is set at least once
+ boolean changingDirection =
+ mWasLastRevealAnimReversed != null && mWasLastRevealAnimReversed != isReversed;
+
mWasLastRevealAnimReversed = isReversed;
if (changingDirection) {
mStartProgressForNextRevealAnim = 1f - mStartProgressForNextRevealAnim;
@@ -291,6 +307,21 @@
return revealAnim;
}
+ /**
+ * Get bounds for the bubble bar in the space of the handle view
+ */
+ private Rect getLocalBubbleBarBounds() {
+ // Position the bubble bar bounds to the space of handle view
+ Rect bubbleBarBounds = new Rect(mBarViewController.getBubbleBarBounds());
+ // Start by moving bubble bar bounds to the bottom of handle view
+ int height = bubbleBarBounds.height();
+ bubbleBarBounds.bottom = mStashedHandleView.getHeight();
+ bubbleBarBounds.top = bubbleBarBounds.bottom - height;
+ // Then apply translation that is applied to the bubble bar
+ bubbleBarBounds.offset(0, (int) mBubbleStashController.getBubbleBarTranslationY());
+ return bubbleBarBounds;
+ }
+
/** Checks that the stash handle is visible and that the motion event is within bounds. */
public boolean isEventOverHandle(MotionEvent ev) {
if (mStashedHandleView.getVisibility() != VISIBLE) {
@@ -299,7 +330,7 @@
// the bounds of the handle only include the visible part, so we check that the Y coordinate
// is anywhere within the stashed height of bubble bar (same as taskbar stashed height).
- final int top = mActivity.getDeviceProfile().heightPx - mStashedTaskbarHeight;
+ final int top = mActivity.getDeviceProfile().heightPx - mStashedBubbleBarHeight;
final float x = ev.getRawX();
return ev.getRawY() >= top && x >= mStashedHandleBounds.left
&& x <= mStashedHandleBounds.right;
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/taskbar/bubbles/stashing/BubbleStashController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleStashController.kt
index 48eb7de..b2a88ac 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleStashController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/BubbleStashController.kt
@@ -179,10 +179,10 @@
/** How long to stash/unstash. */
const val BAR_STASH_DURATION = InsetsController.ANIMATION_DURATION_RESIZE.toLong()
+ const val BAR_STASH_ALPHA_DURATION = 50L
+ const val BAR_STASH_ALPHA_DELAY = 33L
+
/** How long to translate Y coordinate of the BubbleBar. */
const val BAR_TRANSLATION_DURATION = 300L
-
- /** The scale bubble bar animates to when being stashed. */
- const val STASHED_BAR_SCALE = 0.5f
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashController.kt
index 1b65019..3ebd97e 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashController.kt
@@ -116,7 +116,7 @@
bubbleBarTranslationYAnimator = bubbleBarViewController.bubbleBarTranslationY
// bubble bar has only alpha property, getting it at index 0
bubbleBarAlphaAnimator = bubbleBarViewController.bubbleBarAlpha.get(/* index= */ 0)
- bubbleBarScaleAnimator = bubbleBarViewController.bubbleBarScale
+ bubbleBarScaleAnimator = bubbleBarViewController.bubbleBarScaleY
}
private fun animateAfterUnlock() {
diff --git a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
index 1a4b982..b8fd1cb 100644
--- a/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashController.kt
@@ -17,30 +17,36 @@
package com.android.launcher3.taskbar.bubbles.stashing
import android.animation.Animator
-import android.animation.AnimatorListenerAdapter
import android.animation.AnimatorSet
-import android.content.res.Resources
+import android.content.Context
import android.view.MotionEvent
import android.view.View
import androidx.annotation.VisibleForTesting
+import androidx.core.animation.doOnEnd
+import androidx.core.animation.doOnStart
+import androidx.dynamicanimation.animation.SpringForce
+import com.android.app.animation.Interpolators.EMPHASIZED
+import com.android.app.animation.Interpolators.LINEAR
import com.android.launcher3.R
import com.android.launcher3.anim.AnimatedFloat
-import com.android.launcher3.taskbar.StashedHandleViewController
+import com.android.launcher3.anim.SpringAnimationBuilder
import com.android.launcher3.taskbar.TaskbarInsetsController
import com.android.launcher3.taskbar.bubbles.BubbleBarViewController
import com.android.launcher3.taskbar.bubbles.BubbleStashedHandleViewController
+import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController.Companion.BAR_STASH_ALPHA_DELAY
+import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController.Companion.BAR_STASH_ALPHA_DURATION
import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController.Companion.BAR_STASH_DURATION
import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController.Companion.BAR_TRANSLATION_DURATION
-import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController.Companion.STASHED_BAR_SCALE
import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController.ControllersAfterInitAction
import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController.TaskbarHotseatDimensionsProvider
import com.android.launcher3.util.MultiPropertyFactory
import com.android.wm.shell.common.bubbles.BubbleBarLocation
import com.android.wm.shell.shared.animation.PhysicsAnimator
+import kotlin.math.max
class TransientBubbleStashController(
private val taskbarHotseatDimensionsProvider: TaskbarHotseatDimensionsProvider,
- resources: Resources
+ private val context: Context
) : BubbleStashController {
private lateinit var bubbleBarViewController: BubbleBarViewController
@@ -50,14 +56,20 @@
// stash view properties
private var bubbleStashedHandleViewController: BubbleStashedHandleViewController? = null
private var stashHandleViewAlpha: MultiPropertyFactory<View>.MultiProperty? = null
+ private var translationYDuringStash = AnimatedFloat { transY ->
+ bubbleStashedHandleViewController?.setTranslationYForStash(transY)
+ bubbleBarViewController.setTranslationYForStash(transY)
+ }
+ private val stashHandleStashVelocity =
+ context.resources.getDimension(R.dimen.bubblebar_stashed_handle_spring_velocity_dp_per_s)
private var stashedHeight: Int = 0
// bubble bar properties
private lateinit var bubbleBarAlpha: MultiPropertyFactory<View>.MultiProperty
private lateinit var bubbleBarTranslationYAnimator: AnimatedFloat
private lateinit var bubbleBarScale: AnimatedFloat
- private val mHandleCenterFromScreenBottom =
- resources.getDimensionPixelSize(R.dimen.bubblebar_stashed_size) / 2f
+ private val handleCenterFromScreenBottom =
+ context.resources.getDimensionPixelSize(R.dimen.bubblebar_stashed_size) / 2f
private var animator: AnimatorSet? = null
@@ -136,12 +148,9 @@
bubbleBarTranslationYAnimator = bubbleBarViewController.bubbleBarTranslationY
// bubble bar has only alpha property, getting it at index 0
bubbleBarAlpha = bubbleBarViewController.bubbleBarAlpha.get(/* index= */ 0)
- bubbleBarScale = bubbleBarViewController.bubbleBarScale
+ bubbleBarScale = bubbleBarViewController.bubbleBarScaleY
stashedHeight = bubbleStashedHandleViewController?.stashedHeight ?: 0
- stashHandleViewAlpha =
- bubbleStashedHandleViewController
- ?.stashedHandleAlpha
- ?.get(StashedHandleViewController.ALPHA_INDEX_STASHED)
+ stashHandleViewAlpha = bubbleStashedHandleViewController?.stashedHandleAlpha?.get(0)
}
private fun animateAfterUnlock() {
@@ -179,7 +188,7 @@
stashHandleViewAlpha?.value = 1f
this.bubbleBarTranslationYAnimator.updateValue(getStashTranslation())
bubbleBarAlpha.setValue(0f)
- bubbleBarScale.updateValue(STASHED_BAR_SCALE)
+ bubbleBarScale.updateValue(getStashScale())
isStashed = true
onIsStashedChanged()
}
@@ -223,11 +232,11 @@
// the difference between the centers of the handle and the bubble bar is the difference
// between their distance from the bottom of the screen.
val barCenter: Float = bubbleBarViewController.bubbleBarCollapsedHeight / 2f
- return mHandleCenterFromScreenBottom - barCenter
+ return handleCenterFromScreenBottom - barCenter
}
override fun getStashedHandleTranslationForNewBubbleAnimation(): Float {
- return -mHandleCenterFromScreenBottom
+ return -handleCenterFromScreenBottom
}
override fun getStashedHandlePhysicsAnimator(): PhysicsAnimator<View>? {
@@ -245,7 +254,13 @@
override fun getHandleTranslationY(): Float? = bubbleStashedHandleViewController?.translationY
private fun getStashTranslation(): Float {
- return (bubbleBarViewController.bubbleBarCollapsedHeight - stashedHeight) / 2f
+ return bubbleBarTranslationY / 2f
+ }
+
+ @VisibleForTesting
+ fun getStashScale(): Float {
+ val handleHeight = bubbleStashedHandleViewController?.stashedHeight ?: 0
+ return handleHeight / bubbleBarViewController.bubbleBarCollapsedHeight
}
/**
@@ -258,61 +273,84 @@
@Suppress("SameParameterValue")
private fun createStashAnimator(isStashed: Boolean, duration: Long): AnimatorSet {
val animatorSet = AnimatorSet()
- val fullLengthAnimatorSet = AnimatorSet()
- // Not exactly half and may overlap. See [first|second]HalfDurationScale below.
- val firstHalfAnimatorSet = AnimatorSet()
- val secondHalfAnimatorSet = AnimatorSet()
- val firstHalfDurationScale: Float
- val secondHalfDurationScale: Float
- val stashHandleAlphaValue: Float
- if (isStashed) {
- firstHalfDurationScale = 0.75f
- secondHalfDurationScale = 0.5f
- stashHandleAlphaValue = 1f
- fullLengthAnimatorSet.play(
- bubbleBarTranslationYAnimator.animateToValue(getStashTranslation())
- )
- firstHalfAnimatorSet.playTogether(
- bubbleBarAlpha.animateToValue(0f),
- bubbleBarScale.animateToValue(STASHED_BAR_SCALE)
- )
- } else {
- firstHalfDurationScale = 0.5f
- secondHalfDurationScale = 0.75f
- stashHandleAlphaValue = 0f
- fullLengthAnimatorSet.playTogether(
- bubbleBarScale.animateToValue(1f),
- bubbleBarTranslationYAnimator.animateToValue(bubbleBarTranslationY)
- )
- secondHalfAnimatorSet.playTogether(bubbleBarAlpha.animateToValue(1f))
- }
- stashHandleViewAlpha?.let {
- secondHalfAnimatorSet.playTogether(it.animateToValue(stashHandleAlphaValue))
- }
- bubbleStashedHandleViewController?.createRevealAnimToIsStashed(isStashed)?.let {
- fullLengthAnimatorSet.play(it)
- }
- fullLengthAnimatorSet.setDuration(duration)
- firstHalfAnimatorSet.setDuration((duration * firstHalfDurationScale).toLong())
- secondHalfAnimatorSet.setDuration((duration * secondHalfDurationScale).toLong())
- secondHalfAnimatorSet.startDelay = (duration * (1 - secondHalfDurationScale)).toLong()
- animatorSet.playTogether(fullLengthAnimatorSet, firstHalfAnimatorSet, secondHalfAnimatorSet)
- animatorSet.addListener(
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- animator = null
- controllersAfterInitAction.runAfterInit {
- if (isStashed) {
- bubbleBarViewController.isExpanded = false
- }
- taskbarInsetsController.onTaskbarOrBubblebarWindowHeightOrInsetsChanged()
- }
- }
+
+ val alphaDuration = if (isStashed) duration else BAR_STASH_ALPHA_DURATION
+ val alphaDelay = if (isStashed) BAR_STASH_ALPHA_DELAY else 0L
+ animatorSet.play(
+ createStashAlphaAnimator(isStashed).apply {
+ this.duration = max(0L, alphaDuration - alphaDelay)
+ this.startDelay = alphaDelay
+ this.interpolator = LINEAR
}
)
+
+ animatorSet.play(
+ createSpringOnStashAnimator(isStashed).apply {
+ this.duration = duration
+ this.interpolator = LINEAR
+ }
+ )
+
+ animatorSet.play(
+ bubbleStashedHandleViewController?.createRevealAnimToIsStashed(isStashed)?.apply {
+ this.duration = duration
+ this.interpolator = EMPHASIZED
+ }
+ )
+
+ val scaleTarget = if (isStashed) getStashScale() else 1f
+ animatorSet.play(
+ bubbleBarScale.animateToValue(scaleTarget).apply {
+ this.duration = duration
+ this.interpolator = EMPHASIZED
+ this.setBubbleBarPivotDuringAnim(0.5f, 1f)
+ }
+ )
+
+ val translationYTarget = if (isStashed) getStashTranslation() else bubbleBarTranslationY
+ animatorSet.play(
+ bubbleBarTranslationYAnimator.animateToValue(translationYTarget).apply {
+ this.duration = duration
+ this.interpolator = EMPHASIZED
+ }
+ )
+
+ animatorSet.doOnEnd {
+ animator = null
+ controllersAfterInitAction.runAfterInit {
+ if (isStashed) {
+ bubbleBarViewController.isExpanded = false
+ }
+ taskbarInsetsController.onTaskbarOrBubblebarWindowHeightOrInsetsChanged()
+ }
+ }
return animatorSet
}
+ private fun createStashAlphaAnimator(isStashed: Boolean): AnimatorSet {
+ val stashHandleAlphaTarget = if (isStashed) 1f else 0f
+ val barAlphaTarget = if (isStashed) 0f else 1f
+ return AnimatorSet().apply {
+ play(bubbleBarAlpha.animateToValue(barAlphaTarget))
+ play(stashHandleViewAlpha?.animateToValue(stashHandleAlphaTarget))
+ }
+ }
+
+ private fun createSpringOnStashAnimator(isStashed: Boolean): Animator {
+ if (!isStashed) {
+ // Animate the stash translation back to 0
+ return translationYDuringStash.animateToValue(0f)
+ }
+ // Apply a spring to the handle
+ return SpringAnimationBuilder(context)
+ .setStartValue(translationYDuringStash.value)
+ .setEndValue(0f)
+ .setDampingRatio(SpringForce.DAMPING_RATIO_MEDIUM_BOUNCY)
+ .setStiffness(SpringForce.STIFFNESS_LOW)
+ .setStartVelocity(stashHandleStashVelocity)
+ .build(translationYDuringStash, AnimatedFloat.VALUE)
+ }
+
private fun onIsStashedChanged() {
controllersAfterInitAction.runAfterInit {
taskbarInsetsController.onTaskbarOrBubblebarWindowHeightOrInsetsChanged()
@@ -363,13 +401,23 @@
}
private fun Animator.updateTouchRegionOnAnimationEnd(): Animator {
- this.addListener(
- object : AnimatorListenerAdapter() {
- override fun onAnimationEnd(animation: Animator) {
- onIsStashedChanged()
- }
+ doOnEnd { onIsStashedChanged() }
+ return this
+ }
+
+ private fun Animator.setBubbleBarPivotDuringAnim(pivotX: Float, pivotY: Float): Animator {
+ var initialPivotX = Float.NaN
+ var initialPivotY = Float.NaN
+ doOnStart {
+ initialPivotX = bubbleBarViewController.bubbleBarRelativePivotX
+ initialPivotY = bubbleBarViewController.bubbleBarRelativePivotY
+ bubbleBarViewController.setBubbleBarRelativePivot(pivotX, pivotY)
+ }
+ doOnEnd {
+ if (!initialPivotX.isNaN() && !initialPivotY.isNaN()) {
+ bubbleBarViewController.setBubbleBarRelativePivot(initialPivotX, initialPivotY)
}
- )
+ }
return this
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarAllAppsButtonContainer.kt b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarAllAppsButtonContainer.kt
index 7d2d36d..726800c 100644
--- a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarAllAppsButtonContainer.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarAllAppsButtonContainer.kt
@@ -18,18 +18,27 @@
import android.annotation.SuppressLint
import android.content.Context
+import android.content.res.ColorStateList
+import android.graphics.Color.TRANSPARENT
import android.util.AttributeSet
import android.view.LayoutInflater
-import android.widget.LinearLayout
+import android.view.MotionEvent
+import android.view.View
+import android.view.ViewConfiguration
import androidx.annotation.DimenRes
import androidx.annotation.DrawableRes
import androidx.core.view.setPadding
import com.android.launcher3.R
import com.android.launcher3.Utilities.dpToPx
-import com.android.launcher3.config.FeatureFlags
+import com.android.launcher3.config.FeatureFlags.ENABLE_ALL_APPS_SEARCH_IN_TASKBAR
+import com.android.launcher3.config.FeatureFlags.enableTaskbarPinning
import com.android.launcher3.taskbar.TaskbarActivityContext
+import com.android.launcher3.taskbar.TaskbarViewCallbacks
+import com.android.launcher3.util.Executors.MAIN_EXECUTOR
import com.android.launcher3.views.ActivityContext
import com.android.launcher3.views.IconButtonView
+import com.android.quickstep.DeviceConfigWrapper
+import com.android.quickstep.util.AssistStateManager
/** Taskbar all apps button container for customizable taskbar. */
class TaskbarAllAppsButtonContainer
@@ -38,19 +47,21 @@
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
-) : LinearLayout(context, attrs), TaskbarContainer {
+) : IconButtonView(context, attrs), TaskbarContainer {
- private val allAppsButton: IconButtonView =
- LayoutInflater.from(context).inflate(R.layout.taskbar_all_apps_button, this, false)
- as IconButtonView
private val activityContext: TaskbarActivityContext = ActivityContext.lookupContext(context)
+ private var allAppsTouchTriggered = false
+ private var allAppsTouchRunnable: Runnable? = null
+ private var allAppsButtonTouchDelayMs: Long = ViewConfiguration.getLongPressTimeout().toLong()
+ private lateinit var taskbarViewCallbacks: TaskbarViewCallbacks
override val spaceNeeded: Int
get() {
- return dpToPx(activityContext.taskbarSpecsEvaluator!!.taskbarIconSize.size.toFloat())
+ return dpToPx(activityContext.taskbarSpecsEvaluator.taskbarIconSize.size.toFloat())
}
init {
+ LayoutInflater.from(context).inflate(R.layout.taskbar_all_apps_button, null, false)
setUpIcon()
}
@@ -58,24 +69,39 @@
private fun setUpIcon() {
val drawable =
resources.getDrawable(
- getAllAppsButton(activityContext.taskbarFeatureEvaluator!!.isTransient)
+ getAllAppsButton(activityContext.taskbarFeatureEvaluator.isTransient)
)
- val padding = activityContext.taskbarSpecsEvaluator!!.taskbarIconPadding
+ backgroundTintList = ColorStateList.valueOf(TRANSPARENT)
+ setIconDrawable(drawable)
+ setPadding(dpToPx(activityContext.taskbarSpecsEvaluator.taskbarIconPadding.toFloat()))
+ setForegroundTint(activityContext.getColor(R.color.all_apps_button_color))
+ }
- allAppsButton.setIconDrawable(drawable)
- allAppsButton.setPadding(padding)
- allAppsButton.setForegroundTint(activityContext.getColor(R.color.all_apps_button_color))
-
- // TODO(b/356465292) : add click listeners in future cl
- addView(allAppsButton)
+ @SuppressLint("ClickableViewAccessibility")
+ fun setUpCallbacks(callbacks: TaskbarViewCallbacks) {
+ taskbarViewCallbacks = callbacks
+ setOnClickListener(this::onAllAppsButtonClick)
+ setOnLongClickListener(this::onAllAppsButtonLongClick)
+ setOnTouchListener(this::onAllAppsButtonTouch)
+ isHapticFeedbackEnabled = taskbarViewCallbacks.isAllAppsButtonHapticFeedbackEnabled()
+ allAppsTouchRunnable = Runnable {
+ taskbarViewCallbacks.triggerAllAppsButtonLongClick()
+ allAppsTouchTriggered = true
+ }
+ val assistStateManager = AssistStateManager.INSTANCE[mContext]
+ if (
+ DeviceConfigWrapper.get().customLpaaThresholds &&
+ assistStateManager.lpnhDurationMillis.isPresent
+ ) {
+ allAppsButtonTouchDelayMs = assistStateManager.lpnhDurationMillis.get()
+ }
}
@DrawableRes
private fun getAllAppsButton(isTransientTaskbar: Boolean): Int {
val shouldSelectTransientIcon =
- isTransientTaskbar ||
- (FeatureFlags.enableTaskbarPinning() && !activityContext.isThreeButtonNav)
- return if (FeatureFlags.ENABLE_ALL_APPS_SEARCH_IN_TASKBAR.get()) {
+ isTransientTaskbar || (enableTaskbarPinning() && !activityContext.isThreeButtonNav)
+ return if (ENABLE_ALL_APPS_SEARCH_IN_TASKBAR.get()) {
if (shouldSelectTransientIcon) R.drawable.ic_transient_taskbar_all_apps_search_button
else R.drawable.ic_taskbar_all_apps_search_button
} else {
@@ -88,10 +114,43 @@
fun getAllAppsButtonTranslationXOffset(isTransientTaskbar: Boolean): Int {
return if (isTransientTaskbar) {
R.dimen.transient_taskbar_all_apps_button_translation_x_offset
- } else if (FeatureFlags.ENABLE_ALL_APPS_SEARCH_IN_TASKBAR.get()) {
+ } else if (ENABLE_ALL_APPS_SEARCH_IN_TASKBAR.get()) {
R.dimen.taskbar_all_apps_search_button_translation_x_offset
} else {
R.dimen.taskbar_all_apps_button_translation_x_offset
}
}
+
+ private fun onAllAppsButtonTouch(view: View, ev: MotionEvent): Boolean {
+ when (ev.action) {
+ MotionEvent.ACTION_DOWN -> {
+ allAppsTouchTriggered = false
+ MAIN_EXECUTOR.handler.postDelayed(allAppsTouchRunnable!!, allAppsButtonTouchDelayMs)
+ }
+ MotionEvent.ACTION_UP,
+ MotionEvent.ACTION_CANCEL -> cancelAllAppsButtonTouch()
+ }
+ return false
+ }
+
+ private fun cancelAllAppsButtonTouch() {
+ MAIN_EXECUTOR.handler.removeCallbacks(allAppsTouchRunnable!!)
+ // ACTION_UP is first triggered, then click listener / long-click listener is triggered on
+ // the next frame, so we need to post twice and delay the reset.
+ this.post { this.post { allAppsTouchTriggered = false } }
+ }
+
+ private fun onAllAppsButtonClick(view: View) {
+ if (!allAppsTouchTriggered) {
+ taskbarViewCallbacks.triggerAllAppsButtonClick(view)
+ }
+ }
+
+ // Handle long click from Switch Access and Voice Access
+ private fun onAllAppsButtonLongClick(view: View): Boolean {
+ if (!MAIN_EXECUTOR.handler.hasCallbacks(allAppsTouchRunnable!!) && !allAppsTouchTriggered) {
+ taskbarViewCallbacks.triggerAllAppsButtonLongClick()
+ }
+ return true
+ }
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarDividerContainer.kt b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarDividerContainer.kt
index 26e71f7..1fb835a 100644
--- a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarDividerContainer.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarDividerContainer.kt
@@ -18,13 +18,15 @@
import android.annotation.SuppressLint
import android.content.Context
+import android.content.res.ColorStateList
+import android.graphics.Color.TRANSPARENT
import android.util.AttributeSet
import android.view.LayoutInflater
-import android.widget.LinearLayout
import androidx.core.view.setPadding
import com.android.launcher3.R
import com.android.launcher3.Utilities.dpToPx
import com.android.launcher3.taskbar.TaskbarActivityContext
+import com.android.launcher3.taskbar.TaskbarViewCallbacks
import com.android.launcher3.views.ActivityContext
import com.android.launcher3.views.IconButtonView
@@ -35,31 +37,30 @@
context: Context,
attrs: AttributeSet? = null,
defStyleAttr: Int = 0,
-) : LinearLayout(context, attrs), TaskbarContainer {
-
- private val taskbarDivider: IconButtonView =
- LayoutInflater.from(context).inflate(R.layout.taskbar_divider, this, false)
- as IconButtonView
+) : IconButtonView(context, attrs), TaskbarContainer {
private val activityContext: TaskbarActivityContext = ActivityContext.lookupContext(context)
override val spaceNeeded: Int
get() {
- return dpToPx(activityContext.taskbarSpecsEvaluator!!.taskbarIconSize.size.toFloat())
+ return dpToPx(activityContext.taskbarSpecsEvaluator.taskbarIconSize.size.toFloat())
}
init {
+ LayoutInflater.from(context).inflate(R.layout.taskbar_divider, null, false)
setUpIcon()
}
@SuppressLint("UseCompatLoadingForDrawables")
fun setUpIcon() {
+ backgroundTintList = ColorStateList.valueOf(TRANSPARENT)
val drawable = resources.getDrawable(R.drawable.taskbar_divider_button)
- val padding = activityContext.taskbarSpecsEvaluator!!.taskbarIconPadding
+ setIconDrawable(drawable)
+ setPadding(dpToPx(activityContext.taskbarSpecsEvaluator.taskbarIconPadding.toFloat()))
+ }
- taskbarDivider.setIconDrawable(drawable)
- taskbarDivider.setPadding(padding)
-
- // TODO(b/356465292):: add click listeners in future cl
- addView(taskbarDivider)
+ @SuppressLint("ClickableViewAccessibility")
+ fun setUpCallbacks(callbacks: TaskbarViewCallbacks) {
+ setOnLongClickListener(callbacks.taskbarDividerLongClickListener)
+ setOnTouchListener(callbacks.taskbarDividerRightClickListener)
}
}
diff --git a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarIconSpecs.kt b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarIconSpecs.kt
index 887eb01..6be0828 100644
--- a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarIconSpecs.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarIconSpecs.kt
@@ -19,10 +19,11 @@
/** Taskbar Icon Specs */
object TaskbarIconSpecs {
- val iconSize40dp = TaskbarIconSize(40)
- val iconSize44dp = TaskbarIconSize(44)
- val iconSize48dp = TaskbarIconSize(48)
- val iconSize52dp = TaskbarIconSize(52)
+ // Mapping of visual icon size to icon specs value http://b/235886078
+ val iconSize40dp = TaskbarIconSize(44)
+ val iconSize44dp = TaskbarIconSize(48)
+ val iconSize48dp = TaskbarIconSize(52)
+ val iconSize52dp = TaskbarIconSize(57)
val transientTaskbarIconSizes = arrayOf(iconSize44dp, iconSize48dp, iconSize52dp)
diff --git a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarSpecsEvaluator.kt b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarSpecsEvaluator.kt
index 761b47e..f37b2c1 100644
--- a/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarSpecsEvaluator.kt
+++ b/quickstep/src/com/android/launcher3/taskbar/customization/TaskbarSpecsEvaluator.kt
@@ -25,14 +25,14 @@
numRows: Int = taskbarActivityContext.deviceProfile.inv.numRows,
numColumns: Int = taskbarActivityContext.deviceProfile.inv.numColumns,
) {
- var taskbarIconSize: TaskbarIconSize = getIconSizeByGrid(numRows, numColumns)
+ var taskbarIconSize: TaskbarIconSize = getIconSizeByGrid(numColumns, numRows)
// TODO(b/341146605) : initialize it to taskbar container in later cl.
private var taskbarContainer: List<TaskbarContainer> = emptyList()
val taskbarIconPadding: Int =
- if (TaskbarIconSpecs.minimumTaskbarIconTouchSize.size > taskbarIconSize.size) {
- (TaskbarIconSpecs.minimumTaskbarIconTouchSize.size - taskbarIconSize.size) / 2
+ if (TaskbarIconSpecs.iconSize52dp.size > taskbarIconSize.size) {
+ (TaskbarIconSpecs.iconSize52dp.size - taskbarIconSize.size) / 2
} else {
0
}
@@ -44,10 +44,10 @@
TaskbarIconSpecs.defaultPersistentIconMargin
}
- fun getIconSizeByGrid(row: Int, column: Int): TaskbarIconSize {
+ fun getIconSizeByGrid(columns: Int, rows: Int): TaskbarIconSize {
return if (taskbarFeatureEvaluator.isTransient) {
TaskbarIconSpecs.transientTaskbarIconSizeByGridSize.getOrDefault(
- TransientTaskbarIconSizeKey(row, column, taskbarFeatureEvaluator.isLandscape),
+ TransientTaskbarIconSizeKey(columns, rows, taskbarFeatureEvaluator.isLandscape),
TaskbarIconSpecs.defaultTransientIconSize,
)
} else {
@@ -102,6 +102,6 @@
data class TaskbarIconSize(val size: Int)
-data class TransientTaskbarIconSizeKey(val row: Int, val column: Int, val isLandscape: Boolean)
+data class TransientTaskbarIconSizeKey(val columns: Int, val rows: Int, val isLandscape: Boolean)
data class TaskbarIconMarginSize(val size: Int)
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 bbf58a2..38d08e0 100644
--- a/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
+++ b/quickstep/src/com/android/quickstep/AbsSwipeUpHandler.java
@@ -952,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);
@@ -1772,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 {
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 d4b37f1..f653e60 100644
--- a/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
+++ b/quickstep/src/com/android/quickstep/LauncherSwipeHandlerV2.java
@@ -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 d70f0d7..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()
}
}
@@ -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/FloatingWidgetView.java b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
index 4dde635..bdca596 100644
--- a/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
+++ b/quickstep/src/com/android/quickstep/views/FloatingWidgetView.java
@@ -123,8 +123,8 @@
@Override
public void onGlobalLayout() {
if (isUninitialized()) return;
- positionViews();
- if (mOnTargetChangeRunnable != null) {
+ boolean positionsChanged = positionViews();
+ if (mOnTargetChangeRunnable != null && positionsChanged) {
mOnTargetChangeRunnable.run();
}
}
@@ -212,21 +212,43 @@
onGlobalLayout();
}
- /** Sets the layout parameters of the floating view and its background view child. */
- private void positionViews() {
+ /**
+ * Sets the layout parameters of the floating view and its background view child.
+ * @return true if any of the views positions change due to this call.
+ */
+ private boolean positionViews() {
+ boolean positionsChanged = false;
+
LayoutParams layoutParams = (LayoutParams) getLayoutParams();
- layoutParams.setMargins(0, 0, 0, 0);
- setLayoutParams(layoutParams);
+
+ if (layoutParams.topMargin != 0 || layoutParams.bottomMargin != 0
+ || layoutParams.rightMargin != 0 || layoutParams.leftMargin != 0) {
+ positionsChanged = true;
+ layoutParams.setMargins(0, 0, 0, 0);
+ setLayoutParams(layoutParams);
+ }
// FloatingWidgetView layout is forced LTR
- mBackgroundView.setTranslationX(mBackgroundPosition.left);
- mBackgroundView.setTranslationY(mBackgroundPosition.top + mIconOffsetY);
+ float targetY = mBackgroundPosition.top + mIconOffsetY;
+ if (mBackgroundView.getTranslationX() != mBackgroundPosition.left
+ || mBackgroundView.getTranslationY() != targetY) {
+ positionsChanged = true;
+ mBackgroundView.setTranslationX(mBackgroundPosition.left);
+ mBackgroundView.setTranslationY(targetY);
+ }
+
LayoutParams backgroundParams = (LayoutParams) mBackgroundView.getLayoutParams();
- backgroundParams.leftMargin = 0;
- backgroundParams.topMargin = 0;
- backgroundParams.width = (int) mBackgroundPosition.width();
- backgroundParams.height = (int) mBackgroundPosition.height();
- mBackgroundView.setLayoutParams(backgroundParams);
+ if (backgroundParams.leftMargin != 0 || backgroundParams.topMargin != 0
+ || backgroundParams.width != Math.round(mBackgroundPosition.width())
+ || backgroundParams.height != Math.round(mBackgroundPosition.height())) {
+ positionsChanged = true;
+
+ backgroundParams.leftMargin = 0;
+ backgroundParams.topMargin = 0;
+ backgroundParams.width = Math.round(mBackgroundPosition.width());
+ backgroundParams.height = Math.round(mBackgroundPosition.height());
+ mBackgroundView.setLayoutParams(backgroundParams);
+ }
if (mForegroundOverlayView != null) {
sTmpMatrix.reset();
@@ -237,8 +259,15 @@
sTmpMatrix.postScale(foregroundScale, foregroundScale);
sTmpMatrix.postTranslate(mBackgroundPosition.left, mBackgroundPosition.top
+ mIconOffsetY);
- mForegroundOverlayView.setMatrix(sTmpMatrix);
+
+ // We use the animation matrix here, because calling setMatrix on the GhostView
+ // actually sets the animation matrix, not the regular one.
+ if (!sTmpMatrix.equals(mForegroundOverlayView.getAnimationMatrix())) {
+ positionsChanged = true;
+ mForegroundOverlayView.setMatrix(sTmpMatrix);
+ }
}
+ return positionsChanged;
}
private void finish(DragLayer dragLayer) {
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/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashControllerTest.kt
index c0a5dfa..4106a2c 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/PersistentBubbleStashControllerTest.kt
@@ -251,7 +251,7 @@
whenever(bubbleBarViewController.hasBubbles()).thenReturn(true)
whenever(bubbleBarViewController.bubbleBarTranslationY).thenReturn(translationY)
- whenever(bubbleBarViewController.bubbleBarScale).thenReturn(scale)
+ whenever(bubbleBarViewController.bubbleBarScaleY).thenReturn(scale)
whenever(bubbleBarViewController.bubbleBarAlpha).thenReturn(alpha)
whenever(bubbleBarViewController.bubbleBarCollapsedHeight).thenReturn(BUBBLE_BAR_HEIGHT)
}
diff --git a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt
index b5809c2..63c2197 100644
--- a/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt
+++ b/quickstep/tests/multivalentTests/src/com/android/launcher3/taskbar/bubbles/stashing/TransientBubbleStashControllerTest.kt
@@ -31,7 +31,6 @@
import com.android.launcher3.taskbar.bubbles.BubbleBarView
import com.android.launcher3.taskbar.bubbles.BubbleBarViewController
import com.android.launcher3.taskbar.bubbles.BubbleStashedHandleViewController
-import com.android.launcher3.taskbar.bubbles.stashing.BubbleStashController.Companion.STASHED_BAR_SCALE
import com.android.launcher3.util.MultiValueAlpha
import com.android.wm.shell.shared.animation.PhysicsAnimator
import com.android.wm.shell.shared.animation.PhysicsAnimatorTestUtils
@@ -59,7 +58,7 @@
const val HOTSEAT_TRANSLATION_Y = -45f
const val TASK_BAR_TRANSLATION_Y = -TASKBAR_BOTTOM_SPACE
const val HANDLE_VIEW_HEIGHT = 4
- const val BUBBLE_BAR_STASHED_TRANSLATION_Y = 48
+ const val BUBBLE_BAR_STASHED_TRANSLATION_Y = -2.5f
}
@get:Rule val animatorTestRule: AnimatorTestRule = AnimatorTestRule(this)
@@ -90,7 +89,7 @@
val taskbarHotseatDimensionsProvider =
DefaultDimensionsProvider(taskBarBottomSpace = TASKBAR_BOTTOM_SPACE)
mTransientBubbleStashController =
- TransientBubbleStashController(taskbarHotseatDimensionsProvider, context.resources)
+ TransientBubbleStashController(taskbarHotseatDimensionsProvider, context)
setUpBubbleBarView()
setUpBubbleBarController()
setUpStashedHandleView()
@@ -174,8 +173,8 @@
assertThat(mTransientBubbleStashController.isStashed).isTrue()
assertThat(bubbleBarView.translationY).isEqualTo(BUBBLE_BAR_STASHED_TRANSLATION_Y)
assertThat(bubbleBarView.alpha).isEqualTo(0f)
- assertThat(bubbleBarView.scaleX).isEqualTo(STASHED_BAR_SCALE)
- assertThat(bubbleBarView.scaleY).isEqualTo(STASHED_BAR_SCALE)
+ assertThat(bubbleBarView.scaleX).isEqualTo(mTransientBubbleStashController.getStashScale())
+ assertThat(bubbleBarView.scaleY).isEqualTo(mTransientBubbleStashController.getStashScale())
// Handle view is visible
assertThat(stashedHandleView.translationY).isEqualTo(0)
assertThat(stashedHandleView.alpha).isEqualTo(1)
@@ -243,8 +242,8 @@
// Then all property values are updated
assertThat(bubbleBarView.translationY).isEqualTo(BUBBLE_BAR_STASHED_TRANSLATION_Y)
assertThat(bubbleBarView.alpha).isEqualTo(0)
- assertThat(bubbleBarView.scaleX).isEqualTo(STASHED_BAR_SCALE)
- assertThat(bubbleBarView.scaleY).isEqualTo(STASHED_BAR_SCALE)
+ assertThat(bubbleBarView.scaleX).isEqualTo(mTransientBubbleStashController.getStashScale())
+ assertThat(bubbleBarView.scaleY).isEqualTo(mTransientBubbleStashController.getStashScale())
// Handle is visible at correct Y position
assertThat(stashedHandleView.alpha).isEqualTo(1)
assertThat(stashedHandleView.translationY).isEqualTo(0)
@@ -306,7 +305,7 @@
whenever(bubbleBarViewController.hasBubbles()).thenReturn(true)
whenever(bubbleBarViewController.bubbleBarTranslationY).thenReturn(barTranslationY)
- whenever(bubbleBarViewController.bubbleBarScale).thenReturn(barScale)
+ whenever(bubbleBarViewController.bubbleBarScaleY).thenReturn(barScale)
whenever(bubbleBarViewController.bubbleBarAlpha).thenReturn(barAlpha)
whenever(bubbleBarViewController.bubbleBarCollapsedHeight).thenReturn(BUBBLE_BAR_HEIGHT)
}
diff --git a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
index 597227a..f971afb 100644
--- a/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
+++ b/quickstep/tests/src/com/android/quickstep/TaplTestsQuickstep.java
@@ -266,9 +266,6 @@
return launcher.<RecentsView>getOverviewPanel().getBottomRowTaskCountForTablet();
}
- // Staging; will be promoted to presubmit if stable
- @TestStabilityRule.Stability(flavors = LOCAL | PLATFORM_POSTSUBMIT)
-
@Test
@NavigationModeSwitch
@PortraitLandscape
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/Launcher.java b/src/com/android/launcher3/Launcher.java
index 3ca6099..bafb528 100644
--- a/src/com/android/launcher3/Launcher.java
+++ b/src/com/android/launcher3/Launcher.java
@@ -435,6 +435,10 @@
mIsColdStartupAfterReboot = sIsNewProcess
&& !LockedUserState.get(this).isUserUnlockedAtLauncherStartup();
if (mIsColdStartupAfterReboot) {
+ /*
+ * This trace is used to calculate the time from create to the point that icons are
+ * visible.
+ */
Trace.beginAsyncSection(
COLD_STARTUP_TRACE_METHOD_NAME, COLD_STARTUP_TRACE_COOKIE);
}
@@ -2384,10 +2388,6 @@
.logEnd(LAUNCHER_LATENCY_STARTUP_TOTAL_DURATION)
.log()
.reset();
- if (mIsColdStartupAfterReboot) {
- Trace.endAsyncSection(COLD_STARTUP_TRACE_METHOD_NAME,
- COLD_STARTUP_TRACE_COOKIE);
- }
});
}
@@ -2396,6 +2396,10 @@
RunnableList onCompleteSignal, int workspaceItemCount, boolean isBindSync) {
mModelCallbacks.onInitialBindComplete(boundPages, pendingTasks, onCompleteSignal,
workspaceItemCount, isBindSync);
+ if (mIsColdStartupAfterReboot) {
+ Trace.endAsyncSection(COLD_STARTUP_TRACE_METHOD_NAME,
+ COLD_STARTUP_TRACE_COOKIE);
+ }
}
/**
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 {