DivestOS/Patches/LineageOS-18.1/android_frameworks_base/392206.patch
Tavi 0dcdeb029a
Import Q_asb_2024-04 and R_asb_2024-05 + fixups
Signed-off-by: Tavi <tavi@divested.dev>
2024-05-11 11:14:58 -04:00

134 lines
5.8 KiB
Diff

From 402c96a6689e35f11b3de7f86ec010002da7772a Mon Sep 17 00:00:00 2001
From: Jan Tomljanovic <jtomljanovic@google.com>
Date: Fri, 6 Nov 2020 11:28:09 +0000
Subject: [PATCH] Don't try to show the current toast again while it's showing.
By doing this we avoid a few bad things:
- mechanism that hides the current toast by trying to show it again
- delaying the call to hide and remove the current toast from the queue
when it's duration expires (which in the case of repeated calls can
delay this indefinitely)
Test: atest NotificationManagerServiceTest
Test: atest android.widget.cts.ToastTest
Bug: 167672740
Change-Id: Ie4953109314113efae49fa0c5e0c236e6e0dbb23
---
.../NotificationManagerService.java | 13 +++++
.../NotificationManagerServiceTest.java | 53 +++++++++++++++++++
2 files changed, 66 insertions(+)
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 32873445b5e6f..11c89bbdf4d94 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -493,6 +493,10 @@ public class NotificationManagerService extends SystemService {
private KeyguardManager mKeyguardManager;
+ // True if the toast that's on top of the queue is being shown at the moment.
+ @GuardedBy("mToastQueue")
+ private boolean mIsCurrentToastShown = false;
+
// The last key in this list owns the hardware.
ArrayList<String> mLights = new ArrayList<>();
@@ -7444,10 +7448,15 @@ public void run() {
@GuardedBy("mToastQueue")
void showNextToastLocked() {
+ if (mIsCurrentToastShown) {
+ return; // Don't show the same toast twice.
+ }
+
ToastRecord record = mToastQueue.get(0);
while (record != null) {
if (record.show()) {
scheduleDurationReachedLocked(record);
+ mIsCurrentToastShown = true;
return;
}
int index = mToastQueue.indexOf(record);
@@ -7463,6 +7472,10 @@ void cancelToastLocked(int index) {
ToastRecord record = mToastQueue.get(index);
record.hide();
+ if (index == 0) {
+ mIsCurrentToastShown = false;
+ }
+
ToastRecord lastToast = mToastQueue.remove(index);
mWindowManagerInternal.removeWindowToken(lastToast.windowToken, false /* removeWindows */,
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 9ed2b17de4237..3a108144ad66a 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -5341,6 +5341,32 @@ public void testDisallowBackgroundCustomToasts() throws Exception {
assertEquals(0, mService.mToastQueue.size());
}
+ @Test
+ public void testDontCallShowToastAgainOnTheSameCustomToast() throws Exception {
+ final String testPackage = "testPackageName";
+ assertEquals(0, mService.mToastQueue.size());
+ mService.isSystemUid = false;
+
+ // package is not suspended
+ when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
+ .thenReturn(false);
+
+ setAppInForegroundForToasts(mUid, true);
+
+ Binder token = new Binder();
+ ITransientNotification callback = mock(ITransientNotification.class);
+ INotificationManager nmService = (INotificationManager) mService.mService;
+
+ // first time trying to show the toast, showToast gets called
+ nmService.enqueueToast(testPackage, token, callback, 2000, 0);
+ verify(callback, times(1)).show(any());
+
+ // second time trying to show the same toast, showToast isn't called again (total number of
+ // invocations stays at one)
+ nmService.enqueueToast(testPackage, token, callback, 2000, 0);
+ verify(callback, times(1)).show(any());
+ }
+
@Test
public void testAllowForegroundTextToasts() throws Exception {
final String testPackage = "testPackageName";
@@ -5377,6 +5403,33 @@ public void testAllowBackgroundTextToasts() throws Exception {
assertEquals(1, mService.mToastQueue.size());
}
+ @Test
+ public void testDontCallShowToastAgainOnTheSameTextToast() throws Exception {
+ final String testPackage = "testPackageName";
+ assertEquals(0, mService.mToastQueue.size());
+ mService.isSystemUid = false;
+
+ // package is not suspended
+ when(mPackageManager.isPackageSuspendedForUser(testPackage, UserHandle.getUserId(mUid)))
+ .thenReturn(false);
+
+ setAppInForegroundForToasts(mUid, true);
+
+ Binder token = new Binder();
+ INotificationManager nmService = (INotificationManager) mService.mService;
+
+ // first time trying to show the toast, showToast gets called
+ nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null);
+ verify(mStatusBar, times(1))
+ .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any());
+
+ // second time trying to show the same toast, showToast isn't called again (total number of
+ // invocations stays at one)
+ nmService.enqueueTextToast(testPackage, token, "Text", 2000, 0, null);
+ verify(mStatusBar, times(1))
+ .showToast(anyInt(), any(), any(), any(), any(), anyInt(), any());
+ }
+
@Test
public void testTextToastsCallStatusBar() throws Exception {
final String testPackage = "testPackageName";