Merge "AmbientContextManager API changes to support quick-tap detection" into tm-qpr-dev
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index c10c380..41a784a 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -26,7 +26,7 @@
hidden_api_txt_exclude_hook = ${REPO_ROOT}/frameworks/base/tools/hiddenapi/exclude.sh ${PREUPLOAD_COMMIT} ${REPO_ROOT}
-ktfmt_hook = ${REPO_ROOT}/external/ktfmt/ktfmt.py --check -i ${REPO_ROOT}/frameworks/base/ktfmt_includes.txt ${PREUPLOAD_FILES}
+ktfmt_hook = ${REPO_ROOT}/external/ktfmt/ktfmt.py --check -i ${REPO_ROOT}/frameworks/base/packages/SystemUI/ktfmt_includes.txt ${PREUPLOAD_FILES}
ktlint_hook = ${REPO_ROOT}/prebuilts/ktlint/ktlint.py -f ${PREUPLOAD_FILES}
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index fbc2148..aad32b1 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -1740,7 +1740,7 @@
<!-- Generic error message shown when the fingerprint operation fails because too many attempts have been made. -->
<string name="fingerprint_error_lockout">Too many attempts. Try again later.</string>
<!-- Generic error message shown when the fingerprint operation fails because strong authentication is required -->
- <string name="fingerprint_error_lockout_permanent">Too many attempts. Fingerprint sensor disabled.</string>
+ <string name="fingerprint_error_lockout_permanent">Too many attempts. Use screen lock instead.</string>
<!-- Generic error message shown when the fingerprint hardware can't recognize the fingerprint -->
<string name="fingerprint_error_unable_to_process">Try again.</string>
<!-- Generic error message shown when the user has no enrolled fingerprints -->
diff --git a/ktfmt_includes.txt b/ktfmt_includes.txt
deleted file mode 100644
index c7062e0..0000000
--- a/ktfmt_includes.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-packages/SystemUI/compose/
-packages/SystemUI/screenshot/
-packages/SystemUI/src/com/android/systemui/people/data
-packages/SystemUI/src/com/android/systemui/people/ui
-packages/SystemUI/src/com/android/systemui/keyguard/data
-packages/SystemUI/src/com/android/systemui/keyguard/dagger
-packages/SystemUI/src/com/android/systemui/keyguard/domain
-packages/SystemUI/src/com/android/systemui/keyguard/shared
-packages/SystemUI/src/com/android/systemui/keyguard/ui
-packages/SystemUI/src/com/android/systemui/qs/footer
-packages/SystemUI/src/com/android/systemui/security
-packages/SystemUI/src/com/android/systemui/common/
-packages/SystemUI/tests/utils/src/com/android/systemui/qs/
-packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeSecurityController.kt
-packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/FakeUserInfoController.kt
-packages/SystemUI/tests/utils/src/com/android/systemui/statusbar/policy/MockUserSwitcherControllerWrapper.kt
-packages/SystemUI/tests/src/com/android/systemui/qs/footer/
\ No newline at end of file
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
index 02af916..4102732 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitController.java
@@ -792,6 +792,9 @@
* Checks if there is a rule to split the two activities. If there is one, puts them into split
* and returns {@code true}. Otherwise, returns {@code false}.
*/
+ // Suppress GuardedBy warning because lint ask to mark this method as
+ // @GuardedBy(mPresenter.mController.mLock), which is mLock itself
+ @SuppressWarnings("GuardedBy")
@GuardedBy("mLock")
private boolean putActivitiesIntoSplitIfNecessary(@NonNull WindowContainerTransaction wct,
@NonNull Activity primaryActivity, @NonNull Activity secondaryActivity) {
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
index 2b069d7..2ef8e4c 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/SplitPresenter.java
@@ -38,6 +38,7 @@
import android.view.WindowMetrics;
import android.window.WindowContainerTransaction;
+import androidx.annotation.GuardedBy;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
@@ -171,6 +172,7 @@
* created and the activity will be re-parented to it.
* @param rule The split rule to be applied to the container.
*/
+ @GuardedBy("mController.mLock")
void createNewSplitContainer(@NonNull WindowContainerTransaction wct,
@NonNull Activity primaryActivity, @NonNull Activity secondaryActivity,
@NonNull SplitPairRule rule) {
@@ -187,8 +189,10 @@
final TaskFragmentContainer curSecondaryContainer = mController.getContainerWithActivity(
secondaryActivity);
TaskFragmentContainer containerToAvoid = primaryContainer;
- if (rule.shouldClearTop() && curSecondaryContainer != null) {
- // Do not reuse the current TaskFragment if the rule is to clear top.
+ if (curSecondaryContainer != null
+ && (rule.shouldClearTop() || primaryContainer.isAbove(curSecondaryContainer))) {
+ // Do not reuse the current TaskFragment if the rule is to clear top, or if it is below
+ // the primary TaskFragment.
containerToAvoid = curSecondaryContainer;
}
final TaskFragmentContainer secondaryContainer = prepareContainerForActivity(wct,
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
index 77e26c0..45645b2 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskContainer.java
@@ -162,4 +162,8 @@
}
return null;
}
+
+ int indexOf(@NonNull TaskFragmentContainer child) {
+ return mContainers.indexOf(child);
+ }
}
diff --git a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
index 11c0db3..344ffc7 100644
--- a/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
+++ b/libs/WindowManager/Jetpack/src/androidx/window/extensions/embedding/TaskFragmentContainer.java
@@ -501,6 +501,18 @@
return new Size(maxMinWidth, maxMinHeight);
}
+ /** Whether the current TaskFragment is above the {@code other} TaskFragment. */
+ boolean isAbove(@NonNull TaskFragmentContainer other) {
+ if (mTaskContainer != other.mTaskContainer) {
+ throw new IllegalArgumentException(
+ "Trying to compare two TaskFragments in different Task.");
+ }
+ if (this == other) {
+ throw new IllegalArgumentException("Trying to compare a TaskFragment with itself.");
+ }
+ return mTaskContainer.indexOf(this) > mTaskContainer.indexOf(other);
+ }
+
@Override
public String toString() {
return toString(true /* includeContainersToFinishOnExit */);
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
index da724d9..25f0e25 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/SplitPresenterTest.java
@@ -39,6 +39,7 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
@@ -247,6 +248,26 @@
verify(mPresenter).expandTaskFragment(mTransaction, secondaryTf.getTaskFragmentToken());
}
+ @Test
+ public void testCreateNewSplitContainer_secondaryAbovePrimary() {
+ final Activity secondaryActivity = createMockActivity();
+ final TaskFragmentContainer bottomTf = mController.newContainer(secondaryActivity, TASK_ID);
+ final TaskFragmentContainer primaryTf = mController.newContainer(mActivity, TASK_ID);
+ final SplitPairRule rule = new SplitPairRule.Builder(pair ->
+ pair.first == mActivity && pair.second == secondaryActivity, pair -> false,
+ metrics -> true)
+ .setShouldClearTop(false)
+ .build();
+
+ mPresenter.createNewSplitContainer(mTransaction, mActivity, secondaryActivity, rule);
+
+ assertEquals(primaryTf, mController.getContainerWithActivity(mActivity));
+ final TaskFragmentContainer secondaryTf = mController.getContainerWithActivity(
+ secondaryActivity);
+ assertNotEquals(bottomTf, secondaryTf);
+ assertTrue(secondaryTf.isAbove(primaryTf));
+ }
+
private Activity createMockActivity() {
final Activity activity = mock(Activity.class);
final Configuration activityConfig = new Configuration();
diff --git a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java
index 6cbecff..1bc81ee 100644
--- a/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java
+++ b/libs/WindowManager/Jetpack/tests/unittest/src/androidx/window/extensions/embedding/TaskFragmentContainerTest.java
@@ -288,6 +288,18 @@
}
@Test
+ public void testIsAbove() {
+ final TaskContainer taskContainer = new TaskContainer(TASK_ID);
+ final TaskFragmentContainer container0 = new TaskFragmentContainer(null /* activity */,
+ mIntent, taskContainer, mController);
+ final TaskFragmentContainer container1 = new TaskFragmentContainer(null /* activity */,
+ mIntent, taskContainer, mController);
+
+ assertTrue(container1.isAbove(container0));
+ assertFalse(container0.isAbove(container1));
+ }
+
+ @Test
public void testGetBottomMostActivity() {
final TaskContainer taskContainer = new TaskContainer(TASK_ID);
final TaskFragmentContainer container = new TaskFragmentContainer(null /* activity */,
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_letterboxed_app.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_letterboxed_app.xml
deleted file mode 100644
index 6fcd1de..0000000
--- a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_letterboxed_app.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/letterbox_education_dialog_icon_size"
- android:height="@dimen/letterbox_education_dialog_icon_size"
- android:viewportWidth="48"
- android:viewportHeight="48">
- <path
- android:fillColor="@color/letterbox_education_accent_primary"
- android:fillType="evenOdd"
- android:pathData="M2 8C0.895431 8 0 8.89543 0 10V38C0 39.1046 0.895431 40 2 40H46C47.1046 40 48 39.1046 48 38V10C48 8.89543 47.1046 8 46 8H2ZM44 12H4V36H44V12Z" />
- <path
- android:fillColor="@color/letterbox_education_accent_primary"
- android:pathData="M 17 14 L 31 14 Q 32 14 32 15 L 32 33 Q 32 34 31 34 L 17 34 Q 16 34 16 33 L 16 15 Q 16 14 17 14 Z" />
-</vector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_light_bulb.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_light_bulb.xml
new file mode 100644
index 0000000..ddfb5c2
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_light_bulb.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 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.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="@dimen/letterbox_education_dialog_title_icon_width"
+ android:height="@dimen/letterbox_education_dialog_title_icon_height"
+ android:viewportWidth="45"
+ android:viewportHeight="44">
+
+ <path
+ android:fillColor="@color/letterbox_education_accent_primary"
+ android:pathData="M11 40H19C19 42.2 17.2 44 15 44C12.8 44 11 42.2 11 40ZM7 38L23 38V34L7 34L7 38ZM30 19C30 26.64 24.68 30.72 22.46 32L7.54 32C5.32 30.72 0 26.64 0 19C0 10.72 6.72 4 15 4C23.28 4 30 10.72 30 19ZM26 19C26 12.94 21.06 8 15 8C8.94 8 4 12.94 4 19C4 23.94 6.98 26.78 8.7 28L21.3 28C23.02 26.78 26 23.94 26 19ZM39.74 14.74L37 16L39.74 17.26L41 20L42.26 17.26L45 16L42.26 14.74L41 12L39.74 14.74ZM35 12L36.88 7.88L41 6L36.88 4.12L35 0L33.12 4.12L29 6L33.12 7.88L35 12Z" />
+</vector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_reposition.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_reposition.xml
index cbfcfd0..22a8f39 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_reposition.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_reposition.xml
@@ -15,18 +15,16 @@
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/letterbox_education_dialog_icon_size"
- android:height="@dimen/letterbox_education_dialog_icon_size"
- android:viewportWidth="48"
- android:viewportHeight="48">
+ android:width="@dimen/letterbox_education_dialog_icon_width"
+ android:height="@dimen/letterbox_education_dialog_icon_height"
+ android:viewportWidth="40"
+ android:viewportHeight="32">
+
<path
android:fillColor="@color/letterbox_education_text_secondary"
android:fillType="evenOdd"
- android:pathData="M2 8C0.895431 8 0 8.89543 0 10V38C0 39.1046 0.895431 40 2 40H46C47.1046 40 48 39.1046 48 38V10C48 8.89543 47.1046 8 46 8H2ZM44 12H4V36H44V12Z" />
+ android:pathData="M4 0C1.79086 0 0 1.79086 0 4V28C0 30.2091 1.79086 32 4 32H36C38.2091 32 40 30.2091 40 28V4C40 1.79086 38.2091 0 36 0H4ZM36 4H4V28H36V4Z" />
<path
android:fillColor="@color/letterbox_education_text_secondary"
- android:pathData="M 14 22 H 30 V 26 H 14 V 22 Z" />
- <path
- android:fillColor="@color/letterbox_education_text_secondary"
- android:pathData="M26 16L34 24L26 32V16Z" />
+ android:pathData="M19.98 8L17.16 10.82L20.32 14L12 14V18H20.32L17.14 21.18L19.98 24L28 16.02L19.98 8Z" />
</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_screen_rotation.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_screen_rotation.xml
deleted file mode 100644
index 469eb1e..0000000
--- a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_screen_rotation.xml
+++ /dev/null
@@ -1,26 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!--
- ~ Copyright (C) 2022 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.
- -->
-<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/letterbox_education_dialog_icon_size"
- android:height="@dimen/letterbox_education_dialog_icon_size"
- android:viewportWidth="48"
- android:viewportHeight="48">
- <path
- android:fillColor="@color/letterbox_education_text_secondary"
- android:fillType="evenOdd"
- android:pathData="M22.56 2H26C37.02 2 46 10.98 46 22H42C42 14.44 36.74 8.1 29.7 6.42L31.74 10L28.26 12L22.56 2ZM22 46H25.44L19.74 36L16.26 38L18.3 41.58C11.26 39.9 6 33.56 6 26H2C2 37.02 10.98 46 22 46ZM20.46 12L36 27.52L27.54 36L12 20.48L20.46 12ZM17.64 9.18C18.42 8.4 19.44 8 20.46 8C21.5 8 22.52 8.4 23.3 9.16L38.84 24.7C40.4 26.26 40.4 28.78 38.84 30.34L30.36 38.82C29.58 39.6 28.56 40 27.54 40C26.52 40 25.5 39.6 24.72 38.82L9.18 23.28C7.62 21.72 7.62 19.2 9.18 17.64L17.64 9.18Z" />
-</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_split_screen.xml b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_split_screen.xml
index dcb8aed..15e65f7 100644
--- a/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_split_screen.xml
+++ b/libs/WindowManager/Shell/res/drawable/letterbox_education_ic_split_screen.xml
@@ -15,18 +15,12 @@
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="@dimen/letterbox_education_dialog_icon_size"
- android:height="@dimen/letterbox_education_dialog_icon_size"
- android:viewportWidth="48"
- android:viewportHeight="48">
+ android:width="@dimen/letterbox_education_dialog_icon_width"
+ android:height="@dimen/letterbox_education_dialog_icon_height"
+ android:viewportWidth="40"
+ android:viewportHeight="32">
+
<path
android:fillColor="@color/letterbox_education_text_secondary"
- android:fillType="evenOdd"
- android:pathData="M2 8C0.895431 8 0 8.89543 0 10V38C0 39.1046 0.895431 40 2 40H46C47.1046 40 48 39.1046 48 38V10C48 8.89543 47.1046 8 46 8H2ZM44 12H4V36H44V12Z" />
- <path
- android:fillColor="@color/letterbox_education_text_secondary"
- android:pathData="M6 16C6 14.8954 6.89543 14 8 14H21C22.1046 14 23 14.8954 23 16V32C23 33.1046 22.1046 34 21 34H8C6.89543 34 6 33.1046 6 32V16Z" />
- <path
- android:fillColor="@color/letterbox_education_text_secondary"
- android:pathData="M25 16C25 14.8954 25.8954 14 27 14H40C41.1046 14 42 14.8954 42 16V32C42 33.1046 41.1046 34 40 34H27C25.8954 34 25 33.1046 25 32V16Z" />
+ android:pathData="M40 28L40 4C40 1.8 38.2 -7.86805e-08 36 -1.74846e-07L26 -6.11959e-07C23.8 -7.08124e-07 22 1.8 22 4L22 28C22 30.2 23.8 32 26 32L36 32C38.2 32 40 30.2 40 28ZM14 28L4 28L4 4L14 4L14 28ZM18 28L18 4C18 1.8 16.2 -1.04033e-06 14 -1.1365e-06L4 -1.57361e-06C1.8 -1.66978e-06 -7.86805e-08 1.8 -1.74846e-07 4L-1.22392e-06 28C-1.32008e-06 30.2 1.8 32 4 32L14 32C16.2 32 18 30.2 18 28Z" />
</vector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml
index cd1d99a..c65f24d 100644
--- a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_action_layout.xml
@@ -26,7 +26,7 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center"
- android:layout_marginBottom="12dp"/>
+ android:layout_marginBottom="20dp"/>
<TextView
android:id="@+id/letterbox_education_dialog_action_text"
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
index 9592376..3a44eb9 100644
--- a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
@@ -50,13 +50,16 @@
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:orientation="vertical"
- android:padding="24dp">
+ android:paddingTop="32dp"
+ android:paddingBottom="32dp"
+ android:paddingLeft="56dp"
+ android:paddingRight="56dp">
<ImageView
- android:layout_width="@dimen/letterbox_education_dialog_icon_size"
- android:layout_height="@dimen/letterbox_education_dialog_icon_size"
- android:layout_marginBottom="12dp"
- android:src="@drawable/letterbox_education_ic_letterboxed_app"/>
+ android:layout_width="@dimen/letterbox_education_dialog_title_icon_width"
+ android:layout_height="@dimen/letterbox_education_dialog_title_icon_height"
+ android:layout_marginBottom="17dp"
+ android:src="@drawable/letterbox_education_ic_light_bulb"/>
<TextView
android:id="@+id/letterbox_education_dialog_title"
@@ -68,16 +71,6 @@
android:textColor="@color/compat_controls_text"
android:textSize="24sp"/>
- <TextView
- android:layout_width="match_parent"
- android:layout_height="wrap_content"
- android:layout_marginTop="8dp"
- android:lineSpacingExtra="4sp"
- android:text="@string/letterbox_education_dialog_subtext"
- android:textAlignment="center"
- android:textColor="@color/letterbox_education_text_secondary"
- android:textSize="14sp"/>
-
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
@@ -88,16 +81,16 @@
<com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogActionLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- app:icon="@drawable/letterbox_education_ic_screen_rotation"
- app:text="@string/letterbox_education_screen_rotation_text"/>
+ app:icon="@drawable/letterbox_education_ic_reposition"
+ app:text="@string/letterbox_education_reposition_text"/>
<com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogActionLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart=
"@dimen/letterbox_education_dialog_space_between_actions"
- app:icon="@drawable/letterbox_education_ic_reposition"
- app:text="@string/letterbox_education_reposition_text"/>
+ app:icon="@drawable/letterbox_education_ic_split_screen"
+ app:text="@string/letterbox_education_split_screen_text"/>
</LinearLayout>
@@ -105,7 +98,7 @@
android:id="@+id/letterbox_education_dialog_dismiss_button"
android:layout_width="match_parent"
android:layout_height="56dp"
- android:layout_marginTop="48dp"
+ android:layout_marginTop="40dp"
android:background=
"@drawable/letterbox_education_dismiss_button_background_ripple"
android:text="@string/letterbox_education_got_it"
diff --git a/libs/WindowManager/Shell/res/values/dimen.xml b/libs/WindowManager/Shell/res/values/dimen.xml
index 1dac9ca..d2dd8d6b 100644
--- a/libs/WindowManager/Shell/res/values/dimen.xml
+++ b/libs/WindowManager/Shell/res/values/dimen.xml
@@ -246,8 +246,17 @@
<!-- The corner radius of the letterbox education dialog. -->
<dimen name="letterbox_education_dialog_corner_radius">28dp</dimen>
- <!-- The size of an icon in the letterbox education dialog. -->
- <dimen name="letterbox_education_dialog_icon_size">48dp</dimen>
+ <!-- The width of the top icon in the letterbox education dialog. -->
+ <dimen name="letterbox_education_dialog_title_icon_width">45dp</dimen>
+
+ <!-- The height of the top icon in the letterbox education dialog. -->
+ <dimen name="letterbox_education_dialog_title_icon_height">44dp</dimen>
+
+ <!-- The width of an icon in the letterbox education dialog. -->
+ <dimen name="letterbox_education_dialog_icon_width">40dp</dimen>
+
+ <!-- The height of an icon in the letterbox education dialog. -->
+ <dimen name="letterbox_education_dialog_icon_height">32dp</dimen>
<!-- The fixed width of the dialog if there is enough space in the parent. -->
<dimen name="letterbox_education_dialog_width">472dp</dimen>
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index 96778a9..1d1162d 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -172,16 +172,13 @@
<string name="camera_compat_dismiss_button_description">No camera issues? Tap to dismiss.</string>
<!-- The title of the letterbox education dialog. [CHAR LIMIT=NONE] -->
- <string name="letterbox_education_dialog_title">Some apps work best in portrait</string>
+ <string name="letterbox_education_dialog_title">See and do more</string>
- <!-- The subtext of the letterbox education dialog. [CHAR LIMIT=NONE] -->
- <string name="letterbox_education_dialog_subtext">Try one of these options to make the most of your space</string>
-
- <!-- Description of the rotate screen action. [CHAR LIMIT=NONE] -->
- <string name="letterbox_education_screen_rotation_text">Rotate your device to go full screen</string>
+ <!-- Description of the split screen action. [CHAR LIMIT=NONE] -->
+ <string name="letterbox_education_split_screen_text">Drag in another app for split-screen</string>
<!-- Description of the reposition app action. [CHAR LIMIT=NONE] -->
- <string name="letterbox_education_reposition_text">Double-tap next to an app to reposition it</string>
+ <string name="letterbox_education_reposition_text">Double-tap outside an app to reposition it</string>
<!-- Button text for dismissing the letterbox education dialog. [CHAR LIMIT=20] -->
<string name="letterbox_education_got_it">Got it</string>
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
index b7959eb..4c85d20 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/common/split/SplitLayout.java
@@ -80,7 +80,10 @@
public static final int PARALLAX_DISMISSING = 1;
public static final int PARALLAX_ALIGN_CENTER = 2;
- private static final int FLING_ANIMATION_DURATION = 250;
+ private static final int FLING_RESIZE_DURATION = 250;
+ private static final int FLING_SWITCH_DURATION = 350;
+ private static final int FLING_ENTER_DURATION = 350;
+ private static final int FLING_EXIT_DURATION = 350;
private final int mDividerWindowWidth;
private final int mDividerInsets;
@@ -93,6 +96,9 @@
private final Rect mBounds1 = new Rect();
// Bounds2 final position should be always at bottom or right
private final Rect mBounds2 = new Rect();
+ // The temp bounds outside of display bounds for side stage when split screen inactive to avoid
+ // flicker next time active split screen.
+ private final Rect mInvisibleBounds = new Rect();
private final Rect mWinBounds1 = new Rect();
private final Rect mWinBounds2 = new Rect();
private final SplitLayoutHandler mSplitLayoutHandler;
@@ -141,6 +147,8 @@
resetDividerPosition();
mDimNonImeSide = resources.getBoolean(R.bool.config_dimNonImeAttachedSide);
+
+ updateInvisibleRect();
}
private int getDividerInsets(Resources resources, Display display) {
@@ -239,6 +247,12 @@
rect.offset(-mRootBounds.left, -mRootBounds.top);
}
+ /** Gets bounds size equal to root bounds but outside of screen, used for position side stage
+ * when split inactive to avoid flicker when next time active. */
+ public void getInvisibleBounds(Rect rect) {
+ rect.set(mInvisibleBounds);
+ }
+
/** Returns leash of the current divider bar. */
@Nullable
public SurfaceControl getDividerLeash() {
@@ -258,6 +272,14 @@
: (float) ((mBounds1.bottom + mBounds2.top) / 2f) / mBounds2.bottom));
}
+ private void updateInvisibleRect() {
+ mInvisibleBounds.set(mRootBounds.left, mRootBounds.top,
+ isLandscape() ? mRootBounds.right / 2 : mRootBounds.right,
+ isLandscape() ? mRootBounds.bottom : mRootBounds.bottom / 2);
+ mInvisibleBounds.offset(isLandscape() ? mRootBounds.right : 0,
+ isLandscape() ? 0 : mRootBounds.bottom);
+ }
+
/** Applies new configuration, returns {@code false} if there's no effect to the layout. */
public boolean updateConfiguration(Configuration configuration) {
// Update the split bounds when necessary. Besides root bounds changed, split bounds need to
@@ -283,6 +305,7 @@
mRotation = rotation;
mDividerSnapAlgorithm = getSnapAlgorithm(mContext, mRootBounds, null);
initDividerPosition(mTempRect);
+ updateInvisibleRect();
return true;
}
@@ -405,6 +428,13 @@
mFreezeDividerWindow = freezeDividerWindow;
}
+ /** Update current layout as divider put on start or end position. */
+ public void setDividerAtBorder(boolean start) {
+ final int pos = start ? mDividerSnapAlgorithm.getDismissStartTarget().position
+ : mDividerSnapAlgorithm.getDismissEndTarget().position;
+ setDividePosition(pos, false /* applyLayoutChange */);
+ }
+
/**
* Updates bounds with the passing position. Usually used to update recording bounds while
* performing animation or dragging divider bar to resize the splits.
@@ -449,17 +479,17 @@
public void snapToTarget(int currentPosition, DividerSnapAlgorithm.SnapTarget snapTarget) {
switch (snapTarget.flag) {
case FLAG_DISMISS_START:
- flingDividePosition(currentPosition, snapTarget.position,
+ flingDividePosition(currentPosition, snapTarget.position, FLING_RESIZE_DURATION,
() -> mSplitLayoutHandler.onSnappedToDismiss(false /* bottomOrRight */,
EXIT_REASON_DRAG_DIVIDER));
break;
case FLAG_DISMISS_END:
- flingDividePosition(currentPosition, snapTarget.position,
+ flingDividePosition(currentPosition, snapTarget.position, FLING_RESIZE_DURATION,
() -> mSplitLayoutHandler.onSnappedToDismiss(true /* bottomOrRight */,
EXIT_REASON_DRAG_DIVIDER));
break;
default:
- flingDividePosition(currentPosition, snapTarget.position,
+ flingDividePosition(currentPosition, snapTarget.position, FLING_RESIZE_DURATION,
() -> setDividePosition(snapTarget.position, true /* applyLayoutChange */));
break;
}
@@ -514,12 +544,20 @@
public void flingDividerToDismiss(boolean toEnd, int reason) {
final int target = toEnd ? mDividerSnapAlgorithm.getDismissEndTarget().position
: mDividerSnapAlgorithm.getDismissStartTarget().position;
- flingDividePosition(getDividePosition(), target,
+ flingDividePosition(getDividePosition(), target, FLING_EXIT_DURATION,
() -> mSplitLayoutHandler.onSnappedToDismiss(toEnd, reason));
}
+ /** Fling divider from current position to center position. */
+ public void flingDividerToCenter() {
+ final int pos = mDividerSnapAlgorithm.getMiddleTarget().position;
+ flingDividePosition(getDividePosition(), pos, FLING_ENTER_DURATION,
+ () -> setDividePosition(pos, true /* applyLayoutChange */));
+ }
+
@VisibleForTesting
- void flingDividePosition(int from, int to, @Nullable Runnable flingFinishedCallback) {
+ void flingDividePosition(int from, int to, int duration,
+ @Nullable Runnable flingFinishedCallback) {
if (from == to) {
// No animation run, still callback to stop resizing.
mSplitLayoutHandler.onLayoutSizeChanged(this);
@@ -529,7 +567,7 @@
}
ValueAnimator animator = ValueAnimator
.ofInt(from, to)
- .setDuration(FLING_ANIMATION_DURATION);
+ .setDuration(duration);
animator.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
animator.addUpdateListener(
animation -> updateDivideBounds((int) animation.getAnimatedValue()));
@@ -586,7 +624,7 @@
AnimatorSet set = new AnimatorSet();
set.playTogether(animator1, animator2, animator3);
- set.setDuration(FLING_ANIMATION_DURATION);
+ set.setDuration(FLING_SWITCH_DURATION);
set.addListener(new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index 7e83d2f..c08aa5a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -25,6 +25,7 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.content.Intent.FLAG_ACTIVITY_MULTIPLE_TASK;
+import static android.content.res.Configuration.SMALLEST_SCREEN_WIDTH_DP_UNDEFINED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.RemoteAnimationTarget.MODE_OPENING;
import static android.view.WindowManager.LayoutParams.TYPE_DOCK_DIVIDER;
@@ -488,13 +489,6 @@
final WindowContainerTransaction wct = new WindowContainerTransaction();
options = resolveStartStage(STAGE_TYPE_UNDEFINED, position, options, wct);
- // If split still not active, apply windows bounds first to avoid surface reset to
- // wrong pos by SurfaceAnimator from wms.
- // TODO(b/223325631): check is it still necessary after improve enter transition done.
- if (!mMainStage.isActive()) {
- updateWindowBounds(mSplitLayout, wct);
- }
-
wct.sendPendingIntent(intent, fillInIntent, options);
mSyncQueue.queue(transition, WindowManager.TRANSIT_OPEN, wct);
}
@@ -519,6 +513,7 @@
mSplitLayout.setDivideRatio(splitRatio);
updateWindowBounds(mSplitLayout, wct);
wct.reorder(mRootTaskInfo.token, true);
+ wct.setForceTranslucent(mRootTaskInfo.token, false);
// Make sure the launch options will put tasks in the corresponding split roots
addActivityOptions(mainOptions, mMainStage);
@@ -628,6 +623,7 @@
}
updateWindowBounds(mSplitLayout, wct);
wct.reorder(mRootTaskInfo.token, true);
+ wct.setForceTranslucent(mRootTaskInfo.token, false);
// Make sure the launch options will put tasks in the corresponding split roots
addActivityOptions(mainOptions, mMainStage);
@@ -640,8 +636,8 @@
} else {
wct.startTask(sideTaskId, sideOptions);
}
- // Using legacy transitions, so we can't use blast sync since it conflicts.
- mTaskOrganizer.applyTransaction(wct);
+
+ mSyncQueue.queue(wct);
mSyncQueue.runInSync(t -> {
setDividerVisibility(true, t);
updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
@@ -893,10 +889,13 @@
mShouldUpdateRecents = false;
mIsDividerRemoteAnimating = false;
+ mSplitLayout.getInvisibleBounds(mTempRect1);
if (childrenToTop == null) {
mSideStage.removeAllTasks(wct, false /* toTop */);
mMainStage.deactivate(wct, false /* toTop */);
wct.reorder(mRootTaskInfo.token, false /* onTop */);
+ wct.setForceTranslucent(mRootTaskInfo.token, true);
+ wct.setBounds(mSideStage.mRootTaskInfo.token, mTempRect1);
onTransitionAnimationComplete();
} else {
// Expand to top side split as full screen for fading out decor animation and dismiss
@@ -907,27 +906,32 @@
? mSideStage : mMainStage;
tempFullStage.resetBounds(wct);
wct.setSmallestScreenWidthDp(tempFullStage.mRootTaskInfo.token,
- mRootTaskInfo.configuration.smallestScreenWidthDp);
+ SMALLEST_SCREEN_WIDTH_DP_UNDEFINED);
dismissStage.dismiss(wct, false /* toTop */);
}
mSyncQueue.queue(wct);
mSyncQueue.runInSync(t -> {
t.setWindowCrop(mMainStage.mRootLeash, null)
.setWindowCrop(mSideStage.mRootLeash, null);
- t.setPosition(mMainStage.mRootLeash, 0, 0)
- .setPosition(mSideStage.mRootLeash, 0, 0);
t.hide(mMainStage.mDimLayer).hide(mSideStage.mDimLayer);
setDividerVisibility(false, t);
- // In this case, exit still under progress, fade out the split decor after first WCT
- // done and do remaining WCT after animation finished.
- if (childrenToTop != null) {
+ if (childrenToTop == null) {
+ t.setPosition(mSideStage.mRootLeash, mTempRect1.left, mTempRect1.right);
+ } else {
+ // In this case, exit still under progress, fade out the split decor after first WCT
+ // done and do remaining WCT after animation finished.
childrenToTop.fadeOutDecor(() -> {
WindowContainerTransaction finishedWCT = new WindowContainerTransaction();
mIsExiting = false;
childrenToTop.dismiss(finishedWCT, true /* toTop */);
finishedWCT.reorder(mRootTaskInfo.token, false /* toTop */);
- mTaskOrganizer.applyTransaction(finishedWCT);
+ finishedWCT.setForceTranslucent(mRootTaskInfo.token, true);
+ finishedWCT.setBounds(mSideStage.mRootTaskInfo.token, mTempRect1);
+ mSyncQueue.queue(finishedWCT);
+ mSyncQueue.runInSync(at -> {
+ at.setPosition(mSideStage.mRootLeash, mTempRect1.left, mTempRect1.right);
+ });
onTransitionAnimationComplete();
});
}
@@ -996,6 +1000,7 @@
mMainStage.activate(wct, true /* includingTopTask */);
updateWindowBounds(mSplitLayout, wct);
wct.reorder(mRootTaskInfo.token, true);
+ wct.setForceTranslucent(mRootTaskInfo.token, false);
}
void finishEnterSplitScreen(SurfaceControl.Transaction t) {
@@ -1221,7 +1226,13 @@
// Make the stages adjacent to each other so they occlude what's behind them.
wct.setAdjacentRoots(mMainStage.mRootTaskInfo.token, mSideStage.mRootTaskInfo.token);
wct.setLaunchAdjacentFlagRoot(mSideStage.mRootTaskInfo.token);
- mTaskOrganizer.applyTransaction(wct);
+ wct.setForceTranslucent(mRootTaskInfo.token, true);
+ mSplitLayout.getInvisibleBounds(mTempRect1);
+ wct.setBounds(mSideStage.mRootTaskInfo.token, mTempRect1);
+ mSyncQueue.queue(wct);
+ mSyncQueue.runInSync(t -> {
+ t.setPosition(mSideStage.mRootLeash, mTempRect1.left, mTempRect1.top);
+ });
}
private void onRootTaskVanished() {
@@ -1377,10 +1388,15 @@
// TODO (b/238697912) : Add the validation to prevent entering non-recovered status
final WindowContainerTransaction wct = new WindowContainerTransaction();
mSplitLayout.init();
- prepareEnterSplitScreen(wct);
+ mSplitLayout.setDividerAtBorder(mSideStagePosition == SPLIT_POSITION_TOP_OR_LEFT);
+ mMainStage.activate(wct, true /* includingTopTask */);
+ updateWindowBounds(mSplitLayout, wct);
+ wct.reorder(mRootTaskInfo.token, true);
+ wct.setForceTranslucent(mRootTaskInfo.token, false);
mSyncQueue.queue(wct);
- mSyncQueue.runInSync(t ->
- updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */));
+ mSyncQueue.runInSync(t -> {
+ mSplitLayout.flingDividerToCenter();
+ });
}
if (mMainStageListener.mHasChildren && mSideStageListener.mHasChildren) {
mShouldUpdateRecents = true;
@@ -1822,6 +1838,7 @@
// properly for the animation itself.
mSplitLayout.release();
mSplitLayout.resetDividerPosition();
+ mSideStagePosition = SPLIT_POSITION_BOTTOM_OR_RIGHT;
mTopStageAfterFoldDismiss = STAGE_TYPE_UNDEFINED;
}
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
index 95725bb..695550d 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/common/split/SplitLayoutTests.java
@@ -159,7 +159,8 @@
}
private void waitDividerFlingFinished() {
- verify(mSplitLayout).flingDividePosition(anyInt(), anyInt(), mRunnableCaptor.capture());
+ verify(mSplitLayout).flingDividePosition(anyInt(), anyInt(), anyInt(),
+ mRunnableCaptor.capture());
mRunnableCaptor.getValue().run();
}
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
index 62c83cf..51812f0 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothEventManager.java
@@ -367,8 +367,14 @@
if (bondState == BluetoothDevice.BOND_NONE) {
// Check if we need to remove other Coordinated set member devices / Hearing Aid
// devices
+ if (DEBUG) {
+ Log.d(TAG, "BondStateChangedHandler: cachedDevice.getGroupId() = "
+ + cachedDevice.getGroupId() + ", cachedDevice.getHiSyncId()= "
+ + cachedDevice.getHiSyncId());
+ }
if (cachedDevice.getGroupId() != BluetoothCsipSetCoordinator.GROUP_ID_INVALID
|| cachedDevice.getHiSyncId() != BluetoothHearingAid.HI_SYNC_ID_INVALID) {
+ Log.d(TAG, "BondStateChangedHandler: Start onDeviceUnpaired");
mDeviceManager.onDeviceUnpaired(cachedDevice);
}
int reason = intent.getIntExtra(BluetoothDevice.EXTRA_UNBOND_REASON,
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
index 32d5b78..3ca94db 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDevice.java
@@ -1431,11 +1431,10 @@
* first connected device in the coordinated set, and then switch the content of the main
* device and member devices.
*
- * @param prevMainDevice the previous Main device, it will be added into the member device set.
- * @param newMainDevice the new Main device, it will be removed from the member device set.
+ * @param newMainDevice the new Main device which is from the previous main device's member
+ * list.
*/
- public void switchMemberDeviceContent(CachedBluetoothDevice prevMainDevice,
- CachedBluetoothDevice newMainDevice) {
+ public void switchMemberDeviceContent(CachedBluetoothDevice newMainDevice) {
// Backup from main device
final BluetoothDevice tmpDevice = mDevice;
final short tmpRssi = mRssi;
@@ -1444,8 +1443,7 @@
mDevice = newMainDevice.mDevice;
mRssi = newMainDevice.mRssi;
mJustDiscovered = newMainDevice.mJustDiscovered;
- addMemberDevice(prevMainDevice);
- mMemberDevices.remove(newMainDevice);
+
// Set sub device from backup
newMainDevice.mDevice = tmpDevice;
newMainDevice.mRssi = tmpRssi;
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
index cd3242a..26a2080 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManager.java
@@ -17,6 +17,7 @@
package com.android.settingslib.bluetooth;
import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothProfile;
import android.content.Context;
@@ -317,12 +318,14 @@
}
public synchronized void onDeviceUnpaired(CachedBluetoothDevice device) {
+ device.setGroupId(BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
CachedBluetoothDevice mainDevice = mCsipDeviceManager.findMainDevice(device);
final Set<CachedBluetoothDevice> memberDevices = device.getMemberDevice();
if (!memberDevices.isEmpty()) {
// Main device is unpaired, to unpair the member device
for (CachedBluetoothDevice memberDevice : memberDevices) {
memberDevice.unpair();
+ memberDevice.setGroupId(BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
device.removeMemberDevice(memberDevice);
}
} else if (mainDevice != null) {
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
index fc70ba4..9b38238 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/CsipDeviceManager.java
@@ -231,7 +231,7 @@
// When both LE Audio devices are disconnected, receiving member device
// connection. To switch content and dispatch to notify UI change
mBtManager.getEventManager().dispatchDeviceRemoved(mainDevice);
- mainDevice.switchMemberDeviceContent(mainDevice, cachedDevice);
+ mainDevice.switchMemberDeviceContent(cachedDevice);
mainDevice.refresh();
// It is necessary to do remove and add for updating the mapping on
// preference and device
@@ -255,10 +255,11 @@
for (CachedBluetoothDevice device: memberSet) {
if (device.isConnected()) {
+ log("set device: " + device + " as the main device");
// Main device is disconnected and sub device is connected
// To copy data from sub device to main device
mBtManager.getEventManager().dispatchDeviceRemoved(cachedDevice);
- cachedDevice.switchMemberDeviceContent(device, cachedDevice);
+ cachedDevice.switchMemberDeviceContent(device);
cachedDevice.refresh();
// It is necessary to do remove and add for updating the mapping on
// preference and device
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
index bef1d9c..62552f91 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceManagerTest.java
@@ -25,6 +25,7 @@
import static org.mockito.Mockito.when;
import android.bluetooth.BluetoothClass;
+import android.bluetooth.BluetoothCsipSetCoordinator;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothUuid;
import android.content.Context;
@@ -518,7 +519,8 @@
*/
@Test
public void onDeviceUnpaired_unpairCsipMainDevice() {
- when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
+ when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
cachedDevice1.setGroupId(1);
@@ -527,7 +529,12 @@
// Call onDeviceUnpaired for the one in mCachedDevices.
mCachedDeviceManager.onDeviceUnpaired(cachedDevice1);
+
verify(mDevice2).removeBond();
+ assertThat(cachedDevice1.getGroupId()).isEqualTo(
+ BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
+ assertThat(cachedDevice2.getGroupId()).isEqualTo(
+ BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
}
/**
@@ -536,6 +543,7 @@
@Test
public void onDeviceUnpaired_unpairCsipSubDevice() {
when(mDevice1.getBondState()).thenReturn(BluetoothDevice.BOND_BONDED);
+ when(mDevice2.getBondState()).thenReturn(BluetoothDevice.BOND_NONE);
CachedBluetoothDevice cachedDevice1 = mCachedDeviceManager.addDevice(mDevice1);
CachedBluetoothDevice cachedDevice2 = mCachedDeviceManager.addDevice(mDevice2);
cachedDevice1.setGroupId(1);
@@ -544,7 +552,10 @@
// Call onDeviceUnpaired for the one in mCachedDevices.
mCachedDeviceManager.onDeviceUnpaired(cachedDevice2);
+
verify(mDevice1).removeBond();
+ assertThat(cachedDevice2.getGroupId()).isEqualTo(
+ BluetoothCsipSetCoordinator.GROUP_ID_INVALID);
}
/**
diff --git a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
index 76c066c..79e9938 100644
--- a/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
+++ b/packages/SettingsLib/tests/robotests/src/com/android/settingslib/bluetooth/CachedBluetoothDeviceTest.java
@@ -1050,4 +1050,23 @@
assertThat(mCachedDevice.mDrawableCache.size()).isEqualTo(0);
}
+
+ @Test
+ public void switchMemberDeviceContent_switchMainDevice_switchesSuccessful() {
+ mCachedDevice.mRssi = RSSI_1;
+ mCachedDevice.mJustDiscovered = JUSTDISCOVERED_1;
+ mSubCachedDevice.mRssi = RSSI_2;
+ mSubCachedDevice.mJustDiscovered = JUSTDISCOVERED_2;
+ mCachedDevice.addMemberDevice(mSubCachedDevice);
+
+ mCachedDevice.switchMemberDeviceContent(mSubCachedDevice);
+
+ assertThat(mCachedDevice.mRssi).isEqualTo(RSSI_2);
+ assertThat(mCachedDevice.mJustDiscovered).isEqualTo(JUSTDISCOVERED_2);
+ assertThat(mCachedDevice.mDevice).isEqualTo(mSubDevice);
+ assertThat(mSubCachedDevice.mRssi).isEqualTo(RSSI_1);
+ assertThat(mSubCachedDevice.mJustDiscovered).isEqualTo(JUSTDISCOVERED_1);
+ assertThat(mSubCachedDevice.mDevice).isEqualTo(mDevice);
+ assertThat(mCachedDevice.getMemberDevice().contains(mSubCachedDevice)).isTrue();
+ }
}
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index abcd65b..7649de6 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -94,6 +94,7 @@
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.MANAGE_SENSOR_PRIVACY" />
<uses-permission android:name="android.permission.OBSERVE_SENSOR_PRIVACY" />
+ <uses-permission android:name="android.permission.ACCESS_AMBIENT_CONTEXT_EVENT" />
<!-- ActivityManager -->
<uses-permission android:name="android.permission.REAL_GET_TASKS" />
diff --git a/packages/SystemUI/ktfmt_includes.txt b/packages/SystemUI/ktfmt_includes.txt
new file mode 100644
index 0000000..3ca8dfe
--- /dev/null
+++ b/packages/SystemUI/ktfmt_includes.txt
@@ -0,0 +1,870 @@
++packages/SystemUI
+-packages/SystemUI/animation/src/com/android/systemui/animation/FontInterpolator.kt
+-packages/SystemUI/animation/src/com/android/systemui/animation/GhostedViewLaunchAnimatorController.kt
+-packages/SystemUI/animation/src/com/android/systemui/animation/TextAnimator.kt
+-packages/SystemUI/animation/src/com/android/systemui/animation/TextInterpolator.kt
+-packages/SystemUI/animation/src/com/android/systemui/animation/ViewHierarchyAnimator.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/BindServiceViaContextDetector.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/BroadcastSentViaContextDetector.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/GetMainLooperViaContextDetector.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/RegisterReceiverViaContextDetector.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/SoftwareBitmapDetector.kt
+-packages/SystemUI/checks/src/com/android/internal/systemui/lint/SystemUIIssueRegistry.kt
+-packages/SystemUI/checks/tests/com/android/systemui/lint/BindServiceViaContextDetectorTest.kt
+-packages/SystemUI/checks/tests/com/android/systemui/lint/BroadcastSentViaContextDetectorTest.kt
+-packages/SystemUI/checks/tests/com/android/systemui/lint/GetMainLooperViaContextDetectorTest.kt
+-packages/SystemUI/checks/tests/com/android/systemui/lint/RegisterReceiverViaContextDetectorTest.kt
+-packages/SystemUI/checks/tests/com/android/systemui/lint/SoftwareBitmapDetectorTest.kt
+-packages/SystemUI/monet/src/com/android/systemui/monet/ColorScheme.kt
+-packages/SystemUI/plugin/src/com/android/systemui/plugins/ClockProviderPlugin.kt
+-packages/SystemUI/plugin/src/com/android/systemui/plugins/qs/QSContainerController.kt
+-packages/SystemUI/shared/src/com/android/systemui/flags/Flag.kt
+-packages/SystemUI/shared/src/com/android/systemui/flags/FlagListenable.kt
+-packages/SystemUI/shared/src/com/android/systemui/flags/FlagManager.kt
+-packages/SystemUI/shared/src/com/android/systemui/flags/FlagSerializer.kt
+-packages/SystemUI/shared/src/com/android/systemui/flags/FlagSettingsHelper.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimator.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/clocks/AnimatableClockView.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/clocks/ClockRegistry.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/clocks/DefaultClockProvider.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionDarkness.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/regionsampling/RegionSamplingInstance.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/rotation/FloatingRotationButtonPositionCalculator.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/system/UncaughtExceptionPreHandlerManager.kt
+-packages/SystemUI/shared/src/com/android/systemui/shared/system/smartspace/SmartspaceState.kt
+-packages/SystemUI/shared/src/com/android/systemui/unfold/system/ActivityManagerActivityTypeProvider.kt
+-packages/SystemUI/shared/src/com/android/systemui/unfold/system/DeviceStateManagerFoldProvider.kt
+-packages/SystemUI/shared/src/com/android/systemui/unfold/system/SystemUnfoldSharedModule.kt
+-packages/SystemUI/src-debug/com/android/systemui/flags/FlagsModule.kt
+-packages/SystemUI/src-release/com/android/systemui/flags/FlagsModule.kt
+-packages/SystemUI/src/com/android/keyguard/ActiveUnlockConfig.kt
+-packages/SystemUI/src/com/android/keyguard/BouncerPanelExpansionCalculator.kt
+-packages/SystemUI/src/com/android/keyguard/KeyguardBiometricLockoutLogger.kt
+-packages/SystemUI/src/com/android/keyguard/KeyguardListenModel.kt
+-packages/SystemUI/src/com/android/keyguard/KeyguardListenQueue.kt
+-packages/SystemUI/src/com/android/keyguard/KeyguardUnfoldTransition.kt
+-packages/SystemUI/src/com/android/keyguard/KeyguardUserSwitcherAnchor.kt
+-packages/SystemUI/src/com/android/keyguard/clock/ClockPalette.kt
+-packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+-packages/SystemUI/src/com/android/keyguard/mediator/ScreenOnCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/BootCompleteCache.kt
+-packages/SystemUI/src/com/android/systemui/BootCompleteCacheImpl.kt
+-packages/SystemUI/src/com/android/systemui/CameraAvailabilityListener.kt
+-packages/SystemUI/src/com/android/systemui/ChooserSelector.kt
+-packages/SystemUI/src/com/android/systemui/DarkReceiverImpl.kt
+-packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
+-packages/SystemUI/src/com/android/systemui/DualToneHandler.kt
+-packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
+-packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
+-packages/SystemUI/src/com/android/systemui/SystemUIAppComponentFactoryBase.kt
+-packages/SystemUI/src/com/android/systemui/SystemUIInitializerFactory.kt
+-packages/SystemUI/src/com/android/systemui/SystemUIInitializerImpl.kt
+-packages/SystemUI/src/com/android/systemui/assist/AssistLogger.kt
+-packages/SystemUI/src/com/android/systemui/assist/AssistantInvocationEvent.kt
+-packages/SystemUI/src/com/android/systemui/assist/AssistantSessionEvent.kt
+-packages/SystemUI/src/com/android/systemui/backup/BackupHelper.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AlternateUdfpsTouchProvider.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceIconController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFaceView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceIconController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricIconController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/AuthRippleView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/BiometricDisplayListener.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/DwellRippleShader.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/SidefpsController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsAnimationViewController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsBpViewController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsControllerOverlay.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsDrawable.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpDrawable.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsFpmOtherViewController.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsHapticsSimulator.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsOverlayParams.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsShell.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/UdfpsView.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
+-packages/SystemUI/src/com/android/systemui/biometrics/dagger/BiometricsModule.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/ActionReceiver.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcher.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/BroadcastDispatcherStartable.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/BroadcastSender.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/PendingRemovalStore.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/UserBroadcastDispatcher.kt
+-packages/SystemUI/src/com/android/systemui/broadcast/logging/BroadcastDispatcherLogger.kt
+-packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
+-packages/SystemUI/src/com/android/systemui/camera/CameraIntents.kt
+-packages/SystemUI/src/com/android/systemui/camera/CameraIntentsWrapper.kt
+-packages/SystemUI/src/com/android/systemui/charging/WiredChargingRippleController.kt
+-packages/SystemUI/src/com/android/systemui/controls/ControlStatus.kt
+-packages/SystemUI/src/com/android/systemui/controls/ControlsMetricsLogger.kt
+-packages/SystemUI/src/com/android/systemui/controls/ControlsMetricsLoggerImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/ControlsServiceInfo.kt
+-packages/SystemUI/src/com/android/systemui/controls/CustomIconCache.kt
+-packages/SystemUI/src/com/android/systemui/controls/TooltipManager.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapper.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlInfo.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingController.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsBindingControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsController.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapper.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManager.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsTileResourceConfiguration.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/ServiceWrapper.kt
+-packages/SystemUI/src/com/android/systemui/controls/controller/StatefulControlSubscriber.kt
+-packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsComponent.kt
+-packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsFeatureEnabled.kt
+-packages/SystemUI/src/com/android/systemui/controls/dagger/ControlsModule.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/AllModel.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/AppAdapter.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlAdapter.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsAnimations.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsEditingActivity.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsFavoritingActivity.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingController.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsListingControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsModel.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsProviderSelectorActivity.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestDialog.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ControlsRequestReceiver.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/FavoritesModel.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/ManagementPageIndicator.kt
+-packages/SystemUI/src/com/android/systemui/controls/management/StructureAdapter.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/Behavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ChallengeDialogs.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlActionCoordinatorImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlViewHolder.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlWithState.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/CornerDrawable.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/DetailDialog.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/RenderInfo.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/StatusBehavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/TemperatureControlBehavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ThumbnailBehavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ToggleBehavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/ToggleRangeBehavior.kt
+-packages/SystemUI/src/com/android/systemui/controls/ui/TouchBehavior.kt
+-packages/SystemUI/src/com/android/systemui/dagger/SystemUICoreStartableModule.kt
+-packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt
+-packages/SystemUI/src/com/android/systemui/decor/DecorProviderFactory.kt
+-packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt
+-packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt
+-packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt
+-packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderFactory.kt
+-packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt
+-packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt
+-packages/SystemUI/src/com/android/systemui/demomode/DemoModeAvailabilityTracker.kt
+-packages/SystemUI/src/com/android/systemui/demomode/DemoModeController.kt
+-packages/SystemUI/src/com/android/systemui/doze/DozeLogger.kt
+-packages/SystemUI/src/com/android/systemui/doze/util/BurnInHelper.kt
+-packages/SystemUI/src/com/android/systemui/dreams/smartspace/DreamSmartspaceController.kt
+-packages/SystemUI/src/com/android/systemui/dump/DumpHandler.kt
+-packages/SystemUI/src/com/android/systemui/dump/DumpManager.kt
+-packages/SystemUI/src/com/android/systemui/dump/DumpsysTableLogger.kt
+-packages/SystemUI/src/com/android/systemui/dump/LogBufferEulogizer.kt
+-packages/SystemUI/src/com/android/systemui/dump/LogBufferFreezer.kt
+-packages/SystemUI/src/com/android/systemui/flags/FeatureFlags.kt
+-packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt
+-packages/SystemUI/src/com/android/systemui/flags/SystemPropertiesHelper.kt
+-packages/SystemUI/src/com/android/systemui/keyguard/KeyguardUnlockAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/log/LogBuffer.kt
+-packages/SystemUI/src/com/android/systemui/log/LogBufferFactory.kt
+-packages/SystemUI/src/com/android/systemui/log/LogLevel.kt
+-packages/SystemUI/src/com/android/systemui/log/LogMessage.kt
+-packages/SystemUI/src/com/android/systemui/log/LogMessageImpl.kt
+-packages/SystemUI/src/com/android/systemui/log/LogcatEchoTracker.kt
+-packages/SystemUI/src/com/android/systemui/log/LogcatEchoTrackerDebug.kt
+-packages/SystemUI/src/com/android/systemui/log/LogcatEchoTrackerProd.kt
+-packages/SystemUI/src/com/android/systemui/media/AnimationBindHandler.kt
+-packages/SystemUI/src/com/android/systemui/media/ColorSchemeTransition.kt
+-packages/SystemUI/src/com/android/systemui/media/GutsViewHolder.kt
+-packages/SystemUI/src/com/android/systemui/media/IlluminationDrawable.kt
+-packages/SystemUI/src/com/android/systemui/media/KeyguardMediaController.kt
+-packages/SystemUI/src/com/android/systemui/media/LightSourceDrawable.kt
+-packages/SystemUI/src/com/android/systemui/media/LocalMediaManagerFactory.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaCarouselController.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaCarouselControllerLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaCarouselScrollHandler.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaData.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaDataCombineLatest.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaDataFilter.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaDataManager.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaDeviceManager.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaFeatureFlag.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaFlags.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaHierarchyManager.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaHost.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaHostStatesManager.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaProjectionAppSelectorActivity.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaProjectionCaptureTarget.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaResumeListener.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaScrollView.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaSessionBasedFilter.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaTimeoutListener.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaTimeoutLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaUiEventLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaViewController.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaViewHolder.kt
+-packages/SystemUI/src/com/android/systemui/media/MediaViewLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/MetadataAnimationHandler.kt
+-packages/SystemUI/src/com/android/systemui/media/RecommendationViewHolder.kt
+-packages/SystemUI/src/com/android/systemui/media/ResumeMediaBrowserLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/SeekBarObserver.kt
+-packages/SystemUI/src/com/android/systemui/media/SeekBarViewModel.kt
+-packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaData.kt
+-packages/SystemUI/src/com/android/systemui/media/SmartspaceMediaDataProvider.kt
+-packages/SystemUI/src/com/android/systemui/media/SquigglyProgress.kt
+-packages/SystemUI/src/com/android/systemui/media/dagger/MediaProjectionModule.kt
+-packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBroadcastDialogFactory.kt
+-packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogFactory.kt
+-packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputDialogReceiver.kt
+-packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionCli.kt
+-packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManager.kt
+-packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerFactory.kt
+-packages/SystemUI/src/com/android/systemui/media/muteawait/MediaMuteAwaitLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/nearby/NearbyMediaDevicesLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/nearby/NearbyMediaDevicesManager.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelper.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/MediaTttFlags.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/ChipInfoCommon.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommon.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ChipStateReceiver.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttReceiverLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/ReceiverChipRippleView.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/ChipStateSender.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSender.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderLogger.kt
+-packages/SystemUI/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLogger.kt
+-packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanel.kt
+-packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+-packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
+-packages/SystemUI/src/com/android/systemui/power/BatteryStateSnapshot.kt
+-packages/SystemUI/src/com/android/systemui/privacy/AppOpsPrivacyItemMonitor.kt
+-packages/SystemUI/src/com/android/systemui/privacy/MediaProjectionPrivacyItemMonitor.kt
+-packages/SystemUI/src/com/android/systemui/privacy/OngoingPrivacyChip.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipBuilder.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyChipEvent.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyConfig.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialog.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogController.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyDialogEvent.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyItem.kt
+-packages/SystemUI/src/com/android/systemui/privacy/PrivacyItemController.kt
+-packages/SystemUI/src/com/android/systemui/privacy/logging/PrivacyLogger.kt
+-packages/SystemUI/src/com/android/systemui/qs/AutoAddTracker.kt
+-packages/SystemUI/src/com/android/systemui/qs/FgsManagerController.kt
+-packages/SystemUI/src/com/android/systemui/qs/FooterActionsController.kt
+-packages/SystemUI/src/com/android/systemui/qs/FooterActionsView.kt
+-packages/SystemUI/src/com/android/systemui/qs/HeaderPrivacyIconsController.kt
+-packages/SystemUI/src/com/android/systemui/qs/QSEvents.kt
+-packages/SystemUI/src/com/android/systemui/qs/QSExpansionPathInterpolator.kt
+-packages/SystemUI/src/com/android/systemui/qs/QSFragmentDisableFlagsLogger.kt
+-packages/SystemUI/src/com/android/systemui/qs/QSSquishinessController.kt
+-packages/SystemUI/src/com/android/systemui/qs/QSUtils.kt
+-packages/SystemUI/src/com/android/systemui/qs/SideLabelTileLayout.kt
+-packages/SystemUI/src/com/android/systemui/qs/VisibilityChangedDispatcher.kt
+-packages/SystemUI/src/com/android/systemui/qs/carrier/CellSignalState.kt
+-packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.kt
+-packages/SystemUI/src/com/android/systemui/qs/external/CustomTileStatePersister.kt
+-packages/SystemUI/src/com/android/systemui/qs/external/QSExternalModule.kt
+-packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialog.kt
+-packages/SystemUI/src/com/android/systemui/qs/external/TileRequestDialogEventLogger.kt
+-packages/SystemUI/src/com/android/systemui/qs/external/TileServiceRequestController.kt
+-packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
+-packages/SystemUI/src/com/android/systemui/qs/tileimpl/HeightOverrideable.kt
+-packages/SystemUI/src/com/android/systemui/qs/tileimpl/IgnorableChildLinearLayout.kt
+-packages/SystemUI/src/com/android/systemui/qs/tileimpl/QSTileViewImpl.kt
+-packages/SystemUI/src/com/android/systemui/qs/tiles/AlarmTile.kt
+-packages/SystemUI/src/com/android/systemui/qs/tiles/DeviceControlsTile.kt
+-packages/SystemUI/src/com/android/systemui/qs/tiles/dialog/InternetDialogFactory.kt
+-packages/SystemUI/src/com/android/systemui/qs/user/UserSwitchDialogController.kt
+-packages/SystemUI/src/com/android/systemui/ripple/RippleShader.kt
+-packages/SystemUI/src/com/android/systemui/ripple/RippleShaderUtilLibrary.kt
+-packages/SystemUI/src/com/android/systemui/ripple/RippleView.kt
+-packages/SystemUI/src/com/android/systemui/ripple/SdfShaderLibrary.kt
+-packages/SystemUI/src/com/android/systemui/screenshot/ImageCaptureImpl.kt
+-packages/SystemUI/src/com/android/systemui/screenshot/RequestProcessor.kt
+-packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicy.kt
+-packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotPolicyImpl.kt
+-packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotProxyService.kt
+-packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseDialog.kt
+-packages/SystemUI/src/com/android/systemui/sensorprivacy/SensorUseStartedActivity.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserContentResolverProvider.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserContextProvider.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserFileManager.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserFileManagerImpl.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserTracker.kt
+-packages/SystemUI/src/com/android/systemui/settings/UserTrackerImpl.kt
+-packages/SystemUI/src/com/android/systemui/settings/brightness/BrightnessMirrorHandler.kt
+-packages/SystemUI/src/com/android/systemui/settings/brightness/MirroredBrightnessController.kt
+-packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManager.kt
+-packages/SystemUI/src/com/android/systemui/shade/CombinedShadeHeadersConstraintManagerImpl.kt
+-packages/SystemUI/src/com/android/systemui/shade/LargeScreenShadeHeaderController.kt
+-packages/SystemUI/src/com/android/systemui/shade/NPVCDownEventState.kt
+-packages/SystemUI/src/com/android/systemui/shade/NotifPanelEvents.kt
+-packages/SystemUI/src/com/android/systemui/shade/NotificationPanelUnfoldAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/shade/NotificationsQSContainerController.kt
+-packages/SystemUI/src/com/android/systemui/shade/PulsingGestureListener.kt
+-packages/SystemUI/src/com/android/systemui/shade/ShadeLogger.kt
+-packages/SystemUI/src/com/android/systemui/shade/transition/ScrimShadeTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/shade/transition/ShadeTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/shade/transition/SplitShadeOverScroller.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/SmartspacePrecondition.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/SmartspaceTargetFilter.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceModule.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/dagger/SmartspaceViewComponent.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/filters/LockscreenAndDreamTargetFilter.kt
+-packages/SystemUI/src/com/android/systemui/smartspace/preconditions/LockscreenPrecondition.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/AbstractLockscreenShadeTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/ActionClickLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/BaseStatusBarWifiView.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/BlurUtils.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/DisableFlagsLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/LightRevealScrim.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/LockScreenShadeOverScroller.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeKeyguardTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeScrimTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/LockscreenShadeTransitionController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/MediaArtworkProcessor.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/NotificationClickNotifier.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/NotificationShadeDepthController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/PulseExpansionHandler.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScroller.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScroller.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/commandline/CommandRegistry.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/AccessPointController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/ConnectivityState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileSignalControllerFactory.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/MobileStatusTrackerFactory.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/SignalCallback.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/connectivity/WifiStatusTrackerFactory.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/core/StatusBarInitializer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/dagger/StartCentralSurfacesModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/PrivacyDotViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/StatusEvent.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventChipAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/SystemEventCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/events/SystemStatusAnimationScheduler.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/gesture/GenericGestureDetector.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureHandler.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/gesture/SwipeStatusBarAwayGestureLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/gesture/TapGestureDetector.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/ConversationNotifications.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/FeedbackIcon.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/LaunchAnimationParameters.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotifPipelineFlags.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationClickerLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationEntryManagerLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationUtils.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/ViewGroupFadeHelper.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/ListAttachState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipeline.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/PipelineDumper.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/SuppressedAttachState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolver.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coalescer/GroupCoalescerLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/DebugModeCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GutsCoordinatorLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/NotifCoordinators.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/PreparationCoordinatorLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinatorLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/dagger/CoordinatorsModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/BindEventManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/BindEventManagerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifInflater.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustment.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/NotifSection.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/ShadeListBuilderLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/listbuilder/pluggable/NotifStabilityManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTracker.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifEvent.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtender.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/DebugModeFilterProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/NotificationVisibilityProviderImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionHeaderVisibilityProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/provider/SectionStyleProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/MediaContainerController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilder.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifGroupController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifGutsViewListener.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifGutsViewManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifRowController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifShadeEventSource.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifStackController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewBarn.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotifViewRenderer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/NotificationVisibilityProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RenderExtensions.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/RootNodeController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/SectionHeaderController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDiffer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewDifferLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/render/ShadeViewManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/dagger/NotificationSectionHeadersModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconBuilder.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/icon/IconManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerStub.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/HeadsUpViewBinderLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/KeyguardNotificationVisibilityProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/people/NotificationPersonExtractor.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/people/PeopleNotificationIdentifier.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/people/ViewPipeline.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ChannelEditorListView.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotifBindPipelineLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/RowContentBindStageLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/dagger/RemoteInputViewModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationCallTemplateViewWrapper.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/row/wrapper/NotificationConversationTemplateViewWrapper.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/MediaContainerView.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationPriorityBucket.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationSectionsManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackStateLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ConfigurationControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBypassController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardLiftController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/LSShadeTransitionLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ScreenOffAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProvider.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarHideIconsForBouncerManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLaunchAnimatorController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarLocationPublisher.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarNotificationActivityStarterLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/SystemBarAttributesListener.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarIconBlocklist.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/StatusBarSystemEventAnimator.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallChronometer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallFlags.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManager.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/panelstate/PanelStateListener.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserInfoTracker.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherContainer.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherFeatureController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/ConnectivityInfoProcessor.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/dagger/StatusBarPipelineModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiActivityModel.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/model/WifiNetworkModel.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractor.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/shared/WifiConstants.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiView.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModel.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/BatteryStateNotifier.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/HeadsUpManagerLogger.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplyState.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/InflatedSmartReplyViewHolder.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisabler.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/SmartReplyStateInflater.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/VariableDateView.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/VariableDateViewController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/WalletController.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/WalletControllerImpl.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/RemoteInput.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/policy/dagger/SmartRepliesInflationModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/tv/VpnStatusObserver.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowModule.kt
+-packages/SystemUI/src/com/android/systemui/statusbar/window/StatusBarWindowStateController.kt
+-packages/SystemUI/src/com/android/systemui/toast/ToastDefaultAnimation.kt
+-packages/SystemUI/src/com/android/systemui/toast/ToastLogger.kt
+-packages/SystemUI/src/com/android/systemui/tv/TVSystemUICoreStartableModule.kt
+-packages/SystemUI/src/com/android/systemui/unfold/FoldStateLogger.kt
+-packages/SystemUI/src/com/android/systemui/unfold/SysUIUnfoldModule.kt
+-packages/SystemUI/src/com/android/systemui/unfold/UnfoldLatencyTracker.kt
+-packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
+-packages/SystemUI/src/com/android/systemui/unfold/UnfoldProgressProvider.kt
+-packages/SystemUI/src/com/android/systemui/user/UserCreator.kt
+-packages/SystemUI/src/com/android/systemui/user/UserSwitcherActivity.kt
+-packages/SystemUI/src/com/android/systemui/user/UserSwitcherPopupMenu.kt
+-packages/SystemUI/src/com/android/systemui/user/UserSwitcherRootView.kt
+-packages/SystemUI/src/com/android/systemui/util/AsyncActivityLauncher.kt
+-packages/SystemUI/src/com/android/systemui/util/ColorUtil.kt
+-packages/SystemUI/src/com/android/systemui/util/ConvenienceExtensions.kt
+-packages/SystemUI/src/com/android/systemui/util/DelayableMarqueeTextView.kt
+-packages/SystemUI/src/com/android/systemui/util/DumpUtils.kt
+-packages/SystemUI/src/com/android/systemui/util/InitializationChecker.kt
+-packages/SystemUI/src/com/android/systemui/util/LargeScreenUtils.kt
+-packages/SystemUI/src/com/android/systemui/util/ListenerSet.kt
+-packages/SystemUI/src/com/android/systemui/util/NeverExactlyLinearLayout.kt
+-packages/SystemUI/src/com/android/systemui/util/NoRemeasureMotionLayout.kt
+-packages/SystemUI/src/com/android/systemui/util/PluralMessageFormater.kt
+-packages/SystemUI/src/com/android/systemui/util/RingerModeTracker.kt
+-packages/SystemUI/src/com/android/systemui/util/RingerModeTrackerImpl.kt
+-packages/SystemUI/src/com/android/systemui/util/RoundedCornerProgressDrawable.kt
+-packages/SystemUI/src/com/android/systemui/util/SafeMarqueeTextView.kt
+-packages/SystemUI/src/com/android/systemui/util/SparseArrayUtils.kt
+-packages/SystemUI/src/com/android/systemui/util/TraceUtils.kt
+-packages/SystemUI/src/com/android/systemui/util/UserAwareController.kt
+-packages/SystemUI/src/com/android/systemui/util/WallpaperController.kt
+-packages/SystemUI/src/com/android/systemui/util/animation/AnimationUtil.kt
+-packages/SystemUI/src/com/android/systemui/util/animation/MeasurementInput.kt
+-packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayout.kt
+-packages/SystemUI/src/com/android/systemui/util/animation/TransitionLayoutController.kt
+-packages/SystemUI/src/com/android/systemui/util/animation/UniqueObjectHostView.kt
+-packages/SystemUI/src/com/android/systemui/util/collection/RingBuffer.kt
+-packages/SystemUI/src/com/android/systemui/util/concurrency/Execution.kt
+-packages/SystemUI/src/com/android/systemui/util/concurrency/PendingTasksContainer.kt
+-packages/SystemUI/src/com/android/systemui/util/drawable/DrawableSize.kt
+-packages/SystemUI/src/com/android/systemui/util/kotlin/CoroutinesModule.kt
+-packages/SystemUI/src/com/android/systemui/util/kotlin/Flow.kt
+-packages/SystemUI/src/com/android/systemui/util/kotlin/IpcSerializer.kt
+-packages/SystemUI/src/com/android/systemui/util/kotlin/nullability.kt
+-packages/SystemUI/src/com/android/systemui/util/view/ViewUtil.kt
+-packages/SystemUI/src/com/android/systemui/util/wrapper/RotationPolicyWrapper.kt
+-packages/SystemUI/src/com/android/systemui/volume/VolumePanelDialogReceiver.kt
+-packages/SystemUI/src/com/android/systemui/volume/VolumePanelFactory.kt
+-packages/SystemUI/tests/src/com/android/keyguard/ActiveUnlockConfigTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/BouncerPanelExpansionCalculatorTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardBiometricLockoutLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardListenQueueTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardPasswordViewControllerTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardPatternViewControllerTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardStatusViewTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/KeyguardUserSwitcherAnchorTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/clock/ClockPaletteTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/clock/ViewPreviewerTest.kt
+-packages/SystemUI/tests/src/com/android/keyguard/mediator/ScreenOnCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/BootCompleteCacheTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/ChooserSelectorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/DisplayCutoutBaseViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/InstanceIdSequenceFake.kt
+-packages/SystemUI/tests/src/com/android/systemui/ScreenDecorHwcLayerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/DialogLaunchAnimatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/FontInterpolatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/GhostedViewLaunchAnimatorControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/TextAnimatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/TextInterpolatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/animation/ViewHierarchyAnimatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/battery/BatteryMeterViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintAndFaceViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthContainerViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthRippleControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/BiometricTestExtensions.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/SidefpsControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerOverlayTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/broadcast/ActionReceiverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastDispatcherTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/broadcast/BroadcastSenderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/broadcast/PendingRemovalStoreTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/broadcast/UserBroadcastDispatcherTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/camera/CameraGestureHelperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/camera/CameraIntentsTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/charging/WiredChargingRippleControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/CustomIconCacheTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/AuxiliaryPersistenceWrapperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlActionCoordinatorImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsBindingControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsFavoritePersistenceWrapperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsProviderLifecycleManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ControlsTileResourceConfigurationImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/DeletionJobServiceTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/ServiceWrapperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/controller/StatefulControlSubscriberTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/dagger/ControlsComponentTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/AllModelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/AppAdapterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsListingControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestDialogTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/ControlsRequestReceiverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/FavoritesModelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/management/TestControlsRequestDialog.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlViewHolderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/controls/ui/DetailDialogTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/decor/PrivacyDotDecorProviderFactoryTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerDecorProviderFactoryTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/decor/RoundedCornerResDelegateTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/dump/DumpHandlerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/dump/DumpsysTableLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferFreezerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/dump/LogBufferHelper.kt
+-packages/SystemUI/tests/src/com/android/systemui/dump/LogEulogizerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/flags/FlagManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/keyguard/KeyguardUnlockAnimationControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/lifecycle/InstantTaskExecutorRule.kt
+-packages/SystemUI/tests/src/com/android/systemui/log/LogBufferTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/AnimationBindHandlerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/ColorSchemeTransitionTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/KeyguardMediaControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaCarouselControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaControlPanelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaDataFilterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaDataManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaDeviceManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaHierarchyManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaPlayerDataTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaResumeListenerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaSessionBasedFilterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaTestUtils.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MediaTimeoutListenerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/MetadataAnimationHandlerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/ResumeMediaBrowserTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/SeekBarObserverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/SeekBarViewModelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/SmartspaceMediaDataTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/SquigglyProgressTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/muteawait/MediaMuteAwaitConnectionManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/nearby/NearbyMediaDevicesManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/MediaTttCommandLineHelperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttChipControllerCommonTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttChipControllerSenderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/sender/MediaTttSenderUiEventLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/FloatingRotationButtonPositionCalculatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/AppOpsPrivacyItemMonitorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyChipBuilderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyConfigFlagsTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyDialogTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/privacy/PrivacyItemControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/FooterActionsControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/HeaderPrivacyIconsControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSContainerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSFragmentDisableFlagsLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelSwitchToParentTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSPanelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QSSquishinessControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QuickQSPanelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/QuickStatusBarHeaderControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/SettingObserverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/carrier/CellSignalStateTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileStatePersisterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/external/CustomTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogEventLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/external/TileRequestDialogTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServiceRequestControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSFactoryImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/QSTileViewImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/ResourceIconTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tileimpl/TilesStatesTextTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AirplaneModeTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/AlarmTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BatterySaverTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/BluetoothTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/CameraToggleTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DeviceControlsTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/DndTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/MicrophoneToggleTileTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/tiles/UserDetailViewAdapterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/qs/user/UserSwitchDialogControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/ripple/RippleViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/screenrecord/ScreenRecordDialogTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/screenshot/ImageCaptureImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/screenshot/RequestProcessorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/screenshot/TakeScreenshotServiceTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/settings/UserFileManagerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/settings/UserTrackerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/settings/brightness/BrightnessSliderControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/CombinedShadeHeaderConstraintsTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerCombinedTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/LargeScreenShadeHeaderControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/NotificationQSContainerControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/PulsingGestureListenerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/transition/ScrimShadeTransitionControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/transition/ShadeTransitionControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shade/transition/SplitShadeOverScrollerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldConstantTranslateAnimatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/navigationbar/RegionSamplingHelperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/regionsampling/RegionSamplingInstanceTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/rotation/RotationButtonControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/shared/system/UncaughtExceptionPreHandlerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/smartspace/DreamSmartspaceControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenAndDreamTargetFilterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/smartspace/LockscreenPreconditionTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/BlurUtilsTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/DisableFlagsLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/LSShadeTransitionLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/LightRevealScrimTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/LockscreenShadeTransitionControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/MediaArtworkProcessorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationShadeDepthControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/SingleShadeLockScreenOverScrollerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/SplitShadeLockScreenOverScrollerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateEventTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/VibratorHelperTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/commandline/CommandRegistryTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/connectivity/AccessPointControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/gesture/GenericGestureDetectorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/lockscreen/LockscreenSmartspaceControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationLaunchAnimatorControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationSectionsFeatureManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifLiveDataStoreImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/NotifPipelineChoreographerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/TargetSdkResolverTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ConversationCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/DataStoreCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/HeadsUpCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/KeyguardCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RemoteInputCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/RowAppearanceCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SensitiveContentCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ShadeEventCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/SmartspaceDedupingCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/StackCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/coordinator/ViewConfigCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/inflation/NotifUiAdjustmentProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/NotifCollectionInconsistencyTrackerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/notifcollection/SelfTrackingLifetimeExtenderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/provider/VisualStabilityProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/NodeSpecBuilderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/collection/render/RenderStageManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/icon/IconManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ActivatableNotificationViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/ChannelEditorDialogControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationGutsTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/MediaContainerViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationShelfTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/NotificationStackSizeCalculatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ConfigurationControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/FoldStateListenerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxAppearanceCalculatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/LetterboxBackgroundProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/NotificationIconContainerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarContentInsetsProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarMoveFromCenterAnimationControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/SystemBarAttributesListenerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/UnlockedScreenOffAnimationControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallChronometerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/ongoingcall/OngoingCallLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/panelstate/PanelExpansionStateManagerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/userswitcher/StatusBarUserSwitcherControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/shared/ConnectivityPipelineLoggerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/domain/interactor/WifiInteractorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/view/ModernStatusBarWifiViewTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/ui/viewmodel/WifiViewModelTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/BatteryStateNotifierTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/ClockTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceControlsControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceProvisionedControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/FlashlightControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardQsUserSwitchControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/KeyguardUserSwitcherAdapterTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/RemoteInputQuickSettingsDisablerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/SafetyControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/UserSwitcherControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/VariableDateViewControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/WalletControllerImplTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/statusbar/window/StatusBarWindowStateControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/FoldStateLoggingProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldLatencyTrackerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/UnfoldTransitionWallpaperControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfigTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/updates/DeviceFoldStateProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/util/FoldableTestUtils.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/util/NaturalRotationUnfoldProgressProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/util/ScaleAwareUnfoldProgressProviderTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/unfold/util/TestFoldStateProvider.kt
+-packages/SystemUI/tests/src/com/android/systemui/usb/UsbPermissionActivityTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/user/UserCreatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/user/UserSwitcherActivityTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/FakeSharedPreferencesTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/FloatingContentCoordinatorTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/ListenerSetTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/RingerModeLiveDataTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/WallpaperControllerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/animation/AnimationUtilTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/collection/RingBufferTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/drawable/DrawableSizeTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/kotlin/FlowUtilTests.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/kotlin/IpcSerializerTest.kt
+-packages/SystemUI/tests/src/com/android/systemui/util/view/ViewUtilTest.kt
+-packages/SystemUI/tests/utils/src/com/android/systemui/broadcast/FakeBroadcastDispatcher.kt
+-packages/SystemUI/tests/utils/src/com/android/systemui/flags/FakeFeatureFlags.kt
+-packages/SystemUI/tests/utils/src/com/android/systemui/util/FakeSharedPreferences.kt
+-packages/SystemUI/tests/utils/src/com/android/systemui/util/mockito/KotlinMockitoHelpers.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldSharedModule.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/UnfoldTransitionFactory.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/ScreenSizeFoldProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/compat/SizeScreenStatusProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/config/ResourceUnfoldTransitionConfig.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldBackground.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/dagger/UnfoldMain.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/DeviceFoldStateProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/FoldStateProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/hinge/HingeSensorAngleProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/updates/screen/ScreenStatusProvider.kt
+-packages/SystemUI/unfold/src/com/android/systemui/unfold/util/ScaleAwareTransitionProgressProvider.kt
diff --git a/packages/SystemUI/res/values/ids.xml b/packages/SystemUI/res/values/ids.xml
index dca5ea8..f88f46f 100644
--- a/packages/SystemUI/res/values/ids.xml
+++ b/packages/SystemUI/res/values/ids.xml
@@ -131,7 +131,11 @@
<!-- For StatusIconContainer to tag its icon views -->
<item type="id" name="status_bar_view_state_tag" />
+ <!-- Default display cutout on the physical top of screen -->
<item type="id" name="display_cutout" />
+ <item type="id" name="display_cutout_left" />
+ <item type="id" name="display_cutout_right" />
+ <item type="id" name="display_cutout_bottom" />
<item type="id" name="row_tag_for_content_view" />
diff --git a/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt b/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
index d2c229b..a3351e1 100644
--- a/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
+++ b/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
@@ -47,7 +47,8 @@
open class DisplayCutoutBaseView : View, RegionInterceptableView {
private var shouldDrawCutout: Boolean = DisplayCutout.getFillBuiltInDisplayCutout(
- context.resources, context.display?.uniqueId)
+ context.resources, context.display?.uniqueId
+ )
private var displayUniqueId: String? = null
private var displayMode: Display.Mode? = null
protected val location = IntArray(2)
@@ -74,8 +75,8 @@
constructor(context: Context, attrs: AttributeSet?) : super(context, attrs)
- constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int)
- : super(context, attrs, defStyleAttr)
+ constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
+ super(context, attrs, defStyleAttr)
override fun onAttachedToWindow() {
super.onAttachedToWindow()
@@ -85,7 +86,7 @@
onUpdate()
}
- fun onDisplayChanged(displayId: Int) {
+ fun onDisplayChanged(newDisplayUniqueId: String?) {
val oldMode: Display.Mode? = displayMode
val display: Display? = context.display
displayMode = display?.mode
@@ -93,7 +94,8 @@
if (displayUniqueId != display?.uniqueId) {
displayUniqueId = display?.uniqueId
shouldDrawCutout = DisplayCutout.getFillBuiltInDisplayCutout(
- context.resources, displayUniqueId)
+ context.resources, displayUniqueId
+ )
}
// Skip if display mode or cutout hasn't changed.
@@ -101,7 +103,7 @@
display?.cutout == displayInfo.displayCutout) {
return
}
- if (displayId == display?.displayId) {
+ if (newDisplayUniqueId == display?.uniqueId) {
updateCutout()
updateProtectionBoundingPath()
onUpdate()
@@ -147,8 +149,9 @@
cutoutBounds.translate(-location[0], -location[1])
// Intersect with window's frame
- cutoutBounds.op(rootView.left, rootView.top, rootView.right, rootView.bottom,
- Region.Op.INTERSECT)
+ cutoutBounds.op(
+ rootView.left, rootView.top, rootView.right, rootView.bottom, Region.Op.INTERSECT
+ )
return cutoutBounds
}
@@ -171,9 +174,12 @@
protected open fun drawCutoutProtection(canvas: Canvas) {
if (cameraProtectionProgress > HIDDEN_CAMERA_PROTECTION_SCALE &&
- !protectionRect.isEmpty) {
- canvas.scale(cameraProtectionProgress, cameraProtectionProgress,
- protectionRect.centerX(), protectionRect.centerY())
+ !protectionRect.isEmpty
+ ) {
+ canvas.scale(
+ cameraProtectionProgress, cameraProtectionProgress, protectionRect.centerX(),
+ protectionRect.centerY()
+ )
canvas.drawPath(protectionPath, paint)
}
}
@@ -205,14 +211,17 @@
requestLayout()
}
cameraProtectionAnimator?.cancel()
- cameraProtectionAnimator = ValueAnimator.ofFloat(cameraProtectionProgress,
- if (showProtection) 1.0f else HIDDEN_CAMERA_PROTECTION_SCALE).setDuration(750)
+ cameraProtectionAnimator = ValueAnimator.ofFloat(
+ cameraProtectionProgress,
+ if (showProtection) 1.0f else HIDDEN_CAMERA_PROTECTION_SCALE
+ ).setDuration(750)
cameraProtectionAnimator?.interpolator = Interpolators.DECELERATE_QUINT
- cameraProtectionAnimator?.addUpdateListener(ValueAnimator.AnimatorUpdateListener {
- animation: ValueAnimator ->
- cameraProtectionProgress = animation.animatedValue as Float
- invalidate()
- })
+ cameraProtectionAnimator?.addUpdateListener(
+ ValueAnimator.AnimatorUpdateListener { animation: ValueAnimator ->
+ cameraProtectionProgress = animation.animatedValue as Float
+ invalidate()
+ }
+ )
cameraProtectionAnimator?.addListener(object : AnimatorListenerAdapter() {
override fun onAnimationEnd(animation: Animator) {
cameraProtectionAnimator = null
@@ -245,8 +254,10 @@
// Apply rotation.
val lw: Int = displayInfo.logicalWidth
val lh: Int = displayInfo.logicalHeight
- val flipped = (displayInfo.rotation == Surface.ROTATION_90 ||
- displayInfo.rotation == Surface.ROTATION_270)
+ val flipped = (
+ displayInfo.rotation == Surface.ROTATION_90 ||
+ displayInfo.rotation == Surface.ROTATION_270
+ )
val dw = if (flipped) lh else lw
val dh = if (flipped) lw else lh
transformPhysicalToLogicalCoordinates(displayInfo.rotation, dw, dh, m)
@@ -275,7 +286,7 @@
// We purposely ignore refresh rate and id changes here, because we don't need to
// invalidate for those, and they can trigger the refresh rate to increase
return oldMode?.physicalHeight != newMode?.physicalHeight ||
- oldMode?.physicalWidth != newMode?.physicalWidth
+ oldMode?.physicalWidth != newMode?.physicalWidth
}
companion object {
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index edcaf49..2e13903 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -32,7 +32,6 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.ActivityInfo;
-import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.graphics.Color;
@@ -73,6 +72,7 @@
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
+import com.android.systemui.decor.CutoutDecorProviderFactory;
import com.android.systemui.decor.DecorProvider;
import com.android.systemui.decor.DecorProviderFactory;
import com.android.systemui.decor.DecorProviderKt;
@@ -92,10 +92,8 @@
import java.io.PrintWriter;
import java.util.ArrayList;
-import java.util.HashSet;
import java.util.List;
import java.util.Objects;
-import java.util.Set;
import java.util.concurrent.Executor;
import javax.inject.Inject;
@@ -121,6 +119,13 @@
private static final boolean VERBOSE = false;
static final boolean DEBUG_COLOR = DEBUG_SCREENSHOT_ROUNDED_CORNERS;
+ private static final int[] DISPLAY_CUTOUT_IDS = {
+ R.id.display_cutout,
+ R.id.display_cutout_left,
+ R.id.display_cutout_right,
+ R.id.display_cutout_bottom
+ };
+
private DisplayManager mDisplayManager;
@VisibleForTesting
protected boolean mIsRegistered;
@@ -142,13 +147,11 @@
protected RoundedCornerResDelegate mRoundedCornerResDelegate;
@VisibleForTesting
protected DecorProviderFactory mRoundedCornerFactory;
+ private CutoutDecorProviderFactory mCutoutFactory;
private int mProviderRefreshToken = 0;
@VisibleForTesting
protected OverlayWindow[] mOverlays = null;
@VisibleForTesting
- @Nullable
- DisplayCutoutView[] mCutoutViews;
- @VisibleForTesting
ViewGroup mScreenDecorHwcWindow;
@VisibleForTesting
ScreenDecorHwcLayer mScreenDecorHwcLayer;
@@ -190,18 +193,19 @@
return;
}
- if (mCutoutViews == null) {
- Log.w(TAG, "DisplayCutoutView not initialized onApplyCameraProtection");
- return;
- }
-
- // Show the extra protection around the front facing camera if necessary
- for (DisplayCutoutView dcv : mCutoutViews) {
- // Check Null since not all mCutoutViews[pos] be inflated at the meanwhile
- if (dcv != null) {
- dcv.setProtection(protectionPath, bounds);
- dcv.enableShowProtection(true);
+ int setProtectionCnt = 0;
+ for (int id: DISPLAY_CUTOUT_IDS) {
+ final View view = getOverlayView(id);
+ if (!(view instanceof DisplayCutoutView)) {
+ continue;
}
+ ++setProtectionCnt;
+ final DisplayCutoutView dcv = (DisplayCutoutView) view;
+ dcv.setProtection(protectionPath, bounds);
+ dcv.enableShowProtection(true);
+ }
+ if (setProtectionCnt == 0) {
+ Log.e(TAG, "CutoutView not initialized showCameraProtection");
}
}
@@ -222,16 +226,17 @@
return;
}
- if (mCutoutViews == null) {
- Log.w(TAG, "DisplayCutoutView not initialized onHideCameraProtection");
- return;
- }
- // Go back to the regular anti-aliasing
- for (DisplayCutoutView dcv : mCutoutViews) {
- // Check Null since not all mCutoutViews[pos] be inflated at the meanwhile
- if (dcv != null) {
- dcv.enableShowProtection(false);
+ int setProtectionCnt = 0;
+ for (int id: DISPLAY_CUTOUT_IDS) {
+ final View view = getOverlayView(id);
+ if (!(view instanceof DisplayCutoutView)) {
+ continue;
}
+ ++setProtectionCnt;
+ ((DisplayCutoutView) view).enableShowProtection(false);
+ }
+ if (setProtectionCnt == 0) {
+ Log.e(TAG, "CutoutView not initialized hideCameraProtection");
}
}
@@ -338,6 +343,7 @@
decorProviders.addAll(mFaceScanningFactory.getProviders());
if (!hasHwLayer) {
decorProviders.addAll(mRoundedCornerFactory.getProviders());
+ decorProviders.addAll(mCutoutFactory.getProviders());
}
return decorProviders;
}
@@ -382,6 +388,7 @@
mRoundedCornerResDelegate.setPhysicalPixelDisplaySizeRatio(
getPhysicalPixelDisplaySizeRatio());
mRoundedCornerFactory = new RoundedCornerDecorProviderFactory(mRoundedCornerResDelegate);
+ mCutoutFactory = getCutoutFactory();
mHwcScreenDecorationSupport = mContext.getDisplay().getDisplayDecorationSupport();
updateHwLayerRoundedCornerDrawable();
setupDecorations();
@@ -448,6 +455,7 @@
}
}
+ boolean needToUpdateProviderViews = false;
final String newUniqueId = mDisplayInfo.uniqueId;
if (!Objects.equals(newUniqueId, mDisplayUniqueId)) {
mDisplayUniqueId = newUniqueId;
@@ -470,8 +478,7 @@
updateHwLayerRoundedCornerDrawable();
updateHwLayerRoundedCornerExistAndSize();
}
-
- updateOverlayProviderViews();
+ needToUpdateProviderViews = true;
}
final float newRatio = getPhysicalPixelDisplaySizeRatio();
@@ -480,28 +487,23 @@
if (mScreenDecorHwcLayer != null) {
updateHwLayerRoundedCornerExistAndSize();
}
- updateOverlayProviderViews();
+ needToUpdateProviderViews = true;
}
- if (mCutoutViews != null) {
- final int size = mCutoutViews.length;
- for (int i = 0; i < size; i++) {
- final DisplayCutoutView cutoutView = mCutoutViews[i];
- if (cutoutView == null) {
- continue;
- }
- cutoutView.onDisplayChanged(displayId);
- }
- }
-
- DisplayCutoutView overlay = (DisplayCutoutView) getOverlayView(mFaceScanningViewId);
- if (overlay != null) {
- // handle display resolution changes
- overlay.onDisplayChanged(displayId);
+ if (needToUpdateProviderViews) {
+ updateOverlayProviderViews(null);
+ } else {
+ updateOverlayProviderViews(new Integer[] {
+ mFaceScanningViewId,
+ R.id.display_cutout,
+ R.id.display_cutout_left,
+ R.id.display_cutout_right,
+ R.id.display_cutout_bottom,
+ });
}
if (mScreenDecorHwcLayer != null) {
- mScreenDecorHwcLayer.onDisplayChanged(displayId);
+ mScreenDecorHwcLayer.onDisplayChanged(newUniqueId);
}
}
};
@@ -510,8 +512,9 @@
updateConfiguration();
}
+ @VisibleForTesting
@Nullable
- private View getOverlayView(@IdRes int id) {
+ View getOverlayView(@IdRes int id) {
if (mOverlays == null) {
return null;
}
@@ -568,18 +571,18 @@
removeHwcOverlay();
}
- final DisplayCutout cutout = getCutout();
+ boolean[] hasCreatedOverlay = new boolean[BOUNDS_POSITION_LENGTH];
final boolean shouldOptimizeVisibility = shouldOptimizeVisibility();
+ Integer bound;
+ while ((bound = DecorProviderKt.getProperBound(decorProviders)) != null) {
+ hasCreatedOverlay[bound] = true;
+ Pair<List<DecorProvider>, List<DecorProvider>> pair =
+ DecorProviderKt.partitionAlignedBound(decorProviders, bound);
+ decorProviders = pair.getSecond();
+ createOverlay(bound, pair.getFirst(), shouldOptimizeVisibility);
+ }
for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
- if (shouldShowSwLayerCutout(i, cutout)
- || shouldShowSwLayerFaceScan(i, cutout)
- || shouldShowSwLayerRoundedCorner(i, cutout)
- || shouldShowSwLayerPrivacyDot(i, cutout)) {
- Pair<List<DecorProvider>, List<DecorProvider>> pair =
- DecorProviderKt.partitionAlignedBound(decorProviders, i);
- decorProviders = pair.getSecond();
- createOverlay(i, pair.getFirst(), shouldOptimizeVisibility);
- } else {
+ if (!hasCreatedOverlay[i]) {
removeOverlay(i);
}
}
@@ -642,9 +645,10 @@
}
}
- @VisibleForTesting
- DisplayCutout getCutout() {
- return mContext.getDisplay().getCutout();
+ // For unit test to override
+ protected CutoutDecorProviderFactory getCutoutFactory() {
+ return new CutoutDecorProviderFactory(mContext.getResources(),
+ mContext.getDisplay());
}
@VisibleForTesting
@@ -734,16 +738,6 @@
overlayView.setAlpha(0);
overlayView.setForceDarkAllowed(false);
- // Only show cutout in mOverlays when hwc doesn't support screen decoration
- if (mHwcScreenDecorationSupport == null) {
- if (mCutoutViews == null) {
- mCutoutViews = new DisplayCutoutView[BOUNDS_POSITION_LENGTH];
- }
- mCutoutViews[pos] = new DisplayCutoutView(mContext, pos);
- overlayView.addView(mCutoutViews[pos]);
- mCutoutViews[pos].updateRotation(mRotation);
- }
-
mWindowManager.addView(overlayView, getWindowLayoutParams(pos));
overlayView.addOnLayoutChangeListener(new OnLayoutChangeListener() {
@@ -804,7 +798,7 @@
return;
}
removeOverlayView(provider.getViewId());
- overlay.addDecorProvider(provider, mRotation);
+ overlay.addDecorProvider(provider, mRotation, mTintColor);
});
}
// Use visibility of privacy dot views & face scanning view to determine the overlay's
@@ -923,6 +917,7 @@
}
private void setupCameraListener() {
+ // TODO(b/238143614) Support dual screen camera protection
Resources res = mContext.getResources();
boolean enabled = res.getBoolean(R.bool.config_enableDisplayCutoutProtection);
if (enabled) {
@@ -951,45 +946,17 @@
mTintColor = Color.RED;
}
- if (mOverlays == null) {
- return;
- }
-
- // When the hwc supports screen decorations, the layer will use the A8 color mode which
- // won't be affected by the color inversion. If the composition goes the client composition
- // route, the color inversion will be handled by the RenderEngine.
- final Set<Integer> viewsMayNeedColorUpdate = new HashSet<>();
- if (mHwcScreenDecorationSupport == null) {
- ColorStateList tintList = ColorStateList.valueOf(mTintColor);
- mRoundedCornerResDelegate.setColorTintList(tintList);
- viewsMayNeedColorUpdate.add(R.id.rounded_corner_top_left);
- viewsMayNeedColorUpdate.add(R.id.rounded_corner_top_right);
- viewsMayNeedColorUpdate.add(R.id.rounded_corner_bottom_left);
- viewsMayNeedColorUpdate.add(R.id.rounded_corner_bottom_right);
- viewsMayNeedColorUpdate.add(R.id.display_cutout);
- }
- if (getOverlayView(mFaceScanningViewId) != null) {
- viewsMayNeedColorUpdate.add(mFaceScanningViewId);
- }
- final Integer[] views = new Integer[viewsMayNeedColorUpdate.size()];
- viewsMayNeedColorUpdate.toArray(views);
- for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
- if (mOverlays[i] == null) {
- continue;
- }
- final ViewGroup overlayView = mOverlays[i].getRootView();
- final int size = overlayView.getChildCount();
- View child;
- for (int j = 0; j < size; j++) {
- child = overlayView.getChildAt(j);
- if (viewsMayNeedColorUpdate.contains(child.getId())
- && child instanceof DisplayCutoutView) {
- ((DisplayCutoutView) child).setColor(mTintColor);
- }
- }
- mOverlays[i].onReloadResAndMeasure(views, mProviderRefreshToken,
- mRotation, mDisplayUniqueId);
- }
+ updateOverlayProviderViews(new Integer[] {
+ mFaceScanningViewId,
+ R.id.display_cutout,
+ R.id.display_cutout_left,
+ R.id.display_cutout_right,
+ R.id.display_cutout_bottom,
+ R.id.rounded_corner_top_left,
+ R.id.rounded_corner_top_right,
+ R.id.rounded_corner_bottom_left,
+ R.id.rounded_corner_bottom_right
+ });
}
@VisibleForTesting
@@ -1109,18 +1076,9 @@
updateHwLayerRoundedCornerDrawable();
}
updateLayoutParams();
- // update cutout view rotation
- if (mCutoutViews != null) {
- for (final DisplayCutoutView cutoutView: mCutoutViews) {
- if (cutoutView == null) {
- continue;
- }
- cutoutView.updateRotation(mRotation);
- }
- }
// update all provider views inside overlay
- updateOverlayProviderViews();
+ updateOverlayProviderViews(null);
}
FaceScanningOverlay faceScanningOverlay =
@@ -1136,46 +1094,6 @@
return mRoundedCornerFactory.getHasProviders();
}
- private boolean isDefaultShownOverlayPos(@BoundsPosition int pos,
- @Nullable DisplayCutout cutout) {
- // for cutout is null or cutout with only waterfall.
- final boolean emptyBoundsOrWaterfall = cutout == null || cutout.isBoundsEmpty();
- // Shows rounded corner on left and right overlays only when there is no top or bottom
- // cutout.
- final int rotatedTop = getBoundPositionFromRotation(BOUNDS_POSITION_TOP, mRotation);
- final int rotatedBottom = getBoundPositionFromRotation(BOUNDS_POSITION_BOTTOM, mRotation);
- if (emptyBoundsOrWaterfall || !cutout.getBoundingRectsAll()[rotatedTop].isEmpty()
- || !cutout.getBoundingRectsAll()[rotatedBottom].isEmpty()) {
- return pos == BOUNDS_POSITION_TOP || pos == BOUNDS_POSITION_BOTTOM;
- } else {
- return pos == BOUNDS_POSITION_LEFT || pos == BOUNDS_POSITION_RIGHT;
- }
- }
-
- private boolean shouldShowSwLayerRoundedCorner(@BoundsPosition int pos,
- @Nullable DisplayCutout cutout) {
- return hasRoundedCorners() && isDefaultShownOverlayPos(pos, cutout)
- && mHwcScreenDecorationSupport == null;
- }
-
- private boolean shouldShowSwLayerPrivacyDot(@BoundsPosition int pos,
- @Nullable DisplayCutout cutout) {
- return isPrivacyDotEnabled() && isDefaultShownOverlayPos(pos, cutout);
- }
-
- private boolean shouldShowSwLayerFaceScan(@BoundsPosition int pos,
- @Nullable DisplayCutout cutout) {
- return mFaceScanningFactory.getHasProviders() && isDefaultShownOverlayPos(pos, cutout);
- }
-
- private boolean shouldShowSwLayerCutout(@BoundsPosition int pos,
- @Nullable DisplayCutout cutout) {
- final Rect[] bounds = cutout == null ? null : cutout.getBoundingRectsAll();
- final int rotatedPos = getBoundPositionFromRotation(pos, mRotation);
- return (bounds != null && !bounds[rotatedPos].isEmpty()
- && mHwcScreenDecorationSupport == null);
- }
-
private boolean shouldOptimizeVisibility() {
return (isPrivacyDotEnabled() || mFaceScanningFactory.getHasProviders())
&& (mHwcScreenDecorationSupport != null
@@ -1184,7 +1102,7 @@
}
private boolean shouldDrawCutout() {
- return shouldDrawCutout(mContext);
+ return mCutoutFactory.getHasProviders();
}
static boolean shouldDrawCutout(Context context) {
@@ -1192,7 +1110,7 @@
context.getResources(), context.getDisplay().getUniqueId());
}
- private void updateOverlayProviderViews() {
+ private void updateOverlayProviderViews(@Nullable Integer[] filterIds) {
if (mOverlays == null) {
return;
}
@@ -1201,7 +1119,8 @@
if (overlay == null) {
continue;
}
- overlay.onReloadResAndMeasure(null, mProviderRefreshToken, mRotation, mDisplayUniqueId);
+ overlay.onReloadResAndMeasure(filterIds, mProviderRefreshToken, mRotation, mTintColor,
+ mDisplayUniqueId);
}
}
@@ -1240,19 +1159,12 @@
} catch (NumberFormatException e) {
mRoundedCornerResDelegate.setTuningSizeFactor(null);
}
- Integer[] filterIds = {
+ updateOverlayProviderViews(new Integer[] {
R.id.rounded_corner_top_left,
R.id.rounded_corner_top_right,
R.id.rounded_corner_bottom_left,
R.id.rounded_corner_bottom_right
- };
- for (final OverlayWindow overlay: mOverlays) {
- if (overlay == null) {
- continue;
- }
- overlay.onReloadResAndMeasure(filterIds, mProviderRefreshToken, mRotation,
- mDisplayUniqueId);
- }
+ });
updateHwLayerRoundedCornerExistAndSize();
});
}
@@ -1306,7 +1218,6 @@
paint.setColor(mColor);
paint.setStyle(Paint.Style.FILL);
- setId(R.id.display_cutout);
if (DEBUG) {
getViewTreeObserver().addOnDrawListener(() -> Log.i(TAG,
getWindowTitleByPos(pos) + " drawn in rot " + mRotation));
@@ -1314,6 +1225,9 @@
}
public void setColor(int color) {
+ if (color == mColor) {
+ return;
+ }
mColor = color;
paint.setColor(mColor);
invalidate();
@@ -1321,6 +1235,12 @@
@Override
public void updateRotation(int rotation) {
+ // updateRotation() is called inside CutoutDecorProviderImpl::onReloadResAndMeasure()
+ // during onDisplayChanged. In order to prevent reloading cutout info in super class,
+ // check mRotation at first
+ if (rotation == mRotation) {
+ return;
+ }
mRotation = rotation;
super.updateRotation(rotation);
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
index 84e1c3d..86837366 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthContainerView.java
@@ -129,6 +129,8 @@
private final Set<Integer> mFailedModalities = new HashSet<Integer>();
private final @Background DelayableExecutor mBackgroundExecutor;
+ private int mOrientation;
+ private boolean mSkipFirstLostFocus = false;
// Non-null only if the dialog is in the act of dismissing and has not sent the reason yet.
@Nullable @AuthDialogCallback.DismissedReason private Integer mPendingCallbackReason;
@@ -441,6 +443,12 @@
public void onWindowFocusChanged(boolean hasWindowFocus) {
super.onWindowFocusChanged(hasWindowFocus);
if (!hasWindowFocus) {
+ //it's a workaround to avoid closing BP incorrectly
+ //BP gets a onWindowFocusChanged(false) and then gets a onWindowFocusChanged(true)
+ if (mSkipFirstLostFocus) {
+ mSkipFirstLostFocus = false;
+ return;
+ }
Log.v(TAG, "Lost window focus, dismissing the dialog");
animateAway(AuthDialogCallback.DISMISSED_USER_CANCELED);
}
@@ -450,6 +458,9 @@
public void onAttachedToWindow() {
super.onAttachedToWindow();
+ //save the first orientation
+ mOrientation = getResources().getConfiguration().orientation;
+
mWakefulnessLifecycle.addObserver(this);
if (Utils.isBiometricAllowed(mConfig.mPromptInfo)) {
@@ -621,6 +632,12 @@
if (mBiometricView != null) {
mBiometricView.restoreState(savedState);
}
+
+ if (savedState != null) {
+ mSkipFirstLostFocus = savedState.getBoolean(
+ AuthDialog.KEY_BIOMETRIC_ORIENTATION_CHANGED);
+ }
+
wm.addView(this, getLayoutParams(mWindowToken, mConfig.mPromptInfo.getTitle()));
}
@@ -677,6 +694,10 @@
mBiometricView != null && mCredentialView == null);
outState.putBoolean(AuthDialog.KEY_CREDENTIAL_SHOWING, mCredentialView != null);
+ if (mOrientation != getResources().getConfiguration().orientation) {
+ outState.putBoolean(AuthDialog.KEY_BIOMETRIC_ORIENTATION_CHANGED, true);
+ }
+
if (mBiometricView != null) {
mBiometricView.onSaveState(outState);
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
index 51f39b3..cd0fc37 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthDialog.java
@@ -48,6 +48,8 @@
String KEY_BIOMETRIC_SENSOR_TYPE = "sensor_type";
String KEY_BIOMETRIC_SENSOR_PROPS = "sensor_props";
+ String KEY_BIOMETRIC_ORIENTATION_CHANGED = "orientation_changed";
+
int SIZE_UNKNOWN = 0;
/**
* Minimal UI, showing only biometric icon.
diff --git a/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
index 4fe2dd8..e2ef247 100644
--- a/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
+++ b/packages/SystemUI/src/com/android/systemui/camera/CameraGestureHelper.kt
@@ -33,7 +33,6 @@
import com.android.systemui.ActivityIntentHelper
import com.android.systemui.dagger.qualifiers.Main
import com.android.systemui.plugins.ActivityStarter
-import com.android.systemui.shade.NotificationPanelViewController
import com.android.systemui.shared.system.ActivityManagerKt.isInForeground
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.phone.CentralSurfaces
@@ -117,7 +116,7 @@
)
} catch (e: RemoteException) {
Log.w(
- NotificationPanelViewController.TAG,
+ "CameraGestureHelper",
"Unable to start camera activity",
e
)
diff --git a/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderFactory.kt b/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderFactory.kt
new file mode 100644
index 0000000..cbed21c
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderFactory.kt
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2022 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.systemui.decor
+
+import android.content.res.Resources
+import android.util.Log
+import android.view.Display
+import android.view.DisplayCutout
+import android.view.DisplayInfo
+
+class CutoutDecorProviderFactory constructor(
+ private val res: Resources,
+ private val display: Display?,
+) : DecorProviderFactory() {
+
+ val displayInfo = DisplayInfo()
+
+ override val hasProviders: Boolean
+ get() {
+ display?.getDisplayInfo(displayInfo) ?: run {
+ Log.w(TAG, "display is null, can't update displayInfo")
+ }
+ return DisplayCutout.getFillBuiltInDisplayCutout(res, displayInfo.uniqueId)
+ }
+
+ override val providers: List<DecorProvider>
+ get() {
+ if (!hasProviders) {
+ return emptyList()
+ }
+
+ return ArrayList<DecorProvider>().also { list ->
+ // We need to update displayInfo before using it, but it has already updated during
+ // accessing hasProviders field
+ displayInfo.displayCutout?.getBoundBaseOnCurrentRotation()?.let { bounds ->
+ for (bound in bounds) {
+ list.add(
+ CutoutDecorProviderImpl(bound.baseOnRotation0(displayInfo.rotation))
+ )
+ }
+ }
+ }
+ }
+}
+
+private const val TAG = "CutoutDecorProviderFactory"
diff --git a/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt
new file mode 100644
index 0000000..991b54e
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/decor/CutoutDecorProviderImpl.kt
@@ -0,0 +1,65 @@
+/*
+ * Copyright (C) 2022 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.systemui.decor
+
+import android.content.Context
+import android.view.DisplayCutout
+import android.view.Surface
+import android.view.View
+import android.view.ViewGroup
+import com.android.systemui.R
+import com.android.systemui.ScreenDecorations.DisplayCutoutView
+
+class CutoutDecorProviderImpl(
+ @DisplayCutout.BoundsPosition override val alignedBound: Int
+) : BoundDecorProvider() {
+
+ override val viewId: Int = when (alignedBound) {
+ DisplayCutout.BOUNDS_POSITION_TOP -> R.id.display_cutout
+ DisplayCutout.BOUNDS_POSITION_LEFT -> R.id.display_cutout_left
+ DisplayCutout.BOUNDS_POSITION_RIGHT -> R.id.display_cutout_right
+ else -> R.id.display_cutout_bottom
+ }
+
+ override fun inflateView(
+ context: Context,
+ parent: ViewGroup,
+ @Surface.Rotation rotation: Int,
+ tintColor: Int
+ ): View {
+ return DisplayCutoutView(context, alignedBound).also { view ->
+ view.id = viewId
+ view.setColor(tintColor)
+ parent.addView(view)
+ view.updateRotation(rotation)
+ }
+ }
+
+ override fun onReloadResAndMeasure(
+ view: View,
+ reloadToken: Int,
+ @Surface.Rotation rotation: Int,
+ tintColor: Int,
+ displayUniqueId: String?
+ ) {
+ (view as? DisplayCutoutView)?.let { cutoutView ->
+ cutoutView.setColor(tintColor)
+ cutoutView.updateRotation(rotation)
+ cutoutView.onDisplayChanged(displayUniqueId)
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt b/packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt
index 169b50e..0681f50 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/DecorProvider.kt
@@ -32,8 +32,8 @@
abstract val viewId: Int
/** The number of total aligned bounds */
- val numOfAlignedEdge: Int
- get() = alignedBounds.size
+ val numOfAlignedBound: Int
+ get() = alignedBounds.size
/** The aligned bounds for the view which is created through inflateView() */
abstract val alignedBounds: List<Int>
@@ -46,25 +46,19 @@
view: View,
reloadToken: Int,
@Surface.Rotation rotation: Int,
- displayUniqueId: String? = null
+ tintColor: Int,
+ displayUniqueId: String?
)
/** Inflate view into parent as current rotation */
abstract fun inflateView(
context: Context,
parent: ViewGroup,
- @Surface.Rotation rotation: Int
+ @Surface.Rotation rotation: Int,
+ tintColor: Int
): View
-}
-/**
- * Split list to 2 list, and return it back as Pair<>. The providers on the first list contains this
- * alignedBound element. The providers on the second list do not contain this alignedBound element
- */
-fun List<DecorProvider>.partitionAlignedBound(
- @DisplayCutout.BoundsPosition alignedBound: Int
-): Pair<List<DecorProvider>, List<DecorProvider>> {
- return partition { it.alignedBounds.contains(alignedBound) }
+ override fun toString() = "${javaClass.simpleName}{alignedBounds=$alignedBounds}"
}
/**
@@ -92,3 +86,61 @@
listOf(alignedBound)
}
}
+
+/**
+ * Split list to 2 sub-lists, and return it back as Pair<>. The providers on the first list contains
+ * this alignedBound element. The providers on the second list do not contain this alignedBound
+ * element.
+ */
+fun List<DecorProvider>.partitionAlignedBound(
+ @DisplayCutout.BoundsPosition alignedBound: Int
+): Pair<List<DecorProvider>, List<DecorProvider>> {
+ return partition { it.alignedBounds.contains(alignedBound) }
+}
+
+/**
+ * Get the proper bound from DecorProvider list
+ * Time complexity: O(N), N is the number of providers
+ *
+ * Choose order
+ * 1. Return null if list is empty
+ * 2. If list contains BoundDecorProvider, return its alignedBound[0] because it is a must-have
+ * bound
+ * 3. Return the bound with most DecorProviders
+ */
+fun List<DecorProvider>.getProperBound(): Int? {
+ // Return null if list is empty
+ if (isEmpty()) {
+ return null
+ }
+
+ // Choose alignedBounds[0] of BoundDecorProvider if any
+ val singleBoundProvider = firstOrNull { it.numOfAlignedBound == 1 }
+ if (singleBoundProvider != null) {
+ return singleBoundProvider.alignedBounds[0]
+ }
+
+ // Return the bound with most DecorProviders
+ val boundCount = intArrayOf(0, 0, 0, 0)
+ for (provider in this) {
+ for (bound in provider.alignedBounds) {
+ boundCount[bound]++
+ }
+ }
+ var maxCount = 0
+ var maxCountBound: Int? = null
+ val bounds = arrayOf(
+ // Put top and bottom at first to get the highest priority to be chosen
+ DisplayCutout.BOUNDS_POSITION_TOP,
+ DisplayCutout.BOUNDS_POSITION_BOTTOM,
+ DisplayCutout.BOUNDS_POSITION_LEFT,
+ DisplayCutout.BOUNDS_POSITION_RIGHT
+ )
+ for (bound in bounds) {
+ if (boundCount[bound] > maxCount) {
+ maxCountBound = bound
+ maxCount = boundCount[bound]
+ }
+ }
+ return maxCountBound
+}
diff --git a/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt b/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt
index 81d3d6c..5925c57 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/FaceScanningProviderFactory.kt
@@ -115,19 +115,25 @@
override fun onReloadResAndMeasure(
view: View,
reloadToken: Int,
- rotation: Int,
+ @Surface.Rotation rotation: Int,
+ tintColor: Int,
displayUniqueId: String?
) {
(view.layoutParams as FrameLayout.LayoutParams).let {
updateLayoutParams(it, rotation)
view.layoutParams = it
+ (view as? FaceScanningOverlay)?.let { overlay ->
+ overlay.setColor(tintColor)
+ overlay.onDisplayChanged(displayUniqueId)
+ }
}
}
override fun inflateView(
context: Context,
parent: ViewGroup,
- @Surface.Rotation rotation: Int
+ @Surface.Rotation rotation: Int,
+ tintColor: Int
): View {
val view = FaceScanningOverlay(
context,
@@ -137,6 +143,7 @@
mainExecutor
)
view.id = viewId
+ view.setColor(tintColor)
FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.MATCH_PARENT).let {
updateLayoutParams(it, rotation)
diff --git a/packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt b/packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt
index 3c0748e..45b8a08 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/OverlayWindow.kt
@@ -34,9 +34,10 @@
fun addDecorProvider(
decorProvider: DecorProvider,
- @Surface.Rotation rotation: Int
+ @Surface.Rotation rotation: Int,
+ tintColor: Int
) {
- val view = decorProvider.inflateView(context, rootView, rotation)
+ val view = decorProvider.inflateView(context, rootView, rotation, tintColor)
viewProviderMap[decorProvider.viewId] = Pair(view, decorProvider)
}
@@ -69,7 +70,7 @@
*/
fun hasSameProviders(newProviders: List<DecorProvider>): Boolean {
return (newProviders.size == viewProviderMap.size) &&
- newProviders.all { getView(it.viewId) != null }
+ newProviders.all { getView(it.viewId) != null }
}
/**
@@ -82,23 +83,28 @@
filterIds: Array<Int>? = null,
reloadToken: Int,
@Surface.Rotation rotation: Int,
+ tintColor: Int,
displayUniqueId: String? = null
) {
filterIds?.forEach { id ->
viewProviderMap[id]?.let {
it.second.onReloadResAndMeasure(
- view = it.first,
- reloadToken = reloadToken,
- displayUniqueId = displayUniqueId,
- rotation = rotation)
+ view = it.first,
+ reloadToken = reloadToken,
+ rotation = rotation,
+ tintColor = tintColor,
+ displayUniqueId = displayUniqueId
+ )
}
} ?: run {
viewProviderMap.values.forEach {
it.second.onReloadResAndMeasure(
- view = it.first,
- reloadToken = reloadToken,
- displayUniqueId = displayUniqueId,
- rotation = rotation)
+ view = it.first,
+ reloadToken = reloadToken,
+ rotation = rotation,
+ tintColor = tintColor,
+ displayUniqueId = displayUniqueId
+ )
}
}
}
@@ -108,7 +114,8 @@
pw.println(" rootView=$rootView")
for (i in 0 until rootView.childCount) {
val child = rootView.getChildAt(i)
- pw.println(" child[$i]=$child")
+ val provider = viewProviderMap[child.id]?.second
+ pw.println(" child[$i]=$child $provider")
}
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt b/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt
index 9f624b3..e18c0e1 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/PrivacyDotDecorProviderFactory.kt
@@ -20,9 +20,9 @@
import android.content.res.Resources
import android.view.DisplayCutout
import android.view.LayoutInflater
+import android.view.Surface
import android.view.View
import android.view.ViewGroup
-import android.view.Surface
import com.android.systemui.R
import com.android.systemui.dagger.SysUISingleton
import com.android.systemui.dagger.qualifiers.Main
@@ -85,6 +85,7 @@
view: View,
reloadToken: Int,
rotation: Int,
+ tintColor: Int,
displayUniqueId: String?
) {
// Do nothing here because it is handled inside PrivacyDotViewController
@@ -93,7 +94,8 @@
override fun inflateView(
context: Context,
parent: ViewGroup,
- @Surface.Rotation rotation: Int
+ @Surface.Rotation rotation: Int,
+ tintColor: Int
): View {
LayoutInflater.from(context).inflate(layoutId, parent, true)
return parent.getChildAt(parent.childCount - 1 /* latest new added child */)
diff --git a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt
index e316722..8156797 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerDecorProviderImpl.kt
@@ -17,6 +17,7 @@
package com.android.systemui.decor
import android.content.Context
+import android.content.res.ColorStateList
import android.view.DisplayCutout
import android.view.Gravity
import android.view.Surface
@@ -38,12 +39,13 @@
override fun inflateView(
context: Context,
parent: ViewGroup,
- @Surface.Rotation rotation: Int
+ @Surface.Rotation rotation: Int,
+ tintColor: Int
): View {
return ImageView(context).also { view ->
// View
view.id = viewId
- initView(view, rotation)
+ initView(view, rotation, tintColor)
// LayoutParams
val layoutSize = if (isTop) {
@@ -52,31 +54,36 @@
roundedCornerResDelegate.bottomRoundedSize
}
val params = FrameLayout.LayoutParams(
- layoutSize.width,
- layoutSize.height,
- alignedBound1.toLayoutGravity(rotation) or
- alignedBound2.toLayoutGravity(rotation))
+ layoutSize.width,
+ layoutSize.height,
+ alignedBound1.toLayoutGravity(rotation) or alignedBound2.toLayoutGravity(rotation)
+ )
// AddView
parent.addView(view, params)
}
}
- private fun initView(view: ImageView, @Surface.Rotation rotation: Int) {
+ private fun initView(
+ view: ImageView,
+ @Surface.Rotation rotation: Int,
+ tintColor: Int
+ ) {
view.setRoundedCornerImage(roundedCornerResDelegate, isTop)
view.adjustRotation(alignedBounds, rotation)
- view.imageTintList = roundedCornerResDelegate.colorTintList
+ view.imageTintList = ColorStateList.valueOf(tintColor)
}
override fun onReloadResAndMeasure(
view: View,
reloadToken: Int,
@Surface.Rotation rotation: Int,
+ tintColor: Int,
displayUniqueId: String?
) {
roundedCornerResDelegate.updateDisplayUniqueId(displayUniqueId, reloadToken)
- initView((view as ImageView), rotation)
+ initView((view as ImageView), rotation, tintColor)
val layoutSize = if (isTop) {
roundedCornerResDelegate.topRoundedSize
@@ -87,7 +94,7 @@
it.width = layoutSize.width
it.height = layoutSize.height
it.gravity = alignedBound1.toLayoutGravity(rotation) or
- alignedBound2.toLayoutGravity(rotation)
+ alignedBound2.toLayoutGravity(rotation)
view.setLayoutParams(it)
}
}
@@ -134,10 +141,10 @@
setImageDrawable(drawable)
} else {
setImageResource(
- if (isTop)
- R.drawable.rounded_corner_top
- else
- R.drawable.rounded_corner_bottom
+ if (isTop)
+ R.drawable.rounded_corner_top
+ else
+ R.drawable.rounded_corner_bottom
)
}
}
@@ -187,4 +194,4 @@
this.rotation = newRotation
this.scaleX = newScaleX
this.scaleY = newScaleY
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt
index b5a0cfc..a252864 100644
--- a/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt
+++ b/packages/SystemUI/src/com/android/systemui/decor/RoundedCornerResDelegate.kt
@@ -18,9 +18,7 @@
import android.annotation.ArrayRes
import android.annotation.DrawableRes
-import android.content.res.ColorStateList
import android.content.res.Resources
-import android.graphics.Color
import android.graphics.drawable.Drawable
import android.util.DisplayUtils
import android.util.Size
@@ -57,8 +55,6 @@
var bottomRoundedSize = Size(0, 0)
private set
- var colorTintList = ColorStateList.valueOf(Color.BLACK)
-
var tuningSizeFactor: Int? = null
set(value) {
if (field == value) {
@@ -107,19 +103,19 @@
val hasDefaultRadius = RoundedCorners.getRoundedCornerRadius(res, displayUniqueId) > 0
hasTop = hasDefaultRadius ||
- (RoundedCorners.getRoundedCornerTopRadius(res, displayUniqueId) > 0)
+ (RoundedCorners.getRoundedCornerTopRadius(res, displayUniqueId) > 0)
hasBottom = hasDefaultRadius ||
- (RoundedCorners.getRoundedCornerBottomRadius(res, displayUniqueId) > 0)
+ (RoundedCorners.getRoundedCornerBottomRadius(res, displayUniqueId) > 0)
topRoundedDrawable = getDrawable(
- displayConfigIndex = configIdx,
- arrayResId = R.array.config_roundedCornerTopDrawableArray,
- backupDrawableId = R.drawable.rounded_corner_top
+ displayConfigIndex = configIdx,
+ arrayResId = R.array.config_roundedCornerTopDrawableArray,
+ backupDrawableId = R.drawable.rounded_corner_top
)
bottomRoundedDrawable = getDrawable(
- displayConfigIndex = configIdx,
- arrayResId = R.array.config_roundedCornerBottomDrawableArray,
- backupDrawableId = R.drawable.rounded_corner_bottom
+ displayConfigIndex = configIdx,
+ arrayResId = R.array.config_roundedCornerBottomDrawableArray,
+ backupDrawableId = R.drawable.rounded_corner_bottom
)
}
@@ -147,13 +143,15 @@
if (physicalPixelDisplaySizeRatio != 1f) {
if (topRoundedSize.width != 0) {
topRoundedSize = Size(
- (physicalPixelDisplaySizeRatio * topRoundedSize.width + 0.5f).toInt(),
- (physicalPixelDisplaySizeRatio * topRoundedSize.height + 0.5f).toInt())
+ (physicalPixelDisplaySizeRatio * topRoundedSize.width + 0.5f).toInt(),
+ (physicalPixelDisplaySizeRatio * topRoundedSize.height + 0.5f).toInt()
+ )
}
if (bottomRoundedSize.width != 0) {
bottomRoundedSize = Size(
- (physicalPixelDisplaySizeRatio * bottomRoundedSize.width + 0.5f).toInt(),
- (physicalPixelDisplaySizeRatio * bottomRoundedSize.height + 0.5f).toInt())
+ (physicalPixelDisplaySizeRatio * bottomRoundedSize.width + 0.5f).toInt(),
+ (physicalPixelDisplaySizeRatio * bottomRoundedSize.height + 0.5f).toInt()
+ )
}
}
}
@@ -180,8 +178,9 @@
pw.println(" hasTop=$hasTop")
pw.println(" hasBottom=$hasBottom")
pw.println(" topRoundedSize(w,h)=(${topRoundedSize.width},${topRoundedSize.height})")
- pw.println(" bottomRoundedSize(w,h)=(${bottomRoundedSize.width}," +
- "${bottomRoundedSize.height})")
+ pw.println(
+ " bottomRoundedSize(w,h)=(${bottomRoundedSize.width},${bottomRoundedSize.height})"
+ )
pw.println(" physicalPixelDisplaySizeRatio=$physicalPixelDisplaySizeRatio")
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java
index 567bdbc..a981f25 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/SmartSpaceComplication.java
@@ -70,11 +70,7 @@
new BcSmartspaceDataPlugin.SmartspaceTargetListener() {
@Override
public void onSmartspaceTargetsUpdated(List<? extends Parcelable> targets) {
- if (!targets.isEmpty()) {
- mDreamOverlayStateController.addComplication(mComplication);
- } else {
- mDreamOverlayStateController.removeComplication(mComplication);
- }
+ mDreamOverlayStateController.addComplication(mComplication);
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
index 9e2b7c7..a3dc779 100644
--- a/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
+++ b/packages/SystemUI/src/com/android/systemui/keyboard/KeyboardUI.java
@@ -50,7 +50,6 @@
import com.android.settingslib.bluetooth.LocalBluetoothManager;
import com.android.settingslib.bluetooth.LocalBluetoothProfileManager;
import com.android.systemui.CoreStartable;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
@@ -61,6 +60,7 @@
import java.util.Set;
import javax.inject.Inject;
+import javax.inject.Provider;
/** */
@SysUISingleton
@@ -106,6 +106,8 @@
protected volatile Context mContext;
+ private final Provider<LocalBluetoothManager> mBluetoothManagerProvider;
+
private boolean mEnabled;
private String mKeyboardName;
private CachedBluetoothDeviceManager mCachedDeviceManager;
@@ -122,8 +124,9 @@
private int mState;
@Inject
- public KeyboardUI(Context context) {
+ public KeyboardUI(Context context, Provider<LocalBluetoothManager> bluetoothManagerProvider) {
super(context);
+ this.mBluetoothManagerProvider = bluetoothManagerProvider;
}
@Override
@@ -181,7 +184,7 @@
return;
}
- LocalBluetoothManager bluetoothManager = Dependency.get(LocalBluetoothManager.class);
+ LocalBluetoothManager bluetoothManager = mBluetoothManagerProvider.get();
if (bluetoothManager == null) {
if (DEBUG) {
Slog.e(TAG, "Failed to retrieve LocalBluetoothManager instance");
diff --git a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
index bec130b..e08e338 100644
--- a/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/media/dialog/MediaOutputBaseDialog.java
@@ -356,15 +356,6 @@
mHeaderSubtitle.setText(subTitle);
mHeaderTitle.setGravity(Gravity.NO_GRAVITY);
}
- if (!mAdapter.isDragging()) {
- int currentActivePosition = mAdapter.getCurrentActivePosition();
- if (!colorSetUpdated && !deviceSetChanged && currentActivePosition >= 0
- && currentActivePosition < mAdapter.getItemCount()) {
- mAdapter.notifyItemChanged(currentActivePosition);
- } else {
- mAdapter.notifyDataSetChanged();
- }
- }
// Show when remote media session is available or
// when the device supports BT LE audio + media is playing
mStopButton.setVisibility(getStopButtonVisibility());
@@ -374,6 +365,18 @@
mBroadcastIcon.setVisibility(getBroadcastIconVisibility());
mBroadcastIcon.setOnClickListener(v -> onBroadcastIconClick());
+ if (!mAdapter.isDragging()) {
+ int currentActivePosition = mAdapter.getCurrentActivePosition();
+ if (!colorSetUpdated && !deviceSetChanged && currentActivePosition >= 0
+ && currentActivePosition < mAdapter.getItemCount()) {
+ mAdapter.notifyItemChanged(currentActivePosition);
+ } else {
+ mAdapter.notifyDataSetChanged();
+ }
+ } else {
+ mMediaOutputController.setRefreshing(false);
+ mMediaOutputController.refreshDataSetIfNeeded();
+ }
}
private void updateButtonBackgroundColorFilter() {
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
index 9818af3..1cdacb9 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelView.java
@@ -17,32 +17,30 @@
package com.android.systemui.shade;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.util.AttributeSet;
+import android.view.MotionEvent;
+import android.widget.FrameLayout;
import com.android.systemui.R;
import com.android.systemui.statusbar.phone.TapAgainView;
-public class NotificationPanelView extends PanelView {
+/** The shade view. */
+public final class NotificationPanelView extends FrameLayout {
+ static final boolean DEBUG = false;
- private static final boolean DEBUG = false;
-
- /**
- * Fling expanding QS.
- */
- public static final int FLING_EXPAND = 0;
-
- public static final String COUNTER_PANEL_OPEN = "panel_open";
- public static final String COUNTER_PANEL_OPEN_QS = "panel_open_qs";
+ private final Paint mAlphaPaint = new Paint();
private int mCurrentPanelAlpha;
- private final Paint mAlphaPaint = new Paint();
private boolean mDozing;
private RtlChangeListener mRtlChangeListener;
+ private NotificationPanelViewController.TouchHandler mTouchHandler;
+ private OnConfigurationChangedListener mOnConfigurationChangedListener;
public NotificationPanelView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -99,7 +97,36 @@
return findViewById(R.id.shade_falsing_tap_again);
}
+ /** Sets the touch handler for this view. */
+ public void setOnTouchListener(NotificationPanelViewController.TouchHandler touchHandler) {
+ super.setOnTouchListener(touchHandler);
+ mTouchHandler = touchHandler;
+ }
+
+ void setOnConfigurationChangedListener(OnConfigurationChangedListener listener) {
+ mOnConfigurationChangedListener = listener;
+ }
+
+ @Override
+ public boolean onInterceptTouchEvent(MotionEvent event) {
+ return mTouchHandler.onInterceptTouchEvent(event);
+ }
+
+ @Override
+ public void dispatchConfigurationChanged(Configuration newConfig) {
+ super.dispatchConfigurationChanged(newConfig);
+ mOnConfigurationChangedListener.onConfigurationChanged(newConfig);
+ }
+
+ /** Callback for right-to-left setting changes. */
interface RtlChangeListener {
+ /** Called when right-to-left setting changes. */
void onRtlPropertielsChanged(int layoutDirection);
}
+
+ /** Callback for config changes. */
+ interface OnConfigurationChangedListener {
+ /** Called when configuration changes. */
+ void onConfigurationChanged(Configuration newConfig);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 3b7c7ce..efdeba5 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -33,7 +33,7 @@
import static com.android.systemui.classifier.Classifier.QS_COLLAPSE;
import static com.android.systemui.classifier.Classifier.QUICK_SETTINGS;
import static com.android.systemui.classifier.Classifier.UNLOCK;
-import static com.android.systemui.shade.PanelView.DEBUG;
+import static com.android.systemui.shade.NotificationPanelView.DEBUG;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED;
import static com.android.systemui.shared.system.QuickStepContract.SYSUI_STATE_QUICK_SETTINGS_EXPANDED;
import static com.android.systemui.statusbar.StatusBarState.KEYGUARD;
@@ -248,7 +248,7 @@
@CentralSurfacesComponent.CentralSurfacesScope
public final class NotificationPanelViewController {
- public static final String TAG = PanelView.class.getSimpleName();
+ public static final String TAG = "PanelView";
public static final float FLING_MAX_LENGTH_SECONDS = 0.6f;
public static final float FLING_SPEED_UP_FACTOR = 0.6f;
public static final float FLING_CLOSING_MAX_LENGTH_SECONDS = 0.6f;
@@ -274,7 +274,7 @@
/**
* Fling expanding QS.
*/
- private static final int FLING_EXPAND = 0;
+ public static final int FLING_EXPAND = 0;
/**
* Fling collapsing QS, potentially stopping when QS becomes QQS.
@@ -435,7 +435,8 @@
private boolean mQsTracking;
/**
- * If set, the ongoing touch gesture might both trigger the expansion in {@link PanelView} and
+ * If set, the ongoing touch gesture might both trigger the expansion in {@link
+ * NotificationPanelView} and
* the expansion for quick settings.
*/
private boolean mConflictingQsExpansionGesture;
@@ -5417,13 +5418,13 @@
return animator;
}
- /** Update the visibility of {@link PanelView} if necessary. */
+ /** Update the visibility of {@link NotificationPanelView} if necessary. */
public void updateVisibility() {
mView.setVisibility(shouldPanelBeVisible() ? VISIBLE : INVISIBLE);
}
/**
- * Updates the panel expansion and {@link PanelView} visibility if necessary.
+ * Updates the panel expansion and {@link NotificationPanelView} visibility if necessary.
*
* TODO(b/200063118): Could public calls to this method be replaced with calls to
* {@link #updateVisibility()}? That would allow us to make this method private.
@@ -6186,7 +6187,7 @@
}
public class OnConfigurationChangedListener implements
- PanelView.OnConfigurationChangedListener {
+ NotificationPanelView.OnConfigurationChangedListener {
@Override
public void onConfigurationChanged(Configuration newConfig) {
loadDimens();
diff --git a/packages/SystemUI/src/com/android/systemui/shade/PanelView.java b/packages/SystemUI/src/com/android/systemui/shade/PanelView.java
deleted file mode 100644
index 4349d81..0000000
--- a/packages/SystemUI/src/com/android/systemui/shade/PanelView.java
+++ /dev/null
@@ -1,75 +0,0 @@
-/*
- * Copyright (C) 2012 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.systemui.shade;
-
-import android.content.Context;
-import android.content.res.Configuration;
-import android.util.AttributeSet;
-import android.view.MotionEvent;
-import android.widget.FrameLayout;
-
-import com.android.systemui.statusbar.phone.CentralSurfaces;
-import com.android.systemui.statusbar.phone.HeadsUpManagerPhone;
-import com.android.systemui.statusbar.phone.KeyguardBottomAreaView;
-
-public abstract class PanelView extends FrameLayout {
- public static final boolean DEBUG = false;
- public static final String TAG = PanelView.class.getSimpleName();
- private NotificationPanelViewController.TouchHandler mTouchHandler;
-
- protected CentralSurfaces mCentralSurfaces;
- protected HeadsUpManagerPhone mHeadsUpManager;
-
- protected KeyguardBottomAreaView mKeyguardBottomArea;
- private OnConfigurationChangedListener mOnConfigurationChangedListener;
-
- public PanelView(Context context) {
- super(context);
- }
-
- public PanelView(Context context, AttributeSet attrs) {
- super(context, attrs);
- }
-
- public PanelView(Context context, AttributeSet attrs, int defStyleAttr) {
- super(context, attrs, defStyleAttr);
- }
-
- public void setOnTouchListener(NotificationPanelViewController.TouchHandler touchHandler) {
- super.setOnTouchListener(touchHandler);
- mTouchHandler = touchHandler;
- }
-
- public void setOnConfigurationChangedListener(OnConfigurationChangedListener listener) {
- mOnConfigurationChangedListener = listener;
- }
-
- @Override
- public boolean onInterceptTouchEvent(MotionEvent event) {
- return mTouchHandler.onInterceptTouchEvent(event);
- }
-
- @Override
- public void dispatchConfigurationChanged(Configuration newConfig) {
- super.dispatchConfigurationChanged(newConfig);
- mOnConfigurationChangedListener.onConfigurationChanged(newConfig);
- }
-
- interface OnConfigurationChangedListener {
- void onConfigurationChanged(Configuration newConfig);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
index b9684fc..3d161d9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/EmptyShadeView.java
@@ -24,6 +24,8 @@
import android.view.View;
import android.widget.TextView;
+import androidx.annotation.NonNull;
+
import com.android.systemui.R;
import com.android.systemui.statusbar.notification.row.StackScrollerDecorView;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
@@ -73,6 +75,7 @@
}
@Override
+ @NonNull
public ExpandableViewState createExpandableViewState() {
return new EmptyShadeViewState();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt
index 2ca1beb..7b49ecd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationInteractionTracker.kt
@@ -1,7 +1,6 @@
package com.android.systemui.statusbar
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.statusbar.notification.NotificationEntryManager
import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
import javax.inject.Inject
@@ -12,14 +11,12 @@
*/
@SysUISingleton
class NotificationInteractionTracker @Inject constructor(
- private val clicker: NotificationClickNotifier,
- private val entryManager: NotificationEntryManager
+ clicker: NotificationClickNotifier,
) : NotifCollectionListener, NotificationInteractionListener {
private val interactions = mutableMapOf<String, Boolean>()
init {
clicker.addNotificationInteractionListener(this)
- entryManager.addCollectionListener(this)
}
fun hasUserInteractedWith(key: String): Boolean {
@@ -38,5 +35,3 @@
interactions[key] = true
}
}
-
-private const val TAG = "NotificationInteractionTracker"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
index 2214287..cea3deb 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationShelf.java
@@ -29,6 +29,8 @@
import android.view.animation.Interpolator;
import android.view.animation.PathInterpolator;
+import androidx.annotation.NonNull;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.policy.SystemBarUtils;
import com.android.systemui.R;
@@ -153,6 +155,7 @@
}
@Override
+ @NonNull
public ExpandableViewState createExpandableViewState() {
return new ShelfState();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
index 8cb18a0..59022c0f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/InstantAppNotifier.java
@@ -50,7 +50,6 @@
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.messages.nano.SystemMessageProto.SystemMessage;
import com.android.systemui.CoreStartable;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.UiBackground;
@@ -76,20 +75,22 @@
private final Executor mUiBgExecutor;
private final ArraySet<Pair<String, Integer>> mCurrentNotifs = new ArraySet<>();
private final CommandQueue mCommandQueue;
- private KeyguardStateController mKeyguardStateController;
+ private final KeyguardStateController mKeyguardStateController;
@Inject
- public InstantAppNotifier(Context context, CommandQueue commandQueue,
- @UiBackground Executor uiBgExecutor) {
+ public InstantAppNotifier(
+ Context context,
+ CommandQueue commandQueue,
+ @UiBackground Executor uiBgExecutor,
+ KeyguardStateController keyguardStateController) {
super(context);
mCommandQueue = commandQueue;
mUiBgExecutor = uiBgExecutor;
+ mKeyguardStateController = keyguardStateController;
}
@Override
public void start() {
- mKeyguardStateController = Dependency.get(KeyguardStateController.class);
-
// listen for user / profile change.
try {
ActivityManager.getService().registerUserSwitchObserver(mUserSwitchListener, TAG);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
deleted file mode 100644
index c9c6f28..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationListController.java
+++ /dev/null
@@ -1,77 +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.systemui.statusbar.notification;
-
-import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
-
-import java.util.Objects;
-
-/**
- * Root controller for the list of notifications in the shade.
- *
- * TODO: Much of the code in NotificationPresenter should eventually move in here. It will proxy
- * domain-specific behavior (ARC, etc) to subcontrollers.
- */
-public class NotificationListController {
- private final NotificationEntryManager mEntryManager;
- private final NotificationListContainer mListContainer;
- private final DeviceProvisionedController mDeviceProvisionedController;
-
- public NotificationListController(
- NotificationEntryManager entryManager,
- NotificationListContainer listContainer,
- DeviceProvisionedController deviceProvisionedController) {
- mEntryManager = Objects.requireNonNull(entryManager);
- mListContainer = Objects.requireNonNull(listContainer);
- mDeviceProvisionedController = Objects.requireNonNull(deviceProvisionedController);
- }
-
- /**
- * Causes the controller to register listeners on its dependencies. This method must be called
- * before the controller is ready to perform its duties.
- */
- public void bind() {
- mEntryManager.addNotificationEntryListener(mEntryListener);
- mDeviceProvisionedController.addCallback(mDeviceProvisionedListener);
- }
-
- @SuppressWarnings("FieldCanBeLocal")
- private final NotificationEntryListener mEntryListener = new NotificationEntryListener() {
- @Override
- public void onEntryRemoved(
- NotificationEntry entry,
- NotificationVisibility visibility,
- boolean removedByUser,
- int reason) {
- mListContainer.cleanUpViewStateForEntry(entry);
- }
- };
-
- // TODO: (b/145659174) remove after moving to NewNotifPipeline. Replaced by
- // DeviceProvisionedCoordinator
- private final DeviceProvisionedListener mDeviceProvisionedListener =
- new DeviceProvisionedListener() {
- @Override
- public void onDeviceProvisionedChanged() {
- mEntryManager.updateNotifications("device provisioned changed");
- }
- };
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
index dbf4810..126a986 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationWakeUpCoordinator.kt
@@ -18,10 +18,8 @@
import android.animation.ObjectAnimator
import android.util.FloatProperty
-import com.android.systemui.Dumpable
import com.android.systemui.animation.Interpolators
import com.android.systemui.dagger.SysUISingleton
-import com.android.systemui.dump.DumpManager
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.notification.collection.NotificationEntry
@@ -34,20 +32,17 @@
import com.android.systemui.statusbar.phone.panelstate.PanelExpansionListener
import com.android.systemui.statusbar.policy.HeadsUpManager
import com.android.systemui.statusbar.policy.OnHeadsUpChangedListener
-import java.io.PrintWriter
import javax.inject.Inject
import kotlin.math.min
@SysUISingleton
class NotificationWakeUpCoordinator @Inject constructor(
- dumpManager: DumpManager,
private val mHeadsUpManager: HeadsUpManager,
private val statusBarStateController: StatusBarStateController,
private val bypassController: KeyguardBypassController,
private val dozeParameters: DozeParameters,
private val screenOffAnimationController: ScreenOffAnimationController
-) : OnHeadsUpChangedListener, StatusBarStateController.StateListener, PanelExpansionListener,
- Dumpable {
+) : OnHeadsUpChangedListener, StatusBarStateController.StateListener, PanelExpansionListener {
private val mNotificationVisibility = object : FloatProperty<NotificationWakeUpCoordinator>(
"notificationVisibility") {
@@ -65,7 +60,6 @@
private var mLinearDozeAmount: Float = 0.0f
private var mDozeAmount: Float = 0.0f
- private var mDozeAmountSource: String = "init"
private var mNotificationVisibleAmount = 0.0f
private var mNotificationsVisible = false
private var mNotificationsVisibleForExpansion = false
@@ -148,7 +142,6 @@
}
init {
- dumpManager.registerDumpable(this)
mHeadsUpManager.addListener(this)
statusBarStateController.addCallback(this)
addListener(object : WakeUpListener {
@@ -255,14 +248,13 @@
// Let's notify the scroller that an animation started
notifyAnimationStart(mLinearDozeAmount == 1.0f)
}
- setDozeAmount(linear, eased, source = "StatusBar")
+ setDozeAmount(linear, eased)
}
- fun setDozeAmount(linear: Float, eased: Float, source: String) {
+ fun setDozeAmount(linear: Float, eased: Float) {
val changed = linear != mLinearDozeAmount
mLinearDozeAmount = linear
mDozeAmount = eased
- mDozeAmountSource = source
mStackScrollerController.setDozeAmount(mDozeAmount)
updateHideAmount()
if (changed && linear == 0.0f) {
@@ -279,7 +271,7 @@
// undefined state, so it's an indication that we should do state cleanup. We override
// the doze amount to 0f (not dozing) so that the notifications are no longer hidden.
// See: UnlockedScreenOffAnimationController.onFinishedWakingUp()
- setDozeAmount(0f, 0f, source = "Override: Shade->Shade (lock cancelled by unlock)")
+ setDozeAmount(0f, 0f)
}
if (overrideDozeAmountIfAnimatingScreenOff(mLinearDozeAmount)) {
@@ -319,11 +311,12 @@
*/
private fun overrideDozeAmountIfBypass(): Boolean {
if (bypassController.bypassEnabled) {
- if (statusBarStateController.state == StatusBarState.KEYGUARD) {
- setDozeAmount(1f, 1f, source = "Override: bypass (keyguard)")
- } else {
- setDozeAmount(0f, 0f, source = "Override: bypass (shade)")
+ var amount = 1.0f
+ if (statusBarStateController.state == StatusBarState.SHADE ||
+ statusBarStateController.state == StatusBarState.SHADE_LOCKED) {
+ amount = 0.0f
}
+ setDozeAmount(amount, amount)
return true
}
return false
@@ -339,7 +332,7 @@
*/
private fun overrideDozeAmountIfAnimatingScreenOff(linearDozeAmount: Float): Boolean {
if (screenOffAnimationController.overrideNotificationsFullyDozingOnKeyguard()) {
- setDozeAmount(1f, 1f, source = "Override: animating screen off")
+ setDozeAmount(1f, 1f)
return true
}
@@ -433,24 +426,4 @@
*/
@JvmDefault fun onPulseExpansionChanged(expandingChanged: Boolean) {}
}
-
- override fun dump(pw: PrintWriter, args: Array<out String>) {
- pw.println("mLinearDozeAmount: $mLinearDozeAmount")
- pw.println("mDozeAmount: $mDozeAmount")
- pw.println("mDozeAmountSource: $mDozeAmountSource")
- pw.println("mNotificationVisibleAmount: $mNotificationVisibleAmount")
- pw.println("mNotificationsVisible: $mNotificationsVisible")
- pw.println("mNotificationsVisibleForExpansion: $mNotificationsVisibleForExpansion")
- pw.println("mVisibilityAmount: $mVisibilityAmount")
- pw.println("mLinearVisibilityAmount: $mLinearVisibilityAmount")
- pw.println("pulseExpanding: $pulseExpanding")
- pw.println("state: ${StatusBarState.toString(state)}")
- pw.println("fullyAwake: $fullyAwake")
- pw.println("wakingUp: $wakingUp")
- pw.println("willWakeUp: $willWakeUp")
- pw.println("collapsedEnoughToHide: $collapsedEnoughToHide")
- pw.println("pulsing: $pulsing")
- pw.println("notificationsFullyHidden: $notificationsFullyHidden")
- pw.println("canShowPulsingHuns: $canShowPulsingHuns")
- }
-}
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
index 0e9f1cd..d38b6f9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/init/NotificationsControllerImpl.kt
@@ -26,19 +26,19 @@
import com.android.systemui.statusbar.notification.NotificationActivityStarter
import com.android.systemui.statusbar.notification.NotificationClicker
import com.android.systemui.statusbar.notification.NotificationEntryManager
-import com.android.systemui.statusbar.notification.NotificationListController
import com.android.systemui.statusbar.notification.collection.NotifLiveDataStore
import com.android.systemui.statusbar.notification.collection.NotifPipeline
+import com.android.systemui.statusbar.notification.collection.NotificationEntry
import com.android.systemui.statusbar.notification.collection.TargetSdkResolver
import com.android.systemui.statusbar.notification.collection.inflation.NotificationRowBinderImpl
import com.android.systemui.statusbar.notification.collection.init.NotifPipelineInitializer
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection
+import com.android.systemui.statusbar.notification.collection.notifcollection.NotifCollectionListener
import com.android.systemui.statusbar.notification.collection.render.NotifStackController
import com.android.systemui.statusbar.notification.interruption.HeadsUpViewBinder
import com.android.systemui.statusbar.notification.row.NotifBindPipelineInitializer
import com.android.systemui.statusbar.notification.stack.NotificationListContainer
import com.android.systemui.statusbar.phone.CentralSurfaces
-import com.android.systemui.statusbar.policy.DeviceProvisionedController
import com.android.wm.shell.bubbles.Bubbles
import dagger.Lazy
import java.io.PrintWriter
@@ -63,7 +63,6 @@
private val targetSdkResolver: TargetSdkResolver,
private val notifPipelineInitializer: Lazy<NotifPipelineInitializer>,
private val notifBindPipelineInitializer: NotifBindPipelineInitializer,
- private val deviceProvisionedController: DeviceProvisionedController,
private val notificationRowBinder: NotificationRowBinderImpl,
private val headsUpViewBinder: HeadsUpViewBinder,
private val clickerBuilder: NotificationClicker.Builder,
@@ -81,12 +80,11 @@
) {
notificationListener.registerAsSystemService()
- val listController =
- NotificationListController(
- entryManager,
- listContainer,
- deviceProvisionedController)
- listController.bind()
+ notifPipeline.get().addCollectionListener(object : NotifCollectionListener {
+ override fun onEntryRemoved(entry: NotificationEntry, reason: Int) {
+ listContainer.cleanUpViewStateForEntry(entry)
+ }
+ })
notificationRowBinder.setNotificationClicker(
clickerBuilder.build(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
index 855390d..8574f87 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableNotificationRow.java
@@ -25,8 +25,6 @@
import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.animation.ValueAnimator.AnimatorUpdateListener;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
import android.app.INotificationManager;
import android.app.Notification;
import android.app.NotificationChannel;
@@ -68,6 +66,9 @@
import android.widget.FrameLayout;
import android.widget.ImageView;
+import androidx.annotation.NonNull;
+import androidx.annotation.Nullable;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
@@ -3247,6 +3248,7 @@
}
@Override
+ @NonNull
public ExpandableViewState createExpandableViewState() {
return new NotificationViewState();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
index 8f73b80..1e09b8a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/ExpandableView.java
@@ -29,6 +29,7 @@
import android.view.ViewParent;
import android.widget.FrameLayout;
+import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.android.systemui.Dumpable;
@@ -66,7 +67,7 @@
protected float mContentTransformationAmount;
protected boolean mIsLastChild;
protected int mContentShift;
- private final ExpandableViewState mViewState;
+ @NonNull private final ExpandableViewState mViewState;
private float mContentTranslation;
protected boolean mLastInSection;
protected boolean mFirstInSection;
@@ -610,6 +611,7 @@
public void setActualHeightAnimating(boolean animating) {}
+ @NonNull
protected ExpandableViewState createExpandableViewState() {
return new ExpandableViewState();
}
@@ -642,7 +644,12 @@
return mViewState;
}
- @Nullable public ExpandableViewState getViewState() {
+ /**
+ * Get the {@link ExpandableViewState} associated with the view.
+ *
+ * @return the ExpandableView's view state.
+ */
+ @NonNull public ExpandableViewState getViewState() {
return mViewState;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
index e43ecf7..49dc655 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/FooterView.java
@@ -23,6 +23,8 @@
import android.util.IndentingPrintWriter;
import android.view.View;
+import androidx.annotation.NonNull;
+
import com.android.systemui.R;
import com.android.systemui.statusbar.notification.stack.ExpandableViewState;
import com.android.systemui.statusbar.notification.stack.ViewState;
@@ -142,6 +144,7 @@
}
@Override
+ @NonNull
public ExpandableViewState createExpandableViewState() {
return new FooterViewState();
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java
deleted file mode 100644
index 6abfee9..0000000
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManager.java
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (C) 2018 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.systemui.statusbar.notification.row;
-
-import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
-
-import android.content.Context;
-import android.metrics.LogMaker;
-import android.util.Log;
-
-import androidx.annotation.VisibleForTesting;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
-import com.android.systemui.statusbar.notification.dagger.NotificationsModule;
-import com.android.systemui.statusbar.notification.logging.NotificationCounters;
-import com.android.systemui.util.Compile;
-
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Set;
-
-/**
- * Manager for the notification blocking helper - tracks and helps create the blocking helper
- * affordance.
- */
-public class NotificationBlockingHelperManager {
- /** Enables debug logging and always makes the blocking helper show up after a dismiss. */
- private static final String TAG = "BlockingHelper";
- private static final boolean DEBUG = Compile.IS_DEBUG && Log.isLoggable(TAG, Log.DEBUG);
- private static final boolean DEBUG_ALWAYS_SHOW = false;
-
- private final Context mContext;
- private final NotificationGutsManager mNotificationGutsManager;
- private final NotificationEntryManager mNotificationEntryManager;
- private final MetricsLogger mMetricsLogger;
- private final GroupMembershipManager mGroupMembershipManager;
- /** Row that the blocking helper will be shown in (via {@link NotificationGuts}. */
- private ExpandableNotificationRow mBlockingHelperRow;
- private Set<String> mNonBlockablePkgs;
-
- /**
- * Whether the notification shade/stack is expanded - used to determine blocking helper
- * eligibility.
- */
- private boolean mIsShadeExpanded;
-
- /**
- * Injected constructor. See {@link NotificationsModule}.
- */
- public NotificationBlockingHelperManager(
- Context context,
- NotificationGutsManager notificationGutsManager,
- NotificationEntryManager notificationEntryManager,
- MetricsLogger metricsLogger,
- GroupMembershipManager groupMembershipManager) {
- mContext = context;
- mNotificationGutsManager = notificationGutsManager;
- mNotificationEntryManager = notificationEntryManager;
- mMetricsLogger = metricsLogger;
- mNonBlockablePkgs = new HashSet<>();
- Collections.addAll(mNonBlockablePkgs, mContext.getResources().getStringArray(
- com.android.internal.R.array.config_nonBlockableNotificationPackages));
- mGroupMembershipManager = groupMembershipManager;
- }
-
- /**
- * Potentially shows the blocking helper, represented via the {@link NotificationInfo} menu
- * item, in the current row if user sentiment is negative.
- *
- * @param row row to render the blocking helper in
- * @param menuRow menu used to generate the {@link NotificationInfo} view that houses the
- * blocking helper UI
- * @return whether we're showing a blocking helper in the given notification row
- */
- boolean perhapsShowBlockingHelper(
- ExpandableNotificationRow row, NotificationMenuRowPlugin menuRow) {
- // We only show the blocking helper if:
- // - User sentiment is negative (DEBUG flag can bypass)
- // - The notification shade is fully expanded (guarantees we're not touching a HUN).
- // - The row is blockable (i.e. not non-blockable)
- // - The dismissed row is a valid group (>1 or 0 children from the same channel)
- // or the only child in the group
- final NotificationEntry entry = row.getEntry();
- if ((entry.getUserSentiment() == USER_SENTIMENT_NEGATIVE || DEBUG_ALWAYS_SHOW)
- && mIsShadeExpanded
- && !row.getIsNonblockable()
- && ((!row.isChildInGroup() || mGroupMembershipManager.isOnlyChildInGroup(entry))
- && row.getNumUniqueChannels() <= 1)) {
- // Dismiss any current blocking helper before continuing forward (only one can be shown
- // at a given time).
- dismissCurrentBlockingHelper();
-
- if (DEBUG) {
- Log.d(TAG, "Manager.perhapsShowBlockingHelper: Showing new blocking helper");
- }
-
- // Enable blocking helper on the row before moving forward so everything in the guts is
- // correctly prepped.
- mBlockingHelperRow = row;
- mBlockingHelperRow.setBlockingHelperShowing(true);
-
- // Log triggering of blocking helper by the system. This log line
- // should be emitted before the "display" log line.
- mMetricsLogger.write(
- getLogMaker().setSubtype(MetricsEvent.BLOCKING_HELPER_TRIGGERED_BY_SYSTEM));
-
- // We don't care about the touch origin (x, y) since we're opening guts without any
- // explicit user interaction.
- mNotificationGutsManager.openGuts(
- mBlockingHelperRow, 0, 0, menuRow.getLongpressMenuItem(mContext));
-
- mMetricsLogger.count(NotificationCounters.BLOCKING_HELPER_SHOWN, 1);
- return true;
- }
- return false;
- }
-
- /**
- * Dismiss the currently showing blocking helper, if any, through a notification update.
- *
- * @return whether the blocking helper was dismissed
- */
- boolean dismissCurrentBlockingHelper() {
- if (!isBlockingHelperRowNull()) {
- if (DEBUG) {
- Log.d(TAG, "Manager.dismissCurrentBlockingHelper: Dismissing current helper");
- }
- if (!mBlockingHelperRow.isBlockingHelperShowing()) {
- Log.e(TAG, "Manager.dismissCurrentBlockingHelper: "
- + "Non-null row is not showing a blocking helper");
- }
-
- mBlockingHelperRow.setBlockingHelperShowing(false);
- if (mBlockingHelperRow.isAttachedToWindow()) {
- mNotificationEntryManager.updateNotifications("dismissCurrentBlockingHelper");
- }
- mBlockingHelperRow = null;
- return true;
- }
- return false;
- }
-
- /**
- * Update the expansion status of the notification shade/stack.
- *
- * @param expandedHeight how much the shade is expanded ({code 0} indicating it's collapsed)
- */
- public void setNotificationShadeExpanded(float expandedHeight) {
- mIsShadeExpanded = expandedHeight > 0.0f;
- }
-
- /**
- * Returns whether the given package name is in the list of non-blockable packages.
- */
- public boolean isNonblockable(String packageName, String channelName) {
- return mNonBlockablePkgs.contains(packageName)
- || mNonBlockablePkgs.contains(makeChannelKey(packageName, channelName));
- }
-
- private LogMaker getLogMaker() {
- return mBlockingHelperRow.getEntry().getSbn()
- .getLogMaker()
- .setCategory(MetricsEvent.NOTIFICATION_BLOCKING_HELPER);
- }
-
- // Format must stay in sync with frameworks/base/core/res/res/values/config.xml
- // config_nonBlockableNotificationPackages
- private String makeChannelKey(String pkg, String channel) {
- return pkg + ":" + channel;
- }
-
- @VisibleForTesting
- boolean isBlockingHelperRowNull() {
- return mBlockingHelperRow == null;
- }
-
- @VisibleForTesting
- void setBlockingHelperRowForTest(ExpandableNotificationRow blockingHelperRowForTest) {
- mBlockingHelperRow = blockingHelperRowForTest;
- }
-
- @VisibleForTesting
- void setNonBlockablePkgs(String[] pkgsAndChannels) {
- mNonBlockablePkgs = new HashSet<>();
- Collections.addAll(mNonBlockablePkgs, pkgsAndChannels);
- }
-}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
index cc87499..1fb265f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayout.java
@@ -4460,8 +4460,7 @@
}
private void updateVisibility() {
- boolean shouldShow = !mAmbientState.isFullyHidden() || !onKeyguard();
- setVisibility(shouldShow ? View.VISIBLE : View.INVISIBLE);
+ mController.updateVisibility(!mAmbientState.isFullyHidden() || !onKeyguard());
}
@ShadeViewRefactor(RefactorComponent.STATE_RESOLVER)
@@ -4526,17 +4525,21 @@
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
- void updateEmptyShadeView(boolean visible, boolean notifVisibleInShade) {
+ void updateEmptyShadeView(boolean visible, boolean areNotificationsHiddenInShade) {
mEmptyShadeView.setVisible(visible, mIsExpanded && mAnimationsEnabled);
int oldTextRes = mEmptyShadeView.getTextResource();
- int newTextRes = notifVisibleInShade
+ int newTextRes = areNotificationsHiddenInShade
? R.string.dnd_suppressing_shade_text : R.string.empty_shade_text;
if (oldTextRes != newTextRes) {
mEmptyShadeView.setText(newTextRes);
}
}
+ public boolean isEmptyShadeViewVisible() {
+ return mEmptyShadeView.isVisible();
+ }
+
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
public void updateFooterView(boolean visible, boolean showDismissView, boolean showHistory) {
if (mFooterView == null) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
index e6eceb5..ec1e620 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/NotificationStackScrollLayoutController.java
@@ -177,7 +177,6 @@
private NotificationStackScrollLayout mView;
private boolean mFadeNotificationsOnDismiss;
private NotificationSwipeHelper mSwipeHelper;
- private boolean mShowEmptyShadeView;
@Nullable private Boolean mHistoryEnabled;
private int mBarState;
private HeadsUpAppearanceController mHeadsUpAppearanceController;
@@ -1173,8 +1172,21 @@
}
/**
- * Update whether we should show the empty shade view (no notifications in the shade).
- * If so, send the update to our view.
+ * Set the visibility of the view, and propagate it to specific children.
+ *
+ * @param visible either the view is visible or not.
+ */
+ public void updateVisibility(boolean visible) {
+ mView.setVisibility(visible ? View.VISIBLE : View.INVISIBLE);
+
+ if (mView.getVisibility() == View.VISIBLE) {
+ // Synchronize EmptyShadeView visibility with the parent container.
+ updateShowEmptyShadeView();
+ }
+ }
+
+ /**
+ * Update whether we should show the empty shade view ("no notifications" in the shade).
*
* When in split mode, notifications are always visible regardless of the state of the
* QuickSettings panel. That being the case, empty view is always shown if the other conditions
@@ -1182,18 +1194,31 @@
*/
public void updateShowEmptyShadeView() {
Trace.beginSection("NSSLC.updateShowEmptyShadeView");
- mShowEmptyShadeView = mStatusBarStateController.getCurrentOrUpcomingState() != KEYGUARD
- && !mView.isQsFullScreen()
- && getVisibleNotificationCount() == 0;
- mView.updateEmptyShadeView(
- mShowEmptyShadeView,
- mZenModeController.areNotificationsHiddenInShade());
+ final boolean shouldShow = getVisibleNotificationCount() == 0
+ && !mView.isQsFullScreen()
+ // Hide empty shade view when in transition to Keyguard.
+ // That avoids "No Notifications" to blink when transitioning to AOD.
+ // For more details, see: b/228790482
+ && !isInTransitionToKeyguard();
+
+ mView.updateEmptyShadeView(shouldShow, mZenModeController.areNotificationsHiddenInShade());
+
Trace.endSection();
}
+ /**
+ * @return true if {@link StatusBarStateController} is in transition to the KEYGUARD
+ * and false otherwise.
+ */
+ private boolean isInTransitionToKeyguard() {
+ final int currentState = mStatusBarStateController.getState();
+ final int upcomingState = mStatusBarStateController.getCurrentOrUpcomingState();
+ return (currentState != upcomingState && upcomingState == KEYGUARD);
+ }
+
public boolean isShowingEmptyShadeView() {
- return mShowEmptyShadeView;
+ return mView.isEmptyShadeViewVisible();
}
public void setHeadsUpAnimatingAway(boolean headsUpAnimatingAway) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
index 6d513d0da..353355b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithm.java
@@ -120,11 +120,64 @@
updateClipping(algorithmState, ambientState);
updateSpeedBumpState(algorithmState, speedBumpIndex);
updateShelfState(algorithmState, ambientState);
+ updateAlphaState(algorithmState, ambientState);
getNotificationChildrenStates(algorithmState, ambientState);
}
+ private void updateAlphaState(StackScrollAlgorithmState algorithmState,
+ AmbientState ambientState) {
+ for (ExpandableView view : algorithmState.visibleChildren) {
+ final ViewState viewState = view.getViewState();
+
+ final boolean isHunGoingToShade = ambientState.isShadeExpanded()
+ && view == ambientState.getTrackedHeadsUpRow();
+
+ if (isHunGoingToShade) {
+ // Keep 100% opacity for heads up notification going to shade.
+ viewState.alpha = 1f;
+ } else if (ambientState.isOnKeyguard()) {
+ // Adjust alpha for wakeup to lockscreen.
+ viewState.alpha = 1f - ambientState.getHideAmount();
+ } else if (ambientState.isExpansionChanging()) {
+ // Adjust alpha for shade open & close.
+ float expansion = ambientState.getExpansionFraction();
+ viewState.alpha = ambientState.isBouncerInTransit()
+ ? BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion)
+ : ShadeInterpolation.getContentAlpha(expansion);
+ }
+
+ // For EmptyShadeView if on keyguard, we need to control the alpha to create
+ // a nice transition when the user is dragging down the notification panel.
+ if (view instanceof EmptyShadeView && ambientState.isOnKeyguard()) {
+ final float fractionToShade = ambientState.getFractionToShade();
+ viewState.alpha = ShadeInterpolation.getContentAlpha(fractionToShade);
+ }
+
+ NotificationShelf shelf = ambientState.getShelf();
+ if (shelf != null) {
+ final ViewState shelfState = shelf.getViewState();
+
+ // After the shelf has updated its yTranslation, explicitly set alpha=0 for view
+ // below shelf to skip rendering them in the hardware layer. We do not set them
+ // invisible because that runs invalidate & onDraw when these views return onscreen,
+ // which is more expensive.
+ if (shelfState.hidden) {
+ // When the shelf is hidden, it won't clip views, so we don't hide rows
+ return;
+ }
+
+ final float shelfTop = shelfState.yTranslation;
+ final float viewTop = viewState.yTranslation;
+ if (viewTop >= shelfTop) {
+ viewState.alpha = 0;
+ }
+ }
+ }
+ }
+
/**
* How expanded or collapsed notifications are when pulling down the shade.
+ *
* @param ambientState Current ambient state.
* @return 0 when fully collapsed, 1 when expanded.
*/
@@ -208,22 +261,6 @@
}
shelf.updateState(algorithmState, ambientState);
-
- // After the shelf has updated its yTranslation, explicitly set alpha=0 for view below shelf
- // to skip rendering them in the hardware layer. We do not set them invisible because that
- // runs invalidate & onDraw when these views return onscreen, which is more expensive.
- if (shelf.getViewState().hidden) {
- // When the shelf is hidden, it won't clip views, so we don't hide rows
- return;
- }
- final float shelfTop = shelf.getViewState().yTranslation;
-
- for (ExpandableView view : algorithmState.visibleChildren) {
- final float viewTop = view.getViewState().yTranslation;
- if (viewTop >= shelfTop) {
- view.getViewState().alpha = 0;
- }
- }
}
private void updateClipping(StackScrollAlgorithmState algorithmState,
@@ -473,21 +510,6 @@
ExpandableViewState viewState = view.getViewState();
viewState.location = ExpandableViewState.LOCATION_UNKNOWN;
- final boolean isHunGoingToShade = ambientState.isShadeExpanded()
- && view == ambientState.getTrackedHeadsUpRow();
- if (isHunGoingToShade) {
- // Keep 100% opacity for heads up notification going to shade.
- } else if (ambientState.isOnKeyguard()) {
- // Adjust alpha for wakeup to lockscreen.
- viewState.alpha = 1f - ambientState.getHideAmount();
- } else if (ambientState.isExpansionChanging()) {
- // Adjust alpha for shade open & close.
- float expansion = ambientState.getExpansionFraction();
- viewState.alpha = ambientState.isBouncerInTransit()
- ? BouncerPanelExpansionCalculator.aboutToShowBouncerProgress(expansion)
- : ShadeInterpolation.getContentAlpha(expansion);
- }
-
final float expansionFraction = getExpansionFractionWithoutShelf(
algorithmState, ambientState);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
index 747c4de..52a45d6 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesCommandQueueCallbacks.java
@@ -55,7 +55,6 @@
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.keyguard.WakefulnessLifecycle;
import com.android.systemui.qs.QSPanelController;
-import com.android.systemui.shade.NotificationPanelView;
import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.shade.ShadeController;
import com.android.systemui.statusbar.CommandQueue;
@@ -326,12 +325,12 @@
mNotificationPanelViewController.expand(true /* animate */);
mNotificationStackScrollLayoutController.setWillExpand(true);
mHeadsUpManager.unpinAll(true /* userUnpinned */);
- mMetricsLogger.count(NotificationPanelView.COUNTER_PANEL_OPEN, 1);
+ mMetricsLogger.count("panel_open", 1);
} else if (!mNotificationPanelViewController.isInSettings()
&& !mNotificationPanelViewController.isExpanding()) {
mNotificationPanelViewController.flingSettings(0 /* velocity */,
- NotificationPanelView.FLING_EXPAND);
- mMetricsLogger.count(NotificationPanelView.COUNTER_PANEL_OPEN_QS, 1);
+ NotificationPanelViewController.FLING_EXPAND);
+ mMetricsLogger.count("panel_open_qs", 1);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index ed186ab..8273d57 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -33,7 +33,6 @@
import androidx.annotation.VisibleForTesting;
import com.android.internal.statusbar.StatusBarIcon;
-import com.android.systemui.Dependency;
import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.demomode.DemoModeCommandReceiver;
@@ -137,11 +136,12 @@
LinearLayout linearLayout,
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
- Provider<WifiViewModel> wifiViewModelProvider) {
+ Provider<WifiViewModel> wifiViewModelProvider,
+ DarkIconDispatcher darkIconDispatcher) {
super(linearLayout, featureFlags, statusBarPipelineFlags, wifiViewModelProvider);
mIconHPadding = mContext.getResources().getDimensionPixelSize(
R.dimen.status_bar_icon_padding);
- mDarkIconDispatcher = Dependency.get(DarkIconDispatcher.class);
+ mDarkIconDispatcher = darkIconDispatcher;
}
@Override
@@ -198,20 +198,24 @@
private final FeatureFlags mFeatureFlags;
private final StatusBarPipelineFlags mStatusBarPipelineFlags;
private final Provider<WifiViewModel> mWifiViewModelProvider;
+ private final DarkIconDispatcher mDarkIconDispatcher;
@Inject
public Factory(
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
- Provider<WifiViewModel> wifiViewModelProvider) {
+ Provider<WifiViewModel> wifiViewModelProvider,
+ DarkIconDispatcher darkIconDispatcher) {
mFeatureFlags = featureFlags;
mStatusBarPipelineFlags = statusBarPipelineFlags;
mWifiViewModelProvider = wifiViewModelProvider;
+ mDarkIconDispatcher = darkIconDispatcher;
}
public DarkIconManager create(LinearLayout group) {
return new DarkIconManager(
- group, mFeatureFlags, mStatusBarPipelineFlags, mWifiViewModelProvider);
+ group, mFeatureFlags, mStatusBarPipelineFlags, mWifiViewModelProvider,
+ mDarkIconDispatcher);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
index 7765427..103f3fc 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepository.kt
@@ -46,7 +46,7 @@
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.flowOf
-import kotlinx.coroutines.flow.shareIn
+import kotlinx.coroutines.flow.stateIn
/**
* Provides data related to the wifi state.
@@ -118,12 +118,19 @@
}
}
- trySend(WIFI_NETWORK_DEFAULT)
connectivityManager.registerNetworkCallback(WIFI_NETWORK_CALLBACK_REQUEST, callback)
awaitClose { connectivityManager.unregisterNetworkCallback(callback) }
}
- .shareIn(scope, started = SharingStarted.WhileSubscribed())
+ // There will be multiple wifi icons in different places that will frequently
+ // subscribe/unsubscribe to flows as the views attach/detach. Using [stateIn] ensures that
+ // new subscribes will get the latest value immediately upon subscription. Otherwise, the
+ // views could show stale data. See b/244173280.
+ .stateIn(
+ scope,
+ started = SharingStarted.WhileSubscribed(),
+ initialValue = WIFI_NETWORK_DEFAULT
+ )
override val wifiActivity: Flow<WifiActivityModel> =
if (wifiManager == null) {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
index 90609fa..df10dfe 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/ScreenDecorationsTest.java
@@ -16,7 +16,6 @@
import static android.view.DisplayCutout.BOUNDS_POSITION_BOTTOM;
import static android.view.DisplayCutout.BOUNDS_POSITION_LEFT;
-import static android.view.DisplayCutout.BOUNDS_POSITION_LENGTH;
import static android.view.DisplayCutout.BOUNDS_POSITION_RIGHT;
import static android.view.DisplayCutout.BOUNDS_POSITION_TOP;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY;
@@ -36,6 +35,7 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isA;
+import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -49,7 +49,6 @@
import android.content.pm.PackageManager;
import android.content.res.Configuration;
import android.content.res.TypedArray;
-import android.graphics.Insets;
import android.graphics.Path;
import android.graphics.PixelFormat;
import android.graphics.Rect;
@@ -60,7 +59,6 @@
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.testing.TestableLooper.RunWithLooper;
-import android.util.RotationUtils;
import android.util.Size;
import android.view.Display;
import android.view.DisplayCutout;
@@ -80,6 +78,8 @@
import com.android.systemui.biometrics.AuthController;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.decor.CornerDecorProvider;
+import com.android.systemui.decor.CutoutDecorProviderFactory;
+import com.android.systemui.decor.CutoutDecorProviderImpl;
import com.android.systemui.decor.DecorProvider;
import com.android.systemui.decor.DecorProviderFactory;
import com.android.systemui.decor.FaceScanningOverlayProviderImpl;
@@ -157,6 +157,9 @@
@Mock
private DisplayInfo mDisplayInfo;
private PrivacyDotViewController.ShowingListener mPrivacyDotShowingListener;
+ @Mock
+ private CutoutDecorProviderFactory mCutoutFactory;
+ private List<DecorProvider> mMockCutoutList;
@Before
public void setup() {
@@ -206,6 +209,11 @@
DisplayCutout.BOUNDS_POSITION_RIGHT,
R.layout.privacy_dot_bottom_right));
+ // Default no cutout
+ mMockCutoutList = new ArrayList<>();
+ doAnswer(it -> !(mMockCutoutList.isEmpty())).when(mCutoutFactory).getHasProviders();
+ doReturn(mMockCutoutList).when(mCutoutFactory).getProviders();
+
mFaceScanningDecorProvider = spy(new FaceScanningOverlayProviderImpl(
BOUNDS_POSITION_TOP,
mAuthController,
@@ -239,6 +247,11 @@
super.updateOverlayWindowVisibilityIfViewExists(view);
mExecutor.runAllReady();
}
+
+ @Override
+ protected CutoutDecorProviderFactory getCutoutFactory() {
+ return ScreenDecorationsTest.this.mCutoutFactory;
+ }
});
mScreenDecorations.mDisplayInfo = mDisplayInfo;
doReturn(1f).when(mScreenDecorations).getPhysicalPixelDisplaySizeRatio();
@@ -429,11 +442,9 @@
public void testNoRounding_NoCutout_NoPrivacyDot_NoFaceScanning() {
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, false /* fillCutout */, false /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
- // no cutout
- doReturn(null).when(mScreenDecorations).getCutout();
+ // no cutout (default)
mScreenDecorations.start();
// No views added.
@@ -448,11 +459,9 @@
public void testNoRounding_NoCutout_PrivacyDot_NoFaceScanning() {
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
- // no cutout
- doReturn(null).when(mScreenDecorations).getCutout();
+ // no cutout (default)
mScreenDecorations.start();
@@ -484,11 +493,9 @@
public void testRounding_NoCutout_NoPrivacyDot_NoFaceScanning() {
setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 20 /* roundedPadding */, false /* fillCutout */, false /* privacyDot */,
- false /* faceScanning */);
+ 20 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
- // no cutout
- doReturn(null).when(mScreenDecorations).getCutout();
+ // no cutout (default)
mScreenDecorations.start();
@@ -516,11 +523,9 @@
public void testRounding_NoCutout_PrivacyDot_NoFaceScanning() {
setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 20 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
- false /* faceScanning */);
+ 20 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
- // no cutout
- doReturn(null).when(mScreenDecorations).getCutout();
+ // no cutout (default)
mScreenDecorations.start();
@@ -555,10 +560,9 @@
/* roundedTopDrawable */,
getTestsDrawable(com.android.systemui.tests.R.drawable.rounded3px)
/* roundedBottomDrawable */,
- 0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
- false /* faceScanning */);
- // no cutout
- doReturn(null).when(mScreenDecorations).getCutout();
+ 0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
+
+ // no cutout (default)
mScreenDecorations.start();
// Size of corner view should same as rounded_corner_radius{_top|_bottom}
@@ -574,11 +578,9 @@
/* roundedTopDrawable */,
getTestsDrawable(com.android.systemui.tests.R.drawable.rounded3px)
/* roundedBottomDrawable */,
- 0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
- // no cutout
- doReturn(null).when(mScreenDecorations).getCutout();
+ // no cutout (default)
mScreenDecorations.start();
View leftRoundedCorner = mScreenDecorations.mOverlays[BOUNDS_POSITION_TOP].getRootView()
@@ -611,13 +613,10 @@
/* roundedTopDrawable */,
getTestsDrawable(com.android.systemui.tests.R.drawable.rounded5px)
/* roundedBottomDrawable */,
- 0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
// left cutout
- final Rect[] bounds = {new Rect(0, 50, 1, 60), null, null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(1, 0, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
mScreenDecorations.start();
View topRoundedCorner = mScreenDecorations.mOverlays[BOUNDS_POSITION_LEFT].getRootView()
@@ -647,13 +646,10 @@
public void testNoRounding_CutoutShortEdge_NoPrivacyDot() {
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
// top cutout
- final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
mScreenDecorations.start();
// Top window is created for top cutout.
@@ -671,13 +667,10 @@
public void testNoRounding_CutoutShortEdge_PrivacyDot() {
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
// top cutout
- final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
mScreenDecorations.start();
// Top window is created for top cutout.
@@ -706,13 +699,10 @@
public void testNoRounding_CutoutLongEdge_NoPrivacyDot() {
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
// left cutout
- final Rect[] bounds = {new Rect(0, 50, 1, 60), null, null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(1, 0, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
mScreenDecorations.start();
// Left window is created for left cutout.
@@ -734,13 +724,10 @@
public void testNoRounding_CutoutLongEdge_PrivacyDot() {
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
// left cutout
- final Rect[] bounds = {new Rect(0, 50, 1, 60), null, null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(1, 0, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
mScreenDecorations.start();
// Left window is created for left cutout.
@@ -762,13 +749,10 @@
public void testRounding_CutoutShortEdge_NoPrivacyDot() {
setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 20 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
- false /* faceScanning */);
+ 20 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
// top cutout
- final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
mScreenDecorations.start();
// Top window is created for rounded corner and top cutout.
@@ -791,13 +775,10 @@
public void testRounding_CutoutShortEdge_PrivacyDot() {
setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 20 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
- false /* faceScanning */);
+ 20 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
// top cutout
- final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
mScreenDecorations.start();
// Top window is created for rounded corner and top cutout.
@@ -823,13 +804,10 @@
public void testRounding_CutoutLongEdge_NoPrivacyDot() {
setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 20 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
- false /* faceScanning */);
+ 20 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
// left cutout
- final Rect[] bounds = {new Rect(0, 50, 1, 60), null, null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(1, 0, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
mScreenDecorations.start();
// Left window is created for rounded corner and left cutout.
@@ -842,13 +820,10 @@
public void testRounding_CutoutLongEdge_PrivacyDot() {
setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 20 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
- false /* faceScanning */);
+ 20 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
// left cutout
- final Rect[] bounds = {new Rect(0, 50, 1, 60), null, null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(1, 0, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
mScreenDecorations.start();
// Left window is created for rounded corner, left cutout, and privacy.
@@ -863,13 +838,11 @@
public void testRounding_CutoutShortAndLongEdge_NoPrivacyDot() {
setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 20 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
- false /* faceScanning */);
+ 20 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
// top and left cutout
- final Rect[] bounds = {new Rect(0, 50, 1, 60), new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(1, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
mScreenDecorations.start();
// Top window is created for rounded corner and top cutout.
@@ -883,13 +856,11 @@
public void testRounding_CutoutShortAndLongEdge_PrivacyDot() {
setupResources(20 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 20 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
- false /* faceScanning */);
+ 20 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
// top and left cutout
- final Rect[] bounds = {new Rect(0, 50, 1, 60), new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(1, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
mScreenDecorations.start();
// Top window is created for rounded corner and top cutout.
@@ -905,21 +876,16 @@
public void testNoRounding_SwitchFrom_ShortEdgeCutout_To_LongCutout_NoPrivacyDot() {
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
// Set to short edge cutout(top).
- final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
mScreenDecorations.start();
verifyOverlaysExistAndAdded(false, true, false, false, View.VISIBLE);
// Switch to long edge cutout(left).
- final Rect[] newBounds = {new Rect(0, 50, 1, 60), null, null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(1, 0, 0, 0), newBounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.set(0, new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
mScreenDecorations.onConfigurationChanged(new Configuration());
verifyOverlaysExistAndAdded(true, false, false, false, View.VISIBLE);
@@ -929,13 +895,10 @@
public void testNoRounding_SwitchFrom_ShortEdgeCutout_To_LongCutout_PrivacyDot() {
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
// Set to short edge cutout(top).
- final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
mScreenDecorations.start();
verifyOverlaysExistAndAdded(false, true, false, true, View.VISIBLE);
@@ -943,9 +906,7 @@
verify(mDotViewController, times(1)).setShowingListener(null);
// Switch to long edge cutout(left).
- final Rect[] newBounds = {new Rect(0, 50, 1, 60), null, null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(1, 0, 0, 0), newBounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.set(0, new CutoutDecorProviderImpl(BOUNDS_POSITION_LEFT));
mScreenDecorations.onConfigurationChanged(new Configuration());
verifyOverlaysExistAndAdded(true, false, true, false, View.VISIBLE);
@@ -973,20 +934,16 @@
public void testDelayedCutout_NoPrivacyDot() {
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, false /* fillCutout */, false /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
- // top cutout
- final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ // No cutout (default)
mScreenDecorations.start();
verifyOverlaysExistAndAdded(false, false, false, false, null);
- when(mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout))
- .thenReturn(true);
+ // top cutout
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+
mScreenDecorations.onConfigurationChanged(new Configuration());
// Only top windows should be added.
@@ -997,13 +954,9 @@
public void testDelayedCutout_PrivacyDot() {
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
- // top cutout
- final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ // no cutout (default)
mScreenDecorations.start();
// Both top and bottom windows should be added with INVISIBLE because of only privacy dot,
@@ -1015,9 +968,9 @@
verify(mDotViewController, times(1)).setShowingListener(
mScreenDecorations.mPrivacyDotShowingListener);
- when(mContext.getResources().getBoolean(
- com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout))
- .thenReturn(true);
+ // top cutout
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
+
mScreenDecorations.onConfigurationChanged(new Configuration());
// Both top and bottom windows should be added with VISIBLE because of privacy dot and
@@ -1043,8 +996,7 @@
/* roundedTopDrawable */,
getTestsDrawable(com.android.systemui.tests.R.drawable.rounded4px)
/* roundedBottomDrawable */,
- 0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
- false /* faceScanning*/);
+ 0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning*/);
mDisplayInfo.rotation = Surface.ROTATION_0;
mScreenDecorations.start();
@@ -1058,8 +1010,7 @@
/* roundedTopDrawable */,
getTestsDrawable(com.android.systemui.tests.R.drawable.rounded5px)
/* roundedBottomDrawable */,
- 0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
- false /* faceScanning*/);
+ 0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning*/);
mDisplayInfo.rotation = Surface.ROTATION_270;
mScreenDecorations.onConfigurationChanged(null);
@@ -1072,8 +1023,7 @@
public void testOnlyRoundedCornerRadiusTop() {
setupResources(0 /* radius */, 10 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
mScreenDecorations.start();
@@ -1094,8 +1044,7 @@
public void testOnlyRoundedCornerRadiusBottom() {
setupResources(0 /* radius */, 0 /* radiusTop */, 20 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
mScreenDecorations.start();
@@ -1166,13 +1115,10 @@
public void testSupportHwcLayer_SwitchFrom_NotSupport() {
setupResources(0 /* radius */, 10 /* radiusTop */, 20 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
// top cutout
- final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
mScreenDecorations.start();
// should only inflate mOverlays when the hwc doesn't support screen decoration
@@ -1195,16 +1141,13 @@
public void testNotSupportHwcLayer_SwitchFrom_Support() {
setupResources(0 /* radius */, 10 /* radiusTop */, 20 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
decorationSupport.format = PixelFormat.R_8;
doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
// top cutout
- final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
mScreenDecorations.start();
// should only inflate hwc layer when the hwc supports screen decoration
@@ -1234,16 +1177,13 @@
/* roundedTopDrawable */,
getTestsDrawable(com.android.systemui.tests.R.drawable.rounded4px)
/* roundedBottomDrawable */,
- 0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
- true /* faceScanning */);
+ 0 /* roundedPadding */, true /* privacyDot */, true /* faceScanning */);
final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
decorationSupport.format = PixelFormat.R_8;
doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
// top cutout
- final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
mScreenDecorations.start();
// Inflate top and bottom overlay with INVISIBLE because of only privacy dots on sw layer
@@ -1277,11 +1217,9 @@
public void testAutoShowHideOverlayWindowWhenNoRoundedAndNoCutout() {
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, false /* fillCutout */, true /* privacyDot */,
- true /* faceScanning */);
+ 0 /* roundedPadding */, true /* privacyDot */, true /* faceScanning */);
- // no cutout
- doReturn(null).when(mScreenDecorations).getCutout();
+ // no cutout (default)
mScreenDecorations.start();
// Inflate top and bottom overlay with INVISIBLE because of only privacy dots on sw layer
@@ -1315,16 +1253,13 @@
public void testHwcLayer_noPrivacyDot_noFaceScanning() {
setupResources(0 /* radius */, 10 /* radiusTop */, 20 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
decorationSupport.format = PixelFormat.R_8;
doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
// top cutout
- final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
mScreenDecorations.start();
@@ -1337,16 +1272,13 @@
public void testHwcLayer_PrivacyDot_FaceScanning() {
setupResources(0 /* radius */, 10 /* radiusTop */, 20 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
- true /* faceScanning */);
+ 0 /* roundedPadding */, true /* privacyDot */, true /* faceScanning */);
final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
decorationSupport.format = PixelFormat.R_8;
doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
// top cutout
- final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
mScreenDecorations.start();
@@ -1364,16 +1296,13 @@
public void testOnDisplayChanged_hwcLayer() {
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
final DisplayDecorationSupport decorationSupport = new DisplayDecorationSupport();
decorationSupport.format = PixelFormat.R_8;
doReturn(decorationSupport).when(mDisplay).getDisplayDecorationSupport();
// top cutout
- final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
mScreenDecorations.start();
@@ -1383,39 +1312,36 @@
mScreenDecorations.mDisplayListener.onDisplayChanged(1);
- verify(hwcLayer, times(1)).onDisplayChanged(1);
+ verify(hwcLayer, times(1)).onDisplayChanged(any());
}
@Test
public void testOnDisplayChanged_nonHwcLayer() {
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, true /* fillCutout */, false /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
// top cutout
- final Rect[] bounds = {null, new Rect(9, 0, 10, 1), null, null};
- doReturn(getDisplayCutoutForRotation(Insets.of(0, 1, 0, 0), bounds))
- .when(mScreenDecorations).getCutout();
+ mMockCutoutList.add(new CutoutDecorProviderImpl(BOUNDS_POSITION_TOP));
mScreenDecorations.start();
- final ScreenDecorations.DisplayCutoutView cutoutView =
- mScreenDecorations.mCutoutViews[BOUNDS_POSITION_TOP];
+ final ScreenDecorations.DisplayCutoutView cutoutView = (ScreenDecorations.DisplayCutoutView)
+ mScreenDecorations.getOverlayView(R.id.display_cutout);
+ assertNotNull(cutoutView);
spyOn(cutoutView);
doReturn(mDisplay).when(cutoutView).getDisplay();
mScreenDecorations.mDisplayListener.onDisplayChanged(1);
- verify(cutoutView, times(1)).onDisplayChanged(1);
+ verify(cutoutView, times(1)).onDisplayChanged(any());
}
@Test
public void testHasSameProvidersWithNullOverlays() {
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, false /* fillCutout */, false /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, false /* privacyDot */, false /* faceScanning */);
mScreenDecorations.start();
@@ -1433,8 +1359,7 @@
public void testHasSameProvidersWithPrivacyDots() {
setupResources(0 /* radius */, 0 /* radiusTop */, 0 /* radiusBottom */,
null /* roundedTopDrawable */, null /* roundedBottomDrawable */,
- 0 /* roundedPadding */, true /* fillCutout */, true /* privacyDot */,
- false /* faceScanning */);
+ 0 /* roundedPadding */, true /* privacyDot */, false /* faceScanning */);
mScreenDecorations.start();
@@ -1471,7 +1396,7 @@
private void setupResources(int radius, int radiusTop, int radiusBottom,
@Nullable Drawable roundedTopDrawable, @Nullable Drawable roundedBottomDrawable,
- int roundedPadding, boolean fillCutout, boolean privacyDot, boolean faceScanning) {
+ int roundedPadding, boolean privacyDot, boolean faceScanning) {
mContext.getOrCreateTestableResources().addOverride(
com.android.internal.R.array.config_displayUniqueIdArray,
new String[]{});
@@ -1511,8 +1436,6 @@
}
mContext.getOrCreateTestableResources().addOverride(
R.dimen.rounded_corner_content_padding, roundedPadding);
- mContext.getOrCreateTestableResources().addOverride(
- com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, fillCutout);
mPrivacyDecorProviders = new ArrayList<>();
if (privacyDot) {
@@ -1531,19 +1454,4 @@
when(mFaceScanningProviderFactory.getProviders()).thenReturn(mFaceScanningProviders);
when(mFaceScanningProviderFactory.getHasProviders()).thenReturn(faceScanning);
}
-
- private DisplayCutout getDisplayCutoutForRotation(Insets safeInsets, Rect[] cutoutBounds) {
- final int rotation = mContext.getDisplay().getRotation();
- final Insets insets = RotationUtils.rotateInsets(safeInsets, rotation);
- final Rect[] sorted = new Rect[BOUNDS_POSITION_LENGTH];
- for (int i = 0; i < BOUNDS_POSITION_LENGTH; i++) {
- final int rotatedPos = ScreenDecorations.getBoundPositionFromRotation(i, rotation);
- if (cutoutBounds[i] != null) {
- RotationUtils.rotateBounds(cutoutBounds[i], new Rect(0, 0, 100, 200), rotation);
- }
- sorted[rotatedPos] = cutoutBounds[i];
- }
- return new DisplayCutout(insets, sorted[BOUNDS_POSITION_LEFT], sorted[BOUNDS_POSITION_TOP],
- sorted[BOUNDS_POSITION_RIGHT], sorted[BOUNDS_POSITION_BOTTOM]);
- }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/CutoutDecorProviderFactoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/CutoutDecorProviderFactoryTest.kt
new file mode 100644
index 0000000..1040ec4
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/decor/CutoutDecorProviderFactoryTest.kt
@@ -0,0 +1,200 @@
+/*
+ * Copyright (C) 2022 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.systemui.decor
+
+import android.graphics.Insets
+import android.graphics.Rect
+import android.testing.AndroidTestingRunner
+import android.testing.TestableResources
+import android.util.RotationUtils
+import android.util.Size
+import android.view.Display
+import android.view.DisplayCutout
+import android.view.DisplayCutout.BOUNDS_POSITION_LENGTH
+import android.view.DisplayInfo
+import android.view.Surface
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.util.mockito.any
+import org.junit.Assert
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.doAnswer
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class CutoutDecorProviderFactoryTest : SysuiTestCase() {
+
+ @Mock private lateinit var display: Display
+ private var testableRes: TestableResources? = null
+ private lateinit var factory: CutoutDecorProviderFactory
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ testableRes = mContext.orCreateTestableResources
+ factory = CutoutDecorProviderFactory(testableRes!!.resources, display)
+ }
+
+ private fun setupFillCutout(fillCutout: Boolean) {
+ testableRes!!.addOverride(
+ com.android.internal.R.bool.config_fillMainBuiltInDisplayCutout, fillCutout
+ )
+ }
+
+ private fun setupDisplayInfo(
+ displayCutout: DisplayCutout? = null,
+ @Surface.Rotation rotation: Int = Surface.ROTATION_0,
+ displayId: Int = -1
+ ) {
+ doAnswer {
+ it.getArgument<DisplayInfo>(0).let { info ->
+ info.displayCutout = displayCutout
+ info.rotation = rotation
+ info.displayId = displayId
+ }
+ true
+ }.`when`(display).getDisplayInfo(any<DisplayInfo>())
+ }
+
+ private fun getCutout(
+ safeInsets: Insets,
+ cutoutBounds: Array<Rect?>,
+ @Surface.Rotation rotation: Int = Surface.ROTATION_0,
+ cutoutParentSizeForRotate: Size = Size(100, 200)
+ ): DisplayCutout {
+ val insets = RotationUtils.rotateInsets(safeInsets, rotation)
+ val sorted = arrayOfNulls<Rect>(BOUNDS_POSITION_LENGTH)
+ for (pos in 0 until BOUNDS_POSITION_LENGTH) {
+ val rotatedPos = (pos - rotation + BOUNDS_POSITION_LENGTH) % BOUNDS_POSITION_LENGTH
+ if (cutoutBounds[pos] != null) {
+ RotationUtils.rotateBounds(
+ cutoutBounds[pos],
+ cutoutParentSizeForRotate.width,
+ cutoutParentSizeForRotate.height,
+ rotation
+ )
+ }
+ sorted[rotatedPos] = cutoutBounds[pos]
+ }
+ return DisplayCutout(
+ insets,
+ sorted[DisplayCutout.BOUNDS_POSITION_LEFT],
+ sorted[DisplayCutout.BOUNDS_POSITION_TOP],
+ sorted[DisplayCutout.BOUNDS_POSITION_RIGHT],
+ sorted[DisplayCutout.BOUNDS_POSITION_BOTTOM]
+ )
+ }
+
+ @Test
+ fun testGetNothingIfNoCutout() {
+ setupFillCutout(false)
+
+ Assert.assertFalse(factory.hasProviders)
+ Assert.assertEquals(0, factory.providers.size)
+ }
+
+ @Test
+ fun testGetTopCutoutProvider() {
+ setupFillCutout(true)
+ setupDisplayInfo(
+ getCutout(
+ safeInsets = Insets.of(0, 1, 0, 0),
+ cutoutBounds = arrayOf(null, Rect(9, 0, 10, 1), null, null)
+ )
+ )
+
+ Assert.assertTrue(factory.hasProviders)
+
+ val providers = factory.providers
+ Assert.assertEquals(1, providers.size)
+ Assert.assertEquals(1, providers[0].numOfAlignedBound)
+ Assert.assertEquals(DisplayCutout.BOUNDS_POSITION_TOP, providers[0].alignedBounds[0])
+ }
+
+ @Test
+ fun testGetBottomCutoutProviderOnLandscape() {
+ setupFillCutout(true)
+ setupDisplayInfo(
+ getCutout(
+ safeInsets = Insets.of(0, 0, 0, 1),
+ cutoutBounds = arrayOf(null, null, null, Rect(45, 199, 55, 200)),
+ rotation = Surface.ROTATION_90
+ ),
+ Surface.ROTATION_90
+ )
+
+ Assert.assertTrue(factory.hasProviders)
+
+ val providers = factory.providers
+ Assert.assertEquals(1, providers.size)
+ Assert.assertEquals(1, providers[0].numOfAlignedBound)
+ Assert.assertEquals(DisplayCutout.BOUNDS_POSITION_BOTTOM, providers[0].alignedBounds[0])
+ }
+
+ @Test
+ fun testGetLeftCutoutProviderOnSeascape() {
+ setupFillCutout(true)
+ setupDisplayInfo(
+ getCutout(
+ safeInsets = Insets.of(1, 0, 0, 0),
+ cutoutBounds = arrayOf(Rect(0, 20, 1, 40), null, null, null),
+ rotation = Surface.ROTATION_270
+ ),
+ Surface.ROTATION_270
+ )
+
+ Assert.assertTrue(factory.hasProviders)
+
+ val providers = factory.providers
+ Assert.assertEquals(1, providers.size)
+ Assert.assertEquals(1, providers[0].numOfAlignedBound)
+ Assert.assertEquals(DisplayCutout.BOUNDS_POSITION_LEFT, providers[0].alignedBounds[0])
+ }
+
+ @Test
+ fun testGetTopRightCutoutProviderOnReverse() {
+ setupFillCutout(true)
+ setupDisplayInfo(
+ getCutout(
+ safeInsets = Insets.of(0, 1, 1, 0),
+ cutoutBounds = arrayOf(
+ null,
+ Rect(9, 0, 10, 1),
+ Rect(99, 40, 100, 60),
+ null
+ ),
+ rotation = Surface.ROTATION_180
+ ),
+ Surface.ROTATION_180
+ )
+
+ Assert.assertTrue(factory.hasProviders)
+
+ val providers = factory.providers
+ Assert.assertEquals(2, providers.size)
+ Assert.assertEquals(1, providers[0].numOfAlignedBound)
+ Assert.assertEquals(1, providers[1].numOfAlignedBound)
+ providers.sortedBy { it.alignedBounds[0] }.let {
+ Assert.assertEquals(DisplayCutout.BOUNDS_POSITION_TOP, it[0].alignedBounds[0])
+ Assert.assertEquals(DisplayCutout.BOUNDS_POSITION_RIGHT, it[1].alignedBounds[0])
+ }
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt b/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
index 69366fa..8bf17d7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/decor/OverlayWindowTest.kt
@@ -16,6 +16,7 @@
package com.android.systemui.decor
+import android.graphics.Color
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper.RunWithLooper
import android.view.DisplayCutout
@@ -51,35 +52,45 @@
@Before
fun setUp() {
- decorProvider1 = spy(PrivacyDotCornerDecorProviderImpl(
+ decorProvider1 = spy(
+ PrivacyDotCornerDecorProviderImpl(
viewId = TEST_DECOR_VIEW_ID_1,
alignedBound1 = DisplayCutout.BOUNDS_POSITION_TOP,
alignedBound2 = DisplayCutout.BOUNDS_POSITION_LEFT,
- layoutId = R.layout.privacy_dot_top_left))
- decorProvider2 = spy(PrivacyDotCornerDecorProviderImpl(
+ layoutId = R.layout.privacy_dot_top_left
+ )
+ )
+ decorProvider2 = spy(
+ PrivacyDotCornerDecorProviderImpl(
viewId = TEST_DECOR_VIEW_ID_2,
alignedBound1 = DisplayCutout.BOUNDS_POSITION_BOTTOM,
alignedBound2 = DisplayCutout.BOUNDS_POSITION_LEFT,
- layoutId = R.layout.privacy_dot_bottom_left))
- decorProvider3 = spy(PrivacyDotCornerDecorProviderImpl(
+ layoutId = R.layout.privacy_dot_bottom_left
+ )
+ )
+ decorProvider3 = spy(
+ PrivacyDotCornerDecorProviderImpl(
viewId = TEST_DECOR_VIEW_ID_3,
alignedBound1 = DisplayCutout.BOUNDS_POSITION_BOTTOM,
alignedBound2 = DisplayCutout.BOUNDS_POSITION_RIGHT,
- layoutId = R.layout.privacy_dot_bottom_right))
-
+ layoutId = R.layout.privacy_dot_bottom_right
+ )
+ )
overlay = OverlayWindow(mContext)
}
@Test
fun testAddProvider() {
@Surface.Rotation val rotation = Surface.ROTATION_270
- overlay.addDecorProvider(decorProvider1, rotation)
- overlay.addDecorProvider(decorProvider2, rotation)
+ overlay.addDecorProvider(decorProvider1, rotation, Color.BLACK)
+ overlay.addDecorProvider(decorProvider2, rotation, Color.YELLOW)
verify(decorProvider1, times(1)).inflateView(
- mContext, overlay.rootView, rotation)
+ mContext, overlay.rootView, rotation, Color.BLACK
+ )
verify(decorProvider2, times(1)).inflateView(
- mContext, overlay.rootView, rotation)
+ mContext, overlay.rootView, rotation, Color.YELLOW
+ )
val view1FoundFromRootView = overlay.rootView.findViewById<View>(TEST_DECOR_VIEW_ID_1)
Assert.assertNotNull(view1FoundFromRootView)
@@ -91,8 +102,8 @@
@Test
fun testRemoveView() {
- overlay.addDecorProvider(decorProvider1, Surface.ROTATION_270)
- overlay.addDecorProvider(decorProvider2, Surface.ROTATION_270)
+ overlay.addDecorProvider(decorProvider1, Surface.ROTATION_270, Color.BLACK)
+ overlay.addDecorProvider(decorProvider2, Surface.ROTATION_270, Color.BLACK)
overlay.removeView(TEST_DECOR_VIEW_ID_1)
val viewFoundFromRootView = overlay.rootView.findViewById<View>(TEST_DECOR_VIEW_ID_1)
@@ -102,39 +113,47 @@
@Test
fun testOnReloadResAndMeasureWithoutIds() {
- overlay.addDecorProvider(decorProvider1, Surface.ROTATION_0)
- overlay.addDecorProvider(decorProvider2, Surface.ROTATION_0)
+ overlay.addDecorProvider(decorProvider1, Surface.ROTATION_0, Color.BLACK)
+ overlay.addDecorProvider(decorProvider2, Surface.ROTATION_0, Color.BLACK)
overlay.onReloadResAndMeasure(
- reloadToken = 1,
- rotation = Surface.ROTATION_90,
- displayUniqueId = null)
+ reloadToken = 1,
+ rotation = Surface.ROTATION_90,
+ tintColor = Color.BLACK,
+ displayUniqueId = null
+ )
verify(decorProvider1, times(1)).onReloadResAndMeasure(
- overlay.getView(TEST_DECOR_VIEW_ID_1)!!, 1, Surface.ROTATION_90, null)
+ overlay.getView(TEST_DECOR_VIEW_ID_1)!!, 1, Surface.ROTATION_90, Color.BLACK, null
+ )
verify(decorProvider2, times(1)).onReloadResAndMeasure(
- overlay.getView(TEST_DECOR_VIEW_ID_2)!!, 1, Surface.ROTATION_90, null)
+ overlay.getView(TEST_DECOR_VIEW_ID_2)!!, 1, Surface.ROTATION_90, Color.BLACK, null
+ )
}
@Test
fun testOnReloadResAndMeasureWithIds() {
- overlay.addDecorProvider(decorProvider1, Surface.ROTATION_0)
- overlay.addDecorProvider(decorProvider2, Surface.ROTATION_0)
+ overlay.addDecorProvider(decorProvider1, Surface.ROTATION_0, Color.BLACK)
+ overlay.addDecorProvider(decorProvider2, Surface.ROTATION_0, Color.BLACK)
overlay.onReloadResAndMeasure(
- filterIds = arrayOf(TEST_DECOR_VIEW_ID_2),
- reloadToken = 1,
- rotation = Surface.ROTATION_90,
- displayUniqueId = null)
+ filterIds = arrayOf(TEST_DECOR_VIEW_ID_2),
+ reloadToken = 1,
+ rotation = Surface.ROTATION_90,
+ tintColor = Color.BLACK,
+ displayUniqueId = null
+ )
verify(decorProvider1, never()).onReloadResAndMeasure(
- overlay.getView(TEST_DECOR_VIEW_ID_1)!!, 1, Surface.ROTATION_90, null)
+ overlay.getView(TEST_DECOR_VIEW_ID_1)!!, 1, Surface.ROTATION_90, Color.BLACK, null
+ )
verify(decorProvider2, times(1)).onReloadResAndMeasure(
- overlay.getView(TEST_DECOR_VIEW_ID_2)!!, 1, Surface.ROTATION_90, null)
+ overlay.getView(TEST_DECOR_VIEW_ID_2)!!, 1, Surface.ROTATION_90, Color.BLACK, null
+ )
}
@Test
fun testRemoveRedundantViewsWithNullParameter() {
- overlay.addDecorProvider(decorProvider1, Surface.ROTATION_270)
- overlay.addDecorProvider(decorProvider2, Surface.ROTATION_270)
+ overlay.addDecorProvider(decorProvider1, Surface.ROTATION_270, Color.BLACK)
+ overlay.addDecorProvider(decorProvider2, Surface.ROTATION_270, Color.BLACK)
overlay.removeRedundantViews(null)
@@ -146,13 +165,15 @@
@Test
fun testRemoveRedundantViewsWith2Providers() {
- overlay.addDecorProvider(decorProvider1, Surface.ROTATION_270)
- overlay.addDecorProvider(decorProvider2, Surface.ROTATION_270)
+ overlay.addDecorProvider(decorProvider1, Surface.ROTATION_270, Color.BLACK)
+ overlay.addDecorProvider(decorProvider2, Surface.ROTATION_270, Color.BLACK)
- overlay.removeRedundantViews(IntArray(2).apply {
- this[0] = TEST_DECOR_VIEW_ID_3
- this[1] = TEST_DECOR_VIEW_ID_1
- })
+ overlay.removeRedundantViews(
+ IntArray(2).apply {
+ this[0] = TEST_DECOR_VIEW_ID_3
+ this[1] = TEST_DECOR_VIEW_ID_1
+ }
+ )
Assert.assertNotNull(overlay.getView(TEST_DECOR_VIEW_ID_1))
Assert.assertNotNull(overlay.rootView.findViewById(TEST_DECOR_VIEW_ID_1))
@@ -167,16 +188,16 @@
Assert.assertFalse(overlay.hasSameProviders(listOf(decorProvider2)))
Assert.assertFalse(overlay.hasSameProviders(listOf(decorProvider2, decorProvider1)))
- overlay.addDecorProvider(decorProvider1, Surface.ROTATION_0)
+ overlay.addDecorProvider(decorProvider1, Surface.ROTATION_0, Color.BLACK)
Assert.assertFalse(overlay.hasSameProviders(emptyList()))
Assert.assertTrue(overlay.hasSameProviders(listOf(decorProvider1)))
Assert.assertFalse(overlay.hasSameProviders(listOf(decorProvider2)))
Assert.assertFalse(overlay.hasSameProviders(listOf(decorProvider2, decorProvider1)))
- overlay.addDecorProvider(decorProvider2, Surface.ROTATION_0)
+ overlay.addDecorProvider(decorProvider2, Surface.ROTATION_0, Color.BLACK)
Assert.assertFalse(overlay.hasSameProviders(emptyList()))
Assert.assertFalse(overlay.hasSameProviders(listOf(decorProvider1)))
Assert.assertFalse(overlay.hasSameProviders(listOf(decorProvider2)))
Assert.assertTrue(overlay.hasSameProviders(listOf(decorProvider2, decorProvider1)))
}
-}
\ No newline at end of file
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java
index 7d54758..fa8f88a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/SmartSpaceComplicationTest.java
@@ -43,7 +43,7 @@
import org.mockito.Mockito;
import org.mockito.MockitoAnnotations;
-import java.util.Arrays;
+import java.util.Collections;
@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -61,9 +61,6 @@
private SmartSpaceComplication mComplication;
@Mock
- private ComplicationViewModel mComplicationViewModel;
-
- @Mock
private View mBcSmartspaceView;
@Before
@@ -125,12 +122,12 @@
// Test
final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
- listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
+ listenerCaptor.getValue().onSmartspaceTargetsUpdated(Collections.singletonList(target));
verify(mDreamOverlayStateController).addComplication(eq(mComplication));
}
@Test
- public void testOverlayActive_targetsEmpty_removesComplication() {
+ public void testOverlayActive_targetsEmpty_addsComplication() {
final SmartSpaceComplication.Registrant registrant = getRegistrant();
registrant.start();
@@ -145,13 +142,9 @@
ArgumentCaptor.forClass(BcSmartspaceDataPlugin.SmartspaceTargetListener.class);
verify(mSmartspaceController).addListener(listenerCaptor.capture());
- final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
- listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
- verify(mDreamOverlayStateController).addComplication(eq(mComplication));
-
// Test
- listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList());
- verify(mDreamOverlayStateController).removeComplication(eq(mComplication));
+ listenerCaptor.getValue().onSmartspaceTargetsUpdated(Collections.emptyList());
+ verify(mDreamOverlayStateController).addComplication(eq(mComplication));
}
@Test
@@ -170,8 +163,7 @@
ArgumentCaptor.forClass(BcSmartspaceDataPlugin.SmartspaceTargetListener.class);
verify(mSmartspaceController).addListener(listenerCaptor.capture());
- final SmartspaceTarget target = Mockito.mock(SmartspaceTarget.class);
- listenerCaptor.getValue().onSmartspaceTargetsUpdated(Arrays.asList(target));
+ listenerCaptor.getValue().onSmartspaceTargetsUpdated(Collections.emptyList());
verify(mDreamOverlayStateController).addComplication(eq(mComplication));
// Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
index 1131a7e..eb8ecae 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/dialog/MediaOutputBaseDialogTest.java
@@ -224,6 +224,14 @@
}
@Test
+ public void refresh_inDragging_directSetRefreshingToFalse() {
+ when(mMediaOutputBaseAdapter.isDragging()).thenReturn(true);
+ mMediaOutputBaseDialogImpl.refresh();
+
+ assertThat(mMediaOutputController.isRefreshing()).isFalse();
+ }
+
+ @Test
public void refresh_notInDragging_verifyUpdateAdapter() {
when(mMediaOutputBaseAdapter.getCurrentActivePosition()).thenReturn(-1);
when(mMediaOutputBaseAdapter.isDragging()).thenReturn(false);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
index 98389c2..e2ce939 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationPanelViewControllerTest.java
@@ -458,7 +458,6 @@
NotificationWakeUpCoordinator coordinator =
new NotificationWakeUpCoordinator(
- mDumpManager,
mock(HeadsUpManagerPhone.class),
new StatusBarStateControllerImpl(new UiEventLoggerFake(), mDumpManager,
mInteractionJankMonitor),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
deleted file mode 100644
index 19dd027..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/NotificationListControllerTest.java
+++ /dev/null
@@ -1,123 +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.systemui.statusbar.notification;
-
-import static com.android.systemui.statusbar.notification.NotificationEntryManager.UNDEFINED_DISMISS_REASON;
-
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.verify;
-
-import android.app.ActivityManager;
-import android.app.Notification;
-import android.os.UserHandle;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.statusbar.NotificationVisibility;
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.statusbar.NotificationLockscreenUserManager;
-import com.android.systemui.statusbar.notification.collection.NotificationEntry;
-import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
-import com.android.systemui.statusbar.notification.stack.NotificationListContainer;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController;
-import com.android.systemui.statusbar.policy.DeviceProvisionedController.DeviceProvisionedListener;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@SmallTest
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class NotificationListControllerTest extends SysuiTestCase {
- private NotificationListController mController;
-
- @Mock private NotificationEntryManager mEntryManager;
- @Mock private NotificationListContainer mListContainer;
- @Mock private DeviceProvisionedController mDeviceProvisionedController;
-
- @Captor private ArgumentCaptor<NotificationEntryListener> mEntryListenerCaptor;
- @Captor private ArgumentCaptor<DeviceProvisionedListener> mProvisionedCaptor;
-
- private NotificationEntryListener mEntryListener;
- private DeviceProvisionedListener mProvisionedListener;
-
- private int mNextNotifId = 0;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
- mDependency.injectMockDependency(NotificationLockscreenUserManager.class);
-
- mController = new NotificationListController(
- mEntryManager,
- mListContainer,
- mDeviceProvisionedController);
- mController.bind();
-
- // Capture callbacks passed to mocks
- verify(mEntryManager).addNotificationEntryListener(mEntryListenerCaptor.capture());
- mEntryListener = mEntryListenerCaptor.getValue();
- verify(mDeviceProvisionedController).addCallback(mProvisionedCaptor.capture());
- mProvisionedListener = mProvisionedCaptor.getValue();
- }
-
- @Test
- public void testCleanUpViewStateOnEntryRemoved() {
- final NotificationEntry entry = buildEntry();
- mEntryListener.onEntryRemoved(
- entry,
- NotificationVisibility.obtain(entry.getKey(), 0, 0, true),
- false,
- UNDEFINED_DISMISS_REASON);
- verify(mListContainer).cleanUpViewStateForEntry(entry);
- }
-
- @Test
- public void testCallUpdateNotificationsOnDeviceProvisionedChange() {
- mProvisionedListener.onDeviceProvisionedChanged();
- verify(mEntryManager).updateNotifications(anyString());
- }
-
- private NotificationEntry buildEntry() {
- mNextNotifId++;
-
- Notification.Builder n = new Notification.Builder(mContext, "")
- .setSmallIcon(R.drawable.ic_person)
- .setContentTitle("Title")
- .setContentText("Text");
-
- return new NotificationEntryBuilder()
- .setPkg(TEST_PACKAGE_NAME)
- .setOpPkg(TEST_PACKAGE_NAME)
- .setId(mNextNotifId)
- .setUid(TEST_UID)
- .setNotification(n.build())
- .setUser(new UserHandle(ActivityManager.getCurrentUser()))
- .build();
- }
-
- private static final String TEST_PACKAGE_NAME = "test";
- private static final int TEST_UID = 0;
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java
deleted file mode 100644
index b20f95c..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/row/NotificationBlockingHelperManagerTest.java
+++ /dev/null
@@ -1,302 +0,0 @@
-/*
- * Copyright (C) 2018 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.systemui.statusbar.notification.row;
-
-import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
-import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEGATIVE;
-import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
-import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE;
-
-import static com.android.systemui.statusbar.NotificationEntryHelper.modifyRanking;
-
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.anyString;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.never;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.times;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import android.app.NotificationChannel;
-import android.content.Context;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.View;
-
-import androidx.test.filters.FlakyTest;
-import androidx.test.filters.SmallTest;
-
-import com.android.internal.logging.MetricsLogger;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.plugins.statusbar.NotificationMenuRowPlugin;
-import com.android.systemui.statusbar.notification.NotificationEntryManager;
-import com.android.systemui.statusbar.notification.collection.render.GroupMembershipManager;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-/**
- * Tests for {@link NotificationBlockingHelperManager}.
- */
-@SmallTest
-@FlakyTest
-@org.junit.runner.RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper
-public class NotificationBlockingHelperManagerTest extends SysuiTestCase {
- private NotificationBlockingHelperManager mBlockingHelperManager;
-
- private NotificationTestHelper mHelper;
-
- @Mock private NotificationGutsManager mGutsManager;
- @Mock private NotificationEntryManager mEntryManager;
- @Mock private NotificationMenuRow mMenuRow;
- @Mock private NotificationMenuRowPlugin.MenuItem mMenuItem;
- @Mock private GroupMembershipManager mGroupMembershipManager;
-
- @Before
- public void setUp() {
- allowTestableLooperAsMainThread();
- MockitoAnnotations.initMocks(this);
- when(mGutsManager.openGuts(
- any(View.class),
- anyInt(),
- anyInt(),
- any(NotificationMenuRowPlugin.MenuItem.class)))
- .thenReturn(true);
- when(mMenuRow.getLongpressMenuItem(any(Context.class))).thenReturn(mMenuItem);
-
- mHelper = new NotificationTestHelper(mContext, mDependency, TestableLooper.get(this));
-
- mBlockingHelperManager = new NotificationBlockingHelperManager(
- mContext, mGutsManager, mEntryManager, mock(MetricsLogger.class),
- mGroupMembershipManager);
- // By default, have the shade visible/expanded.
- mBlockingHelperManager.setNotificationShadeExpanded(1f);
- }
-
- @Test
- public void testDismissCurrentBlockingHelper_nullBlockingHelperRow() {
- // By default, this shouldn't dismiss (no pointers/vars set up!)
- assertFalse(mBlockingHelperManager.dismissCurrentBlockingHelper());
- assertTrue(mBlockingHelperManager.isBlockingHelperRowNull());
- }
-
- @Test
- public void testDismissCurrentBlockingHelper_withDetachedBlockingHelperRow() throws Exception {
- ExpandableNotificationRow row = createBlockableRowSpy();
- row.setBlockingHelperShowing(true);
- when(row.isAttachedToWindow()).thenReturn(false);
- mBlockingHelperManager.setBlockingHelperRowForTest(row);
-
- assertTrue(mBlockingHelperManager.dismissCurrentBlockingHelper());
- assertTrue(mBlockingHelperManager.isBlockingHelperRowNull());
-
- verify(mEntryManager, times(0)).updateNotifications(anyString());
- }
-
- @Test
- public void testDismissCurrentBlockingHelper_withAttachedBlockingHelperRow() throws Exception {
- ExpandableNotificationRow row = createBlockableRowSpy();
- row.setBlockingHelperShowing(true);
- when(row.isAttachedToWindow()).thenReturn(true);
- mBlockingHelperManager.setBlockingHelperRowForTest(row);
-
- assertTrue(mBlockingHelperManager.dismissCurrentBlockingHelper());
- assertTrue(mBlockingHelperManager.isBlockingHelperRowNull());
-
- verify(mEntryManager).updateNotifications(anyString());
- }
-
- @Test
- public void testPerhapsShowBlockingHelper_shown() throws Exception {
- ExpandableNotificationRow row = createBlockableRowSpy();
- modifyRanking(row.getEntry())
- .setUserSentiment(USER_SENTIMENT_NEGATIVE)
- .build();
-
- assertTrue(mBlockingHelperManager.perhapsShowBlockingHelper(row, mMenuRow));
-
- verify(mGutsManager).openGuts(row, 0, 0, mMenuItem);
- }
-
- @Test
- public void testPerhapsShowBlockingHelper_notShownForMultiChannelGroup() throws Exception {
- ExpandableNotificationRow groupRow = createBlockableGroupRowSpy(10);
- int i = 0;
- for (ExpandableNotificationRow childRow : groupRow.getAttachedChildren()) {
- modifyRanking(childRow.getEntry())
- .setChannel(
- new NotificationChannel(
- Integer.toString(i++), "", IMPORTANCE_DEFAULT))
- .build();
- }
-
- modifyRanking(groupRow.getEntry())
- .setUserSentiment(USER_SENTIMENT_NEGATIVE)
- .build();
-
- assertFalse(mBlockingHelperManager.perhapsShowBlockingHelper(groupRow, mMenuRow));
-
- verify(mGutsManager, never()).openGuts(groupRow, 0, 0, mMenuItem);
- }
-
- @Test
- public void testPerhapsShowBlockingHelper_shownForLargeGroup() throws Exception {
- ExpandableNotificationRow groupRow = createBlockableGroupRowSpy(10);
- modifyRanking(groupRow.getEntry())
- .setUserSentiment(USER_SENTIMENT_NEGATIVE)
- .build();
-
- assertTrue(mBlockingHelperManager.perhapsShowBlockingHelper(groupRow, mMenuRow));
-
- verify(mGutsManager).openGuts(groupRow, 0, 0, mMenuItem);
- }
-
- @Test
- public void testPerhapsShowBlockingHelper_shownForOnlyChildNotification()
- throws Exception {
- ExpandableNotificationRow groupRow = createBlockableGroupRowSpy(1);
- // Explicitly get the children container & call getViewAtPosition on it instead of the row
- // as other factors such as view expansion may cause us to get the parent row back instead
- // of the child row.
- ExpandableNotificationRow childRow = groupRow.getChildrenContainer().getViewAtPosition(0);
- modifyRanking(childRow.getEntry())
- .setUserSentiment(USER_SENTIMENT_NEGATIVE)
- .build();
- assertFalse(childRow.getIsNonblockable());
-
- when(mGroupMembershipManager.isOnlyChildInGroup(childRow.getEntry())).thenReturn(true);
- assertTrue(mBlockingHelperManager.perhapsShowBlockingHelper(childRow, mMenuRow));
-
- verify(mGutsManager).openGuts(childRow, 0, 0, mMenuItem);
- }
-
- @Test
- public void testPerhapsShowBlockingHelper_notShownDueToNeutralUserSentiment() throws Exception {
- ExpandableNotificationRow row = createBlockableRowSpy();
- modifyRanking(row.getEntry())
- .setUserSentiment(USER_SENTIMENT_NEUTRAL)
- .build();
-
- assertFalse(mBlockingHelperManager.perhapsShowBlockingHelper(row, mMenuRow));
- }
-
- @Test
- public void testPerhapsShowBlockingHelper_notShownDueToPositiveUserSentiment()
- throws Exception {
- ExpandableNotificationRow row = createBlockableRowSpy();
- modifyRanking(row.getEntry())
- .setUserSentiment(USER_SENTIMENT_POSITIVE)
- .build();
-
- assertFalse(mBlockingHelperManager.perhapsShowBlockingHelper(row, mMenuRow));
- }
-
- @Test
- public void testPerhapsShowBlockingHelper_notShownDueToShadeVisibility() throws Exception {
- ExpandableNotificationRow row = createBlockableRowSpy();
- modifyRanking(row.getEntry())
- .setUserSentiment(USER_SENTIMENT_NEGATIVE)
- .build();
- // Hide the shade
- mBlockingHelperManager.setNotificationShadeExpanded(0f);
-
- assertFalse(mBlockingHelperManager.perhapsShowBlockingHelper(row, mMenuRow));
- }
-
- @Test
- public void testPerhapsShowBlockingHelper_notShownDueToNonblockability() throws Exception {
- ExpandableNotificationRow row = createBlockableRowSpy();
- when(row.getIsNonblockable()).thenReturn(true);
- modifyRanking(row.getEntry())
- .setUserSentiment(USER_SENTIMENT_NEGATIVE)
- .build();
-
- assertFalse(mBlockingHelperManager.perhapsShowBlockingHelper(row, mMenuRow));
- }
-
- @Test
- public void testPerhapsShowBlockingHelper_notShownAsNotificationIsInMultipleChildGroup()
- throws Exception {
- ExpandableNotificationRow groupRow = createBlockableGroupRowSpy(2);
- // Explicitly get the children container & call getViewAtPosition on it instead of the row
- // as other factors such as view expansion may cause us to get the parent row back instead
- // of the child row.
- ExpandableNotificationRow childRow = groupRow.getChildrenContainer().getViewAtPosition(0);
- modifyRanking(childRow.getEntry())
- .setUserSentiment(USER_SENTIMENT_NEGATIVE)
- .build();
-
- assertFalse(mBlockingHelperManager.perhapsShowBlockingHelper(childRow, mMenuRow));
- }
-
- @Test
- public void testBlockingHelperShowAndDismiss() throws Exception{
- ExpandableNotificationRow row = createBlockableRowSpy();
- modifyRanking(row.getEntry())
- .setUserSentiment(USER_SENTIMENT_NEGATIVE)
- .build();
- when(row.isAttachedToWindow()).thenReturn(true);
-
- // Show check
- assertTrue(mBlockingHelperManager.perhapsShowBlockingHelper(row, mMenuRow));
-
- verify(mGutsManager).openGuts(row, 0, 0, mMenuItem);
-
- // Dismiss check
- assertTrue(mBlockingHelperManager.dismissCurrentBlockingHelper());
- assertTrue(mBlockingHelperManager.isBlockingHelperRowNull());
-
- verify(mEntryManager).updateNotifications(anyString());
- }
-
- @Test
- public void testNonBlockable_package() {
- mBlockingHelperManager.setNonBlockablePkgs(new String[] {"banana", "strawberry:pie"});
-
- assertFalse(mBlockingHelperManager.isNonblockable("orange", "pie"));
-
- assertTrue(mBlockingHelperManager.isNonblockable("banana", "pie"));
- }
-
- @Test
- public void testNonBlockable_channel() {
- mBlockingHelperManager.setNonBlockablePkgs(new String[] {"banana", "strawberry:pie"});
-
- assertFalse(mBlockingHelperManager.isNonblockable("strawberry", "shortcake"));
-
- assertTrue(mBlockingHelperManager.isNonblockable("strawberry", "pie"));
- }
-
- private ExpandableNotificationRow createBlockableRowSpy() throws Exception {
- ExpandableNotificationRow row = spy(mHelper.createRow());
- when(row.getIsNonblockable()).thenReturn(false);
- return row;
- }
-
- private ExpandableNotificationRow createBlockableGroupRowSpy(int numChildren) throws Exception {
- ExpandableNotificationRow row = spy(mHelper.createGroup(numChildren));
- when(row.getIsNonblockable()).thenReturn(false);
- return row;
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
index 8fd6842..35d2363b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/stack/StackScrollAlgorithmTest.kt
@@ -3,19 +3,21 @@
import android.annotation.DimenRes
import android.widget.FrameLayout
import androidx.test.filters.SmallTest
+import com.android.keyguard.BouncerPanelExpansionCalculator.aboutToShowBouncerProgress
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.animation.ShadeInterpolation.getContentAlpha
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.EmptyShadeView
+import com.android.systemui.statusbar.NotificationShelf
+import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow
import com.android.systemui.statusbar.notification.row.ExpandableView
-import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.BypassController
-import com.android.systemui.statusbar.notification.stack.StackScrollAlgorithm.SectionProvider
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.google.common.truth.Truth.assertThat
+import junit.framework.Assert.assertEquals
import junit.framework.Assert.assertFalse
import junit.framework.Assert.assertTrue
-import junit.framework.Assert.assertEquals
import org.junit.Before
import org.junit.Test
import org.mockito.Mockito.mock
@@ -26,17 +28,20 @@
private val hostView = FrameLayout(context)
private val stackScrollAlgorithm = StackScrollAlgorithm(context, hostView)
- private val expandableViewState = ExpandableViewState()
private val notificationRow = mock(ExpandableNotificationRow::class.java)
private val dumpManager = mock(DumpManager::class.java)
private val mStatusBarKeyguardViewManager = mock(StatusBarKeyguardViewManager::class.java)
+ private val notificationShelf = mock(NotificationShelf::class.java)
+ private val emptyShadeView = EmptyShadeView(context, /* attrs= */ null).apply {
+ layout(/* l= */ 0, /* t= */ 0, /* r= */ 100, /* b= */ 100)
+ }
private val ambientState = AmbientState(
- context,
- dumpManager,
- SectionProvider { _, _ -> false },
- BypassController { false },
- mStatusBarKeyguardViewManager
+ context,
+ dumpManager,
+ /* sectionProvider */ { _, _ -> false },
+ /* bypassController */ { false },
+ mStatusBarKeyguardViewManager
)
private val testableResources = mContext.orCreateTestableResources
@@ -49,7 +54,9 @@
@Before
fun setUp() {
- whenever(notificationRow.viewState).thenReturn(expandableViewState)
+ whenever(notificationShelf.viewState).thenReturn(ExpandableViewState())
+ whenever(notificationRow.viewState).thenReturn(ExpandableViewState())
+
hostView.addView(notificationRow)
}
@@ -60,7 +67,8 @@
stackScrollAlgorithm.resetViewStates(ambientState, 0)
- assertThat(expandableViewState.yTranslation).isEqualTo(stackScrollAlgorithm.mHeadsUpInset)
+ assertThat(notificationRow.viewState.yTranslation)
+ .isEqualTo(stackScrollAlgorithm.mHeadsUpInset)
}
@Test
@@ -75,15 +83,12 @@
stackScrollAlgorithm.resetViewStates(ambientState, 0)
// top margin presence should decrease heads up translation up to minHeadsUpTranslation
- assertThat(expandableViewState.yTranslation).isEqualTo(minHeadsUpTranslation)
+ assertThat(notificationRow.viewState.yTranslation).isEqualTo(minHeadsUpTranslation)
}
@Test
fun resetViewStates_emptyShadeView_isCenteredVertically() {
stackScrollAlgorithm.initView(context)
- val emptyShadeView = EmptyShadeView(context, /* attrs= */ null).apply {
- layout(/* l= */ 0, /* t= */ 0, /* r= */ 100, /* b= */ 100)
- }
hostView.removeAllViews()
hostView.addView(emptyShadeView)
ambientState.layoutMaxHeight = 1280
@@ -98,6 +103,121 @@
}
@Test
+ fun resetViewStates_hunGoingToShade_viewBecomesOpaque() {
+ whenever(notificationRow.isAboveShelf).thenReturn(true)
+ ambientState.isShadeExpanded = true
+ ambientState.trackedHeadsUpRow = notificationRow
+ stackScrollAlgorithm.initView(context)
+
+ stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+ assertThat(notificationRow.viewState.alpha).isEqualTo(1f)
+ }
+
+ @Test
+ fun resetViewStates_isExpansionChanging_viewBecomesTransparent() {
+ whenever(mStatusBarKeyguardViewManager.isBouncerInTransit).thenReturn(false)
+ ambientState.isExpansionChanging = true
+ ambientState.expansionFraction = 0.25f
+ stackScrollAlgorithm.initView(context)
+
+ stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+ val expected = getContentAlpha(0.25f)
+ assertThat(notificationRow.viewState.alpha).isEqualTo(expected)
+ }
+
+ @Test
+ fun resetViewStates_isExpansionChangingWhileBouncerInTransit_viewBecomesTransparent() {
+ whenever(mStatusBarKeyguardViewManager.isBouncerInTransit).thenReturn(true)
+ ambientState.isExpansionChanging = true
+ ambientState.expansionFraction = 0.25f
+ stackScrollAlgorithm.initView(context)
+
+ stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+ val expected = aboutToShowBouncerProgress(0.25f)
+ assertThat(notificationRow.viewState.alpha).isEqualTo(expected)
+ }
+
+ @Test
+ fun resetViewStates_isOnKeyguard_viewBecomesTransparent() {
+ ambientState.setStatusBarState(StatusBarState.KEYGUARD)
+ ambientState.hideAmount = 0.25f
+ stackScrollAlgorithm.initView(context)
+
+ stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+ assertThat(notificationRow.viewState.alpha).isEqualTo(1f - ambientState.hideAmount)
+ }
+
+ @Test
+ fun resetViewStates_isOnKeyguard_emptyShadeViewBecomesTransparent() {
+ ambientState.setStatusBarState(StatusBarState.KEYGUARD)
+ ambientState.fractionToShade = 0.25f
+ stackScrollAlgorithm.initView(context)
+ hostView.removeAllViews()
+ hostView.addView(emptyShadeView)
+
+ stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+ val expected = getContentAlpha(ambientState.fractionToShade)
+ assertThat(emptyShadeView.viewState.alpha).isEqualTo(expected)
+ }
+
+ @Test
+ fun resetViewStates_isOnKeyguard_emptyShadeViewBecomesOpaque() {
+ ambientState.setStatusBarState(StatusBarState.SHADE)
+ ambientState.fractionToShade = 0.25f
+ stackScrollAlgorithm.initView(context)
+ hostView.removeAllViews()
+ hostView.addView(emptyShadeView)
+
+ stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+ assertThat(emptyShadeView.viewState.alpha).isEqualTo(1f)
+ }
+
+ @Test
+ fun resetViewStates_hiddenShelf_viewAlphaDoesNotChange() {
+ val expected = notificationShelf.viewState.alpha
+ notificationShelf.viewState.hidden = true
+ ambientState.shelf = notificationShelf
+ stackScrollAlgorithm.initView(context)
+
+ stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+ assertThat(notificationShelf.viewState.alpha).isEqualTo(expected)
+ }
+
+ @Test
+ fun resetViewStates_shelfTopLessThanViewTop_hidesView() {
+ notificationRow.viewState.yTranslation = 10f
+ notificationShelf.viewState.yTranslation = 0.9f
+ notificationShelf.viewState.hidden = false
+ ambientState.shelf = notificationShelf
+ stackScrollAlgorithm.initView(context)
+
+ stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+ assertThat(notificationRow.viewState.alpha).isEqualTo(0f)
+ }
+
+ @Test
+ fun resetViewStates_shelfTopGreaterOrEqualThanViewTop_viewAlphaDoesNotChange() {
+ val expected = notificationRow.viewState.alpha
+ notificationRow.viewState.yTranslation = 10f
+ notificationShelf.viewState.yTranslation = 10f
+ notificationShelf.viewState.hidden = false
+ ambientState.shelf = notificationShelf
+ stackScrollAlgorithm.initView(context)
+
+ stackScrollAlgorithm.resetViewStates(ambientState, /* speedBumpIndex= */ 0)
+
+ assertThat(notificationRow.viewState.alpha).isEqualTo(expected)
+ }
+
+ @Test
fun getGapForLocation_onLockscreen_returnsSmallGap() {
val gap = stackScrollAlgorithm.getGapForLocation(
/* fractionToShade= */ 0f, /* onKeyguard= */ true)
@@ -267,7 +387,6 @@
assertEquals(10f, expandableViewState.yTranslation)
}
-
@Test
fun clampHunToTop_viewYFarAboveVisibleStack_heightCollapsed() {
val expandableViewState = ExpandableViewState()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
index a6b7e51..ca98143 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerTest.java
@@ -58,7 +58,6 @@
@Before
public void setup() {
injectLeakCheckedDependencies(ALL_SUPPORTED_CLASSES);
- mDependency.injectMockDependency(DarkIconDispatcher.class);
}
@Test
@@ -75,7 +74,8 @@
layout,
mock(FeatureFlags.class),
mock(StatusBarPipelineFlags.class),
- () -> mock(WifiViewModel.class));
+ () -> mock(WifiViewModel.class),
+ mock(DarkIconDispatcher.class));
testCallOnAdd_forManager(manager);
}
@@ -116,8 +116,10 @@
LinearLayout group,
FeatureFlags featureFlags,
StatusBarPipelineFlags statusBarPipelineFlags,
- Provider<WifiViewModel> wifiViewModelProvider) {
- super(group, featureFlags, statusBarPipelineFlags, wifiViewModelProvider);
+ Provider<WifiViewModel> wifiViewModelProvider,
+ DarkIconDispatcher darkIconDispatcher) {
+ super(group, featureFlags, statusBarPipelineFlags, wifiViewModelProvider,
+ darkIconDispatcher);
}
@Override
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
index 9829271..d070ba0 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/wifi/data/repository/WifiRepositoryImplTest.kt
@@ -473,6 +473,40 @@
job.cancel()
}
+ /** Regression test for b/244173280. */
+ @Test
+ fun wifiNetwork_multipleSubscribers_newSubscribersGetCurrentValue() = runBlocking(IMMEDIATE) {
+ var latest1: WifiNetworkModel? = null
+ val job1 = underTest
+ .wifiNetwork
+ .onEach { latest1 = it }
+ .launchIn(this)
+
+ getNetworkCallback()
+ .onCapabilitiesChanged(NETWORK, createWifiNetworkCapabilities(PRIMARY_WIFI_INFO))
+
+ assertThat(latest1 is WifiNetworkModel.Active).isTrue()
+ val latest1Active = latest1 as WifiNetworkModel.Active
+ assertThat(latest1Active.networkId).isEqualTo(NETWORK_ID)
+ assertThat(latest1Active.ssid).isEqualTo(SSID)
+
+ // WHEN we add a second subscriber after having already emitted a value
+ var latest2: WifiNetworkModel? = null
+ val job2 = underTest
+ .wifiNetwork
+ .onEach { latest2 = it }
+ .launchIn(this)
+
+ // THEN the second subscribe receives the already-emitted value
+ assertThat(latest2 is WifiNetworkModel.Active).isTrue()
+ val latest2Active = latest2 as WifiNetworkModel.Active
+ assertThat(latest2Active.networkId).isEqualTo(NETWORK_ID)
+ assertThat(latest2Active.ssid).isEqualTo(SSID)
+
+ job1.cancel()
+ job2.cancel()
+ }
+
@Test
fun wifiActivity_nullWifiManager_receivesDefault() = runBlocking(IMMEDIATE) {
underTest = WifiRepositoryImpl(
diff --git a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
index cdddc1d..2b644fe 100644
--- a/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/virtual/VirtualDeviceManagerService.java
@@ -41,6 +41,7 @@
import android.os.Parcel;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.util.ArraySet;
import android.util.ExceptionUtils;
import android.util.Slog;
import android.util.SparseArray;
@@ -87,6 +88,12 @@
private final SparseArray<VirtualDeviceImpl> mVirtualDevices = new SparseArray<>();
/**
+ * Mapping from CDM association IDs to app UIDs running on the corresponding virtual device.
+ */
+ @GuardedBy("mVirtualDeviceManagerLock")
+ private final SparseArray<ArraySet<Integer>> mAppsOnVirtualDevices = new SparseArray<>();
+
+ /**
* Mapping from user ID to CDM associations. The associations come from
* {@link CompanionDeviceManager#getAllAssociations()}, which contains associations across all
* packages.
@@ -213,6 +220,14 @@
return mLocalService;
}
+ @VisibleForTesting
+ void notifyRunningAppsChanged(int associationId, ArraySet<Integer> uids) {
+ synchronized (mVirtualDeviceManagerLock) {
+ mAppsOnVirtualDevices.put(associationId, uids);
+ }
+ mLocalService.onAppsOnVirtualDeviceChanged();
+ }
+
class VirtualDeviceManagerImpl extends IVirtualDeviceManager.Stub implements
VirtualDeviceImpl.PendingTrampolineCallback {
@@ -252,6 +267,7 @@
public void onClose(int associationId) {
synchronized (mVirtualDeviceManagerLock) {
mVirtualDevices.remove(associationId);
+ mAppsOnVirtualDevices.remove(associationId);
if (cameraAccessController != null) {
cameraAccessController.stopObservingIfNeeded();
} else {
@@ -262,8 +278,10 @@
}
},
this, activityListener,
- runningUids -> cameraAccessController.blockCameraAccessIfNeeded(
- runningUids),
+ runningUids -> {
+ cameraAccessController.blockCameraAccessIfNeeded(runningUids);
+ notifyRunningAppsChanged(associationInfo.getId(), runningUids);
+ },
params);
if (cameraAccessController != null) {
cameraAccessController.startObservingIfNeeded();
@@ -385,8 +403,13 @@
private final class LocalService extends VirtualDeviceManagerInternal {
@GuardedBy("mVirtualDeviceManagerLock")
- private final ArrayList<VirtualDeviceManagerInternal.VirtualDisplayListener>
+ private final ArrayList<VirtualDisplayListener>
mVirtualDisplayListeners = new ArrayList<>();
+ @GuardedBy("mVirtualDeviceManagerLock")
+ private final ArrayList<AppsOnVirtualDeviceListener>
+ mAppsOnVirtualDeviceListeners = new ArrayList<>();
+ @GuardedBy("mVirtualDeviceManagerLock")
+ private final ArraySet<Integer> mAllUidsOnVirtualDevice = new ArraySet<>();
@Override
public boolean isValidVirtualDevice(IVirtualDevice virtualDevice) {
@@ -423,6 +446,34 @@
}
@Override
+ public void onAppsOnVirtualDeviceChanged() {
+ ArraySet<Integer> latestRunningUids = new ArraySet<>();
+ final AppsOnVirtualDeviceListener[] listeners;
+ synchronized (mVirtualDeviceManagerLock) {
+ int size = mAppsOnVirtualDevices.size();
+ for (int i = 0; i < size; i++) {
+ latestRunningUids.addAll(mAppsOnVirtualDevices.valueAt(i));
+ }
+ if (!mAllUidsOnVirtualDevice.equals(latestRunningUids)) {
+ mAllUidsOnVirtualDevice.clear();
+ mAllUidsOnVirtualDevice.addAll(latestRunningUids);
+ listeners =
+ mAppsOnVirtualDeviceListeners.toArray(
+ new AppsOnVirtualDeviceListener[0]);
+ } else {
+ listeners = null;
+ }
+ }
+ if (listeners != null) {
+ mHandler.post(() -> {
+ for (AppsOnVirtualDeviceListener listener : listeners) {
+ listener.onAppsOnAnyVirtualDeviceChanged(latestRunningUids);
+ }
+ });
+ }
+ }
+
+ @Override
public int getBaseVirtualDisplayFlags(IVirtualDevice virtualDevice) {
return ((VirtualDeviceImpl) virtualDevice).getBaseVirtualDisplayFlags();
}
@@ -481,6 +532,22 @@
mVirtualDisplayListeners.remove(listener);
}
}
+
+ @Override
+ public void registerAppsOnVirtualDeviceListener(
+ @NonNull AppsOnVirtualDeviceListener listener) {
+ synchronized (mVirtualDeviceManagerLock) {
+ mAppsOnVirtualDeviceListeners.add(listener);
+ }
+ }
+
+ @Override
+ public void unregisterAppsOnVirtualDeviceListener(
+ @NonNull AppsOnVirtualDeviceListener listener) {
+ synchronized (mVirtualDeviceManagerLock) {
+ mAppsOnVirtualDeviceListeners.remove(listener);
+ }
+ }
}
private static final class PendingTrampolineMap {
diff --git a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
index 230bfc5..81b56a3 100644
--- a/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
+++ b/services/core/java/com/android/server/companion/virtual/VirtualDeviceManagerInternal.java
@@ -19,6 +19,8 @@
import android.annotation.NonNull;
import android.companion.virtual.IVirtualDevice;
+import java.util.Set;
+
/**
* Virtual device manager local service interface.
* Only for use within system server.
@@ -34,14 +36,35 @@
void onVirtualDisplayRemoved(int displayId);
}
+
+ /** Interface to listen to the changes on the list of app UIDs running on any virtual device. */
+ public interface AppsOnVirtualDeviceListener {
+ /** Notifies that running apps on any virtual device has changed */
+ void onAppsOnAnyVirtualDeviceChanged(Set<Integer> allRunningUids);
+ }
+
/** Register a listener for the creation and destruction of virtual displays. */
public abstract void registerVirtualDisplayListener(
@NonNull VirtualDisplayListener listener);
- /** Unregister a listener for the creation and destruction of virtual displays. */
+ /** Unregister a listener for the creation and destruction of virtual displays. */
public abstract void unregisterVirtualDisplayListener(
@NonNull VirtualDisplayListener listener);
+ /** Register a listener for changes of running app UIDs on any virtual device. */
+ public abstract void registerAppsOnVirtualDeviceListener(
+ @NonNull AppsOnVirtualDeviceListener listener);
+
+ /** Unregister a listener for changes of running app UIDs on any virtual device. */
+ public abstract void unregisterAppsOnVirtualDeviceListener(
+ @NonNull AppsOnVirtualDeviceListener listener);
+
+ /**
+ * Notifies that the set of apps running on virtual devices has changed.
+ * This method only notifies the listeners when the union of running UIDs on all virtual devices
+ * has changed.
+ */
+ public abstract void onAppsOnVirtualDeviceChanged();
/**
* Validate the virtual device.
diff --git a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
index 966df4f..cc2cdba 100644
--- a/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/companion/virtual/VirtualDeviceManagerServiceTest.java
@@ -35,6 +35,7 @@
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.when;
import static org.testng.Assert.assertThrows;
@@ -110,6 +111,12 @@
private static final String GOOGLE_MAPS_PACKAGE_NAME = "com.google.android.apps.maps";
private static final String DEVICE_NAME = "device name";
private static final int DISPLAY_ID = 2;
+ private static final int UID_1 = 0;
+ private static final int UID_2 = 10;
+ private static final int UID_3 = 10000;
+ private static final int UID_4 = 10001;
+ private static final int ASSOCIATION_ID_1 = 1;
+ private static final int ASSOCIATION_ID_2 = 2;
private static final int PRODUCT_ID = 10;
private static final int VENDOR_ID = 5;
private static final String UNIQUE_ID = "uniqueid";
@@ -143,6 +150,8 @@
@Mock
private VirtualDeviceManagerInternal.VirtualDisplayListener mDisplayListener;
@Mock
+ private VirtualDeviceManagerInternal.AppsOnVirtualDeviceListener mAppsOnVirtualDeviceListener;
+ @Mock
IPowerManager mIPowerManagerMock;
@Mock
IThermalService mIThermalServiceMock;
@@ -242,7 +251,7 @@
}
@Test
- public void onVirtualDisplayCreatedLocked_listenersNotified() throws RemoteException {
+ public void onVirtualDisplayCreatedLocked_listenersNotified() {
mLocalService.registerVirtualDisplayListener(mDisplayListener);
mLocalService.onVirtualDisplayCreated(DISPLAY_ID);
@@ -252,7 +261,7 @@
}
@Test
- public void onVirtualDisplayRemovedLocked_listenersNotified() throws RemoteException {
+ public void onVirtualDisplayRemovedLocked_listenersNotified() {
mLocalService.registerVirtualDisplayListener(mDisplayListener);
mDeviceImpl.onVirtualDisplayCreatedLocked(
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
@@ -264,13 +273,61 @@
}
@Test
+ public void onAppsOnVirtualDeviceChanged_singleVirtualDevice_listenersNotified() {
+ ArraySet<Integer> uids = new ArraySet<>(Arrays.asList(UID_1, UID_2));
+ mLocalService.registerAppsOnVirtualDeviceListener(mAppsOnVirtualDeviceListener);
+
+ mVdms.notifyRunningAppsChanged(ASSOCIATION_ID_1, uids);
+ TestableLooper.get(this).processAllMessages();
+
+ verify(mAppsOnVirtualDeviceListener).onAppsOnAnyVirtualDeviceChanged(uids);
+ }
+
+ @Test
+ public void onAppsOnVirtualDeviceChanged_multipleVirtualDevices_listenersNotified() {
+ ArraySet<Integer> uidsOnDevice1 = new ArraySet<>(Arrays.asList(UID_1, UID_2));
+ ArraySet<Integer> uidsOnDevice2 = new ArraySet<>(Arrays.asList(UID_3, UID_4));
+ mLocalService.registerAppsOnVirtualDeviceListener(mAppsOnVirtualDeviceListener);
+
+ // Notifies that the running apps on the first virtual device has changed.
+ mVdms.notifyRunningAppsChanged(ASSOCIATION_ID_1, uidsOnDevice1);
+ TestableLooper.get(this).processAllMessages();
+ verify(mAppsOnVirtualDeviceListener).onAppsOnAnyVirtualDeviceChanged(
+ new ArraySet<>(Arrays.asList(UID_1, UID_2)));
+
+ // Notifies that the running apps on the second virtual device has changed.
+ mVdms.notifyRunningAppsChanged(ASSOCIATION_ID_2, uidsOnDevice2);
+ TestableLooper.get(this).processAllMessages();
+ // The union of the apps running on both virtual devices are sent to the listeners.
+ verify(mAppsOnVirtualDeviceListener).onAppsOnAnyVirtualDeviceChanged(
+ new ArraySet<>(Arrays.asList(UID_1, UID_2, UID_3, UID_4)));
+
+ // Notifies that the running apps on the first virtual device has changed again.
+ uidsOnDevice1.remove(UID_2);
+ mVdms.notifyRunningAppsChanged(ASSOCIATION_ID_1, uidsOnDevice1);
+ mLocalService.onAppsOnVirtualDeviceChanged();
+ TestableLooper.get(this).processAllMessages();
+ // The union of the apps running on both virtual devices are sent to the listeners.
+ verify(mAppsOnVirtualDeviceListener).onAppsOnAnyVirtualDeviceChanged(
+ new ArraySet<>(Arrays.asList(UID_1, UID_3, UID_4)));
+
+ // Notifies that the running apps on the first virtual device has changed but with the same
+ // set of UIDs.
+ mVdms.notifyRunningAppsChanged(ASSOCIATION_ID_1, uidsOnDevice1);
+ mLocalService.onAppsOnVirtualDeviceChanged();
+ TestableLooper.get(this).processAllMessages();
+ // Listeners should not be notified.
+ verifyNoMoreInteractions(mAppsOnVirtualDeviceListener);
+ }
+
+ @Test
public void onVirtualDisplayCreatedLocked_wakeLockIsAcquired() throws RemoteException {
verify(mIPowerManagerMock, never()).acquireWakeLock(any(Binder.class), anyInt(),
nullable(String.class), nullable(String.class), nullable(WorkSource.class),
nullable(String.class), anyInt(), eq(null));
mDeviceImpl.onVirtualDisplayCreatedLocked(
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
- verify(mIPowerManagerMock, Mockito.times(1)).acquireWakeLock(any(Binder.class), anyInt(),
+ verify(mIPowerManagerMock).acquireWakeLock(any(Binder.class), anyInt(),
nullable(String.class), nullable(String.class), nullable(WorkSource.class),
nullable(String.class), eq(DISPLAY_ID), eq(null));
}
@@ -284,7 +341,7 @@
assertThrows(IllegalStateException.class,
() -> mDeviceImpl.onVirtualDisplayCreatedLocked(gwpc, DISPLAY_ID));
TestableLooper.get(this).processAllMessages();
- verify(mIPowerManagerMock, Mockito.times(1)).acquireWakeLock(any(Binder.class), anyInt(),
+ verify(mIPowerManagerMock).acquireWakeLock(any(Binder.class), anyInt(),
nullable(String.class), nullable(String.class), nullable(WorkSource.class),
nullable(String.class), eq(DISPLAY_ID), eq(null));
}
@@ -302,14 +359,14 @@
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
ArgumentCaptor<IBinder> wakeLockCaptor = ArgumentCaptor.forClass(IBinder.class);
TestableLooper.get(this).processAllMessages();
- verify(mIPowerManagerMock, Mockito.times(1)).acquireWakeLock(wakeLockCaptor.capture(),
+ verify(mIPowerManagerMock).acquireWakeLock(wakeLockCaptor.capture(),
anyInt(),
nullable(String.class), nullable(String.class), nullable(WorkSource.class),
nullable(String.class), eq(DISPLAY_ID), eq(null));
IBinder wakeLock = wakeLockCaptor.getValue();
mDeviceImpl.onVirtualDisplayRemovedLocked(DISPLAY_ID);
- verify(mIPowerManagerMock, Mockito.times(1)).releaseWakeLock(eq(wakeLock), anyInt());
+ verify(mIPowerManagerMock).releaseWakeLock(eq(wakeLock), anyInt());
}
@Test
@@ -318,7 +375,7 @@
mDeviceImpl.createWindowPolicyController(), DISPLAY_ID);
ArgumentCaptor<IBinder> wakeLockCaptor = ArgumentCaptor.forClass(IBinder.class);
TestableLooper.get(this).processAllMessages();
- verify(mIPowerManagerMock, Mockito.times(1)).acquireWakeLock(wakeLockCaptor.capture(),
+ verify(mIPowerManagerMock).acquireWakeLock(wakeLockCaptor.capture(),
anyInt(),
nullable(String.class), nullable(String.class), nullable(WorkSource.class),
nullable(String.class), eq(DISPLAY_ID), eq(null));
@@ -326,7 +383,7 @@
// Close the VirtualDevice without first notifying it of the VirtualDisplay removal.
mDeviceImpl.close();
- verify(mIPowerManagerMock, Mockito.times(1)).releaseWakeLock(eq(wakeLock), anyInt());
+ verify(mIPowerManagerMock).releaseWakeLock(eq(wakeLock), anyInt());
}
@Test