summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xservices/core/java/com/android/server/notification/NotificationManagerService.java20
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java115
2 files changed, 132 insertions, 3 deletions
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 83c576e9259d..dbe04b0945e0 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -58,6 +58,7 @@ import static android.content.Context.BIND_AUTO_CREATE;
import static android.content.Context.BIND_FOREGROUND_SERVICE;
import static android.content.Context.BIND_NOT_PERCEPTIBLE;
import static android.content.pm.PackageManager.FEATURE_LEANBACK;
+import static android.content.pm.PackageManager.FEATURE_TELECOM;
import static android.content.pm.PackageManager.FEATURE_TELEVISION;
import static android.content.pm.PackageManager.MATCH_ALL;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
@@ -2161,6 +2162,11 @@ public class NotificationManagerService extends SystemService {
mAccessibilityManager = am;
}
+ @VisibleForTesting
+ void setTelecomManager(TelecomManager tm) {
+ mTelecomManager = tm;
+ }
+
// TODO: All tests should use this init instead of the one-off setters above.
@VisibleForTesting
void init(WorkerHandler handler, RankingHandler rankingHandler,
@@ -6978,8 +6984,13 @@ public class NotificationManagerService extends SystemService {
private boolean isCallNotification(String pkg, int uid) {
final long identity = Binder.clearCallingIdentity();
try {
- return mTelecomManager.isInManagedCall() || mTelecomManager.isInSelfManagedCall(
- pkg, UserHandle.getUserHandleForUid(uid));
+ if (mPackageManagerClient.hasSystemFeature(FEATURE_TELECOM)
+ && mTelecomManager != null) {
+ return mTelecomManager.isInManagedCall()
+ || mTelecomManager.isInSelfManagedCall(
+ pkg, UserHandle.getUserHandleForUid(uid));
+ }
+ return false;
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -7405,6 +7416,7 @@ public class NotificationManagerService extends SystemService {
@Override
public void run() {
boolean appBanned = !areNotificationsEnabledForPackageInt(pkg, uid);
+ boolean isCallNotification = isCallNotification(pkg, uid);
synchronized (mNotificationLock) {
try {
NotificationRecord r = null;
@@ -7423,8 +7435,10 @@ public class NotificationManagerService extends SystemService {
final StatusBarNotification n = r.getSbn();
final Notification notification = n.getNotification();
+ boolean isCallNotificationAndCorrectStyle = isCallNotification
+ && notification.isStyle(Notification.CallStyle.class);
- if (!notification.isMediaNotification()
+ if (!(notification.isMediaNotification() || isCallNotificationAndCorrectStyle)
&& (appBanned || isRecordBlockedLocked(r))) {
mUsageStats.registerBlocked(r);
if (DBG) {
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 c0cd7a755e25..850c9e3e6903 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -52,6 +52,7 @@ import static android.app.PendingIntent.FLAG_IMMUTABLE;
import static android.app.PendingIntent.FLAG_MUTABLE;
import static android.app.PendingIntent.FLAG_ONE_SHOT;
import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
+import static android.content.pm.PackageManager.FEATURE_TELECOM;
import static android.content.pm.PackageManager.FEATURE_WATCH;
import static android.content.pm.PackageManager.PERMISSION_DENIED;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
@@ -448,6 +449,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
mContext.addMockSystemService(AppOpsManager.class, mock(AppOpsManager.class));
when(mUm.getProfileIds(0, false)).thenReturn(new int[]{0});
+ when(mPackageManagerClient.hasSystemFeature(FEATURE_TELECOM)).thenReturn(true);
+
ActivityManager.AppTask task = mock(ActivityManager.AppTask.class);
List<ActivityManager.AppTask> taskList = new ArrayList<>();
ActivityManager.RecentTaskInfo taskInfo = new ActivityManager.RecentTaskInfo();
@@ -9194,6 +9197,118 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
r.getSbn().getPackageName(), r.getUser())).thenReturn(true);
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+
+ // set telecom manager to null - blocked
+ mService.setTelecomManager(null);
+ assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
+ r.getSbn().getId(), r.getSbn().getTag(), r, false))
+ .isFalse();
+
+ // set telecom feature to false - blocked
+ when(mPackageManagerClient.hasSystemFeature(FEATURE_TELECOM)).thenReturn(false);
+ assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
+ r.getSbn().getId(), r.getSbn().getTag(), r, false))
+ .isFalse();
+ }
+
+ @Test
+ public void testCallNotificationsBypassBlock_atPost() throws Exception {
+ when(mPackageManager.isPackageSuspendedForUser(anyString(), anyInt())).thenReturn(false);
+ when(mAssistants.isSameUser(any(), anyInt())).thenReturn(true);
+
+ Notification.Builder nb =
+ new Notification.Builder(mContext, mTestNotificationChannel.getId())
+ .setContentTitle("foo")
+ .setSmallIcon(android.R.drawable.sym_def_app_icon)
+ .addAction(new Notification.Action.Builder(null, "test", null).build());
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+ nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
+ NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+ mBinderService.setNotificationsEnabledForPackage(
+ r.getSbn().getPackageName(), r.getUid(), false);
+
+ // normal blocked notifications - blocked
+ mService.addEnqueuedNotification(r);
+ NotificationManagerService.PostNotificationRunnable runnable =
+ mService.new PostNotificationRunnable(r.getKey(), r.getSbn().getPackageName(),
+ r.getUid(), SystemClock.elapsedRealtime());
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats).registerBlocked(any());
+ verify(mUsageStats, never()).registerPostedByApp(any());
+
+ // just using the style - blocked
+ mService.clearNotifications();
+ reset(mUsageStats);
+ Person person = new Person.Builder().setName("caller").build();
+ nb.setStyle(Notification.CallStyle.forOngoingCall(person, mock(PendingIntent.class)));
+ nb.setFullScreenIntent(mock(PendingIntent.class), true);
+ sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0, nb.build(),
+ UserHandle.getUserHandleForUid(mUid), null, 0);
+ r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+ mService.addEnqueuedNotification(r);
+ runnable = mService.new PostNotificationRunnable(
+ r.getKey(), r.getSbn().getPackageName(), r.getUid(), SystemClock.elapsedRealtime());
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats).registerBlocked(any());
+ verify(mUsageStats, never()).registerPostedByApp(any());
+
+ // style + managed call - bypasses block
+ mService.clearNotifications();
+ reset(mUsageStats);
+ when(mTelecomManager.isInManagedCall()).thenReturn(true);
+
+ mService.addEnqueuedNotification(r);
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats, never()).registerBlocked(any());
+ verify(mUsageStats).registerPostedByApp(any());
+
+ // style + self managed call - bypasses block
+ mService.clearNotifications();
+ reset(mUsageStats);
+ when(mTelecomManager.isInSelfManagedCall(r.getSbn().getPackageName(), r.getUser()))
+ .thenReturn(true);
+
+ mService.addEnqueuedNotification(r);
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats, never()).registerBlocked(any());
+ verify(mUsageStats).registerPostedByApp(any());
+
+ // set telecom manager to null - notifications should be blocked
+ // but post notifications runnable should not crash
+ mService.clearNotifications();
+ reset(mUsageStats);
+ mService.setTelecomManager(null);
+
+ mService.addEnqueuedNotification(r);
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats).registerBlocked(any());
+ verify(mUsageStats, never()).registerPostedByApp(any());
+
+ // set FEATURE_TELECOM to false - notifications should be blocked
+ // but post notifications runnable should not crash
+ mService.setTelecomManager(mTelecomManager);
+ when(mPackageManagerClient.hasSystemFeature(FEATURE_TELECOM)).thenReturn(false);
+ reset(mUsageStats);
+ mService.setTelecomManager(null);
+
+ mService.addEnqueuedNotification(r);
+ runnable.run();
+ waitForIdle();
+
+ verify(mUsageStats).registerBlocked(any());
+ verify(mUsageStats, never()).registerPostedByApp(any());
}
@Test