From 844938e7446bc07a4eccd2a82547480e97a0faca Mon Sep 17 00:00:00 2001 From: Yuri Lin Date: Wed, 5 Jan 2022 16:12:22 -0500 Subject: [PATCH] Add a field to ServiceRecord for FGS notification permissions. This field will be logged in the pushed atom for FGS state changes in a future CL, and will help us understand how often a foreground service runs without permission to post notifications. This change adds areNotificationsEnabledForPackage to NotificationManagerInternal for ease of access via ServiceRecord. Bug: 194833441 Test: NMSTest, NotificationPermissionMigrationTest, manual for ServiceRecord Change-Id: I543e68479d57f197937a22217668840dfed1429e --- .../core/java/com/android/server/am/ServiceRecord.java | 6 ++++++ .../server/notification/NotificationManagerInternal.java | 3 +++ .../server/notification/NotificationManagerService.java | 5 +++++ .../notification/NotificationManagerServiceTest.java | 9 ++++++++- .../NotificationPermissionMigrationTest.java | 6 ++++++ 5 files changed, 28 insertions(+), 1 deletion(-) diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java index 9b731d58153ce..b3e46cd0b5269 100644 --- a/services/core/java/com/android/server/am/ServiceRecord.java +++ b/services/core/java/com/android/server/am/ServiceRecord.java @@ -174,6 +174,9 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN boolean mFgsNotificationWasDeferred; // FGS notification was shown before the FGS finishes, or it wasn't deferred in the first place. boolean mFgsNotificationShown; + // Whether FGS package has permissions to show notifications. + // TODO(b/194833441): Output this field to logs in ActiveServices#logFGSStateChangeLocked. + boolean mFgsHasNotificationPermission; // allow the service becomes foreground service? Service started from background may not be // allowed to become a foreground service. @@ -968,6 +971,9 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN if (nm == null) { return; } + // Record whether the package has permission to notify the user + mFgsHasNotificationPermission = nm.areNotificationsEnabledForPackage( + localPackageName, appUid); Notification localForegroundNoti = _foregroundNoti; try { if (localForegroundNoti.getSmallIcon() == null) { diff --git a/services/core/java/com/android/server/notification/NotificationManagerInternal.java b/services/core/java/com/android/server/notification/NotificationManagerInternal.java index 54557386d73ce..c548e7edc3cff 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerInternal.java +++ b/services/core/java/com/android/server/notification/NotificationManagerInternal.java @@ -39,4 +39,7 @@ public interface NotificationManagerInternal { /** Get the number of notification channels for a given package */ int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted); + + /** Does the specified package/uid have permission to post notifications? */ + boolean areNotificationsEnabledForPackage(String pkg, int uid); } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index a0eeb6553088c..399ae5347e6eb 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -6205,6 +6205,11 @@ public class NotificationManagerService extends SystemService { return NotificationManagerService.this .getNumNotificationChannelsForPackage(pkg, uid, includeDeleted); } + + @Override + public boolean areNotificationsEnabledForPackage(String pkg, int uid) { + return areNotificationsEnabledForPackageInt(pkg, uid); + } }; int getNumNotificationChannelsForPackage(String pkg, int uid, boolean includeDeleted) { 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 11777ef7c1e07..d83190353a87f 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -182,7 +182,6 @@ import android.text.TextUtils; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; -import android.util.Slog; import android.util.TypedXmlPullParser; import android.util.TypedXmlSerializer; import android.util.Xml; @@ -7173,6 +7172,14 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { verify(mPermissionHelper, never()).hasPermission(anyInt()); } + @Test + public void testAreNotificationsEnabledForPackage_viaInternalService() throws Exception { + assertEquals(mInternalService.areNotificationsEnabledForPackage( + mContext.getPackageName(), mUid), + mBinderService.areNotificationsEnabledForPackage(mContext.getPackageName(), mUid)); + verify(mPermissionHelper, never()).hasPermission(anyInt()); + } + @Test public void testAreBubblesAllowedForPackage_crossUser() throws Exception { try { diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java index 0c8fe35484f78..1362628bde5e2 100755 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationPermissionMigrationTest.java @@ -535,6 +535,12 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase { verify(mPermissionHelper).hasPermission(mUid + UserHandle.PER_USER_RANGE); } + @Test + public void testAreNotificationsEnabledForPackage_viaInternalService() { + mInternalService.areNotificationsEnabledForPackage(mContext.getPackageName(), mUid); + verify(mPermissionHelper).hasPermission(mUid); + } + @Test public void testGetPackageImportance() throws Exception { when(mPermissionHelper.hasPermission(mUid)).thenReturn(true);