Merge "Check permission when posting notification"
This commit is contained in:
committed by
Android (Google) Code Review
commit
d5e1a8da5a
@@ -139,6 +139,33 @@ public class StatusBarNotification implements Parcelable {
|
||||
this.groupKey = groupKey();
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static int getUidFromKey(@NonNull String key) {
|
||||
String[] parts = key.split("\\|");
|
||||
if (parts.length >= 5) {
|
||||
try {
|
||||
int uid = Integer.parseInt(parts[4]);
|
||||
return uid;
|
||||
} catch (NumberFormatException e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @hide
|
||||
*/
|
||||
public static String getPkgFromKey(@NonNull String key) {
|
||||
String[] parts = key.split("\\|");
|
||||
if (parts.length >= 2) {
|
||||
return parts[1];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private String key() {
|
||||
String sbnKey = user.getIdentifier() + "|" + pkg + "|" + id + "|" + tag + "|" + uid;
|
||||
if (overrideGroupKey != null && getNotification().isGroupSummary()) {
|
||||
|
||||
@@ -23,6 +23,7 @@ import static junit.framework.Assert.assertNull;
|
||||
|
||||
import static org.junit.Assert.assertFalse;
|
||||
import static org.junit.Assert.assertTrue;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -54,6 +55,7 @@ public class StatusBarNotificationTest {
|
||||
private final Context mMockContext = mock(Context.class);
|
||||
@Mock
|
||||
private Context mRealContext;
|
||||
@Mock
|
||||
private PackageManager mPm;
|
||||
|
||||
private static final String PKG = "com.example.o";
|
||||
@@ -78,6 +80,7 @@ public class StatusBarNotificationTest {
|
||||
InstrumentationRegistry.getContext().getResources());
|
||||
when(mMockContext.getPackageManager()).thenReturn(mPm);
|
||||
when(mMockContext.getApplicationInfo()).thenReturn(new ApplicationInfo());
|
||||
when(mPm.getApplicationLabel(any())).thenReturn("");
|
||||
|
||||
mRealContext = InstrumentationRegistry.getContext();
|
||||
}
|
||||
@@ -217,6 +220,26 @@ public class StatusBarNotificationTest {
|
||||
assertEquals(pkg, resultContext.getPackageName());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetUidFromKey() {
|
||||
StatusBarNotification sbn = getNotification("pkg", null, "channel");
|
||||
|
||||
assertEquals(UID, StatusBarNotification.getUidFromKey(sbn.getKey()));
|
||||
|
||||
sbn.setOverrideGroupKey("addsToKey");
|
||||
assertEquals(UID, StatusBarNotification.getUidFromKey(sbn.getKey()));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testGetPkgFromKey() {
|
||||
StatusBarNotification sbn = getNotification("pkg", null, "channel");
|
||||
|
||||
assertEquals("pkg", StatusBarNotification.getPkgFromKey(sbn.getKey()));
|
||||
|
||||
sbn.setOverrideGroupKey("addsToKey");
|
||||
assertEquals("pkg", StatusBarNotification.getPkgFromKey(sbn.getKey()));
|
||||
}
|
||||
|
||||
private StatusBarNotification getNotification(String pkg, String group, String channelId) {
|
||||
return getNotification(pkg, getNotificationBuilder(group, channelId));
|
||||
}
|
||||
|
||||
@@ -3544,11 +3544,7 @@ public class NotificationManagerService extends SystemService {
|
||||
"canNotifyAsPackage for uid " + uid);
|
||||
}
|
||||
|
||||
if (mEnableAppSettingMigration) {
|
||||
return mPermissionHelper.hasPermission(uid);
|
||||
} else {
|
||||
return mPreferencesHelper.getImportance(pkg, uid) != IMPORTANCE_NONE;
|
||||
}
|
||||
return areNotificationsEnabledForPackageInt(pkg, uid);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -6732,13 +6728,30 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
|
||||
// blocked apps
|
||||
if (isBlocked(r, mUsageStats)) {
|
||||
boolean isBlocked = !areNotificationsEnabledForPackageInt(pkg, uid);
|
||||
synchronized (mNotificationLock) {
|
||||
isBlocked |= isRecordBlockedLocked(r);
|
||||
}
|
||||
if (isBlocked) {
|
||||
if (DBG) {
|
||||
Slog.e(TAG, "Suppressing notification from package " + r.getSbn().getPackageName()
|
||||
+ " by user request.");
|
||||
}
|
||||
mUsageStats.registerBlocked(r);
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean areNotificationsEnabledForPackageInt(String pkg, int uid) {
|
||||
if (mEnableAppSettingMigration) {
|
||||
return mPermissionHelper.hasPermission(uid);
|
||||
} else {
|
||||
return mPreferencesHelper.getImportance(pkg, uid) != IMPORTANCE_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
protected int getNotificationCount(String pkg, int userId, int excludedId,
|
||||
String excludedTag) {
|
||||
int count = 0;
|
||||
@@ -6767,24 +6780,15 @@ public class NotificationManagerService extends SystemService {
|
||||
return count;
|
||||
}
|
||||
|
||||
protected boolean isBlocked(NotificationRecord r, NotificationUsageStats usageStats) {
|
||||
if (isBlocked(r)) {
|
||||
if (DBG) {
|
||||
Slog.e(TAG, "Suppressing notification from package " + r.getSbn().getPackageName()
|
||||
+ " by user request.");
|
||||
}
|
||||
usageStats.registerBlocked(r);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean isBlocked(NotificationRecord r) {
|
||||
/**
|
||||
* Checks whether a notification is banned at a group or channel level or if the NAS or system
|
||||
* has blocked the notification.
|
||||
*/
|
||||
@GuardedBy("mNotificationLock")
|
||||
boolean isRecordBlockedLocked(NotificationRecord r) {
|
||||
final String pkg = r.getSbn().getPackageName();
|
||||
final int callingUid = r.getSbn().getUid();
|
||||
return mPreferencesHelper.isGroupBlocked(pkg, callingUid, r.getChannel().getGroup())
|
||||
|| mPreferencesHelper.getImportance(pkg, callingUid)
|
||||
== NotificationManager.IMPORTANCE_NONE
|
||||
|| r.getImportance() == NotificationManager.IMPORTANCE_NONE;
|
||||
}
|
||||
|
||||
@@ -7095,6 +7099,9 @@ public class NotificationManagerService extends SystemService {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
String pkg = StatusBarNotification.getPkgFromKey(key);
|
||||
int uid = StatusBarNotification.getUidFromKey(key);
|
||||
boolean appBanned = !areNotificationsEnabledForPackageInt(pkg, uid);
|
||||
synchronized (mNotificationLock) {
|
||||
try {
|
||||
NotificationRecord r = null;
|
||||
@@ -7111,8 +7118,11 @@ public class NotificationManagerService extends SystemService {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isBlocked(r)) {
|
||||
Slog.i(TAG, "notification blocked by assistant request");
|
||||
if (appBanned || isRecordBlockedLocked(r)) {
|
||||
mUsageStats.registerBlocked(r);
|
||||
if (DBG) {
|
||||
Slog.e(TAG, "Suppressing notification from package " + pkg);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -182,7 +182,6 @@ import android.util.TypedXmlSerializer;
|
||||
import android.util.Xml;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
|
||||
import com.android.internal.app.IAppOpsService;
|
||||
@@ -1040,7 +1039,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
NotificationRecord r = generateNotificationRecord(channel);
|
||||
|
||||
// isBlocked is only used for user blocking, not app suspension
|
||||
assertFalse(mService.isBlocked(r, mUsageStats));
|
||||
assertFalse(mService.isRecordBlockedLocked(r));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1050,8 +1049,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
NotificationChannel channel = new NotificationChannel("id", "name",
|
||||
NotificationManager.IMPORTANCE_NONE);
|
||||
NotificationRecord r = generateNotificationRecord(channel);
|
||||
assertTrue(mService.isBlocked(r, mUsageStats));
|
||||
verify(mUsageStats, times(1)).registerBlocked(eq(r));
|
||||
assertTrue(mService.isRecordBlockedLocked(r));
|
||||
|
||||
mBinderService.createNotificationChannels(
|
||||
PKG, new ParceledListSlice(Arrays.asList(channel)));
|
||||
@@ -1148,8 +1146,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
NotificationManager.IMPORTANCE_HIGH);
|
||||
channel.setGroup("something");
|
||||
NotificationRecord r = generateNotificationRecord(channel);
|
||||
assertTrue(mService.isBlocked(r, mUsageStats));
|
||||
verify(mUsageStats, times(1)).registerBlocked(eq(r));
|
||||
assertTrue(mService.isRecordBlockedLocked(r));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -1286,6 +1283,40 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
|
||||
verify(mUsageStats, never()).registerPostedByApp(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockedNotifications_blockedByUser() throws Exception {
|
||||
mService.setPreferencesHelper(mPreferencesHelper);
|
||||
when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
|
||||
when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
|
||||
|
||||
NotificationChannel channel = new NotificationChannel("id", "name",
|
||||
NotificationManager.IMPORTANCE_HIGH);
|
||||
NotificationRecord r = generateNotificationRecord(channel);
|
||||
mService.addEnqueuedNotification(r);
|
||||
|
||||
when(mPreferencesHelper.getImportance(anyString(), anyInt())).thenReturn(IMPORTANCE_NONE);
|
||||
|
||||
NotificationManagerService.PostNotificationRunnable runnable =
|
||||
mService.new PostNotificationRunnable(r.getKey());
|
||||
runnable.run();
|
||||
waitForIdle();
|
||||
|
||||
verify(mUsageStats).registerBlocked(any());
|
||||
verify(mUsageStats, never()).registerPostedByApp(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnqueueNotification_appBlocked() throws Exception {
|
||||
mBinderService.setNotificationsEnabledForPackage(PKG, mUid, false);
|
||||
|
||||
mBinderService.enqueueNotificationWithTag(PKG, PKG,
|
||||
"testEnqueueNotification_appBlocked", 0,
|
||||
generateNotificationRecord(null).getNotification(), 0);
|
||||
waitForIdle();
|
||||
verify(mWorkerHandler, never()).post(
|
||||
any(NotificationManagerService.EnqueueNotificationRunnable.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnqueueNotificationWithTag_PopulatesGetActiveNotifications() throws Exception {
|
||||
mBinderService.enqueueNotificationWithTag(PKG, PKG,
|
||||
|
||||
@@ -630,4 +630,37 @@ public class NotificationPermissionMigrationTest extends UiServiceTestCase {
|
||||
verify(mPreferencesHelper, never()).getImportance(anyString(), anyInt());
|
||||
verify(mPreferencesHelper, never()).getNotificationChannelsBypassingDnd(PKG, mUid);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testBlockedNotifications_blockedByUser() throws Exception {
|
||||
when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
|
||||
when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
|
||||
|
||||
NotificationChannel channel = new NotificationChannel("id", "name",
|
||||
NotificationManager.IMPORTANCE_HIGH);
|
||||
NotificationRecord r = generateNotificationRecord(channel);
|
||||
mService.addEnqueuedNotification(r);
|
||||
|
||||
when(mPermissionHelper.hasPermission(anyInt())).thenReturn(false);
|
||||
|
||||
NotificationManagerService.PostNotificationRunnable runnable =
|
||||
mService.new PostNotificationRunnable(r.getKey());
|
||||
runnable.run();
|
||||
waitForIdle();
|
||||
|
||||
verify(mUsageStats).registerBlocked(any());
|
||||
verify(mUsageStats, never()).registerPostedByApp(any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testEnqueueNotification_appBlocked() throws Exception {
|
||||
when(mPermissionHelper.hasPermission(mUid)).thenReturn(false);
|
||||
|
||||
mBinderService.enqueueNotificationWithTag(PKG, PKG,
|
||||
"testEnqueueNotification_appBlocked", 0,
|
||||
generateNotificationRecord(null).getNotification(), 0);
|
||||
waitForIdle();
|
||||
verify(mWorkerHandler, never()).post(
|
||||
any(NotificationManagerService.EnqueueNotificationRunnable.class));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user