summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHui Yu <huiyu@google.com>2023-07-19 16:50:07 +0000
committerAndroid Build Coastguard Worker <android-build-coastguard-worker@google.com>2023-08-22 02:14:08 +0000
commit0b7bdf9b18dc799a67b3c9e9fdee384b39d44bb1 (patch)
tree240027528671188826a77a8ee07ebe1c3d683668
parent297db07fd76c7adf5691d7d07506d8138f139778 (diff)
downloadbase-0b7bdf9b18dc799a67b3c9e9fdee384b39d44bb1.tar.gz
Add a flag byForegroundService to enqueueNotification() call.
This flag is passed to NotificationManagerService, the CallStyle check will treat byForegroundService flag same as isFgs flag. Only the ServiceRecord.postNotification() call at startForeground() call has byForegroundService flag set to true. Add a test case NotificationManagerServiceTest.java#checkCallStyleNotification_allowedForByForegroundService Bug: 280003654 Test: atest NotificationManagerServiceTest.java#checkCallStyleNotification_allowedForByForegroundService (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:ea56bb0813c03d4b9d14795da979da8c86b8ccb1) Merged-In: Ibe30526ac0ff52e2e4fe9bc846576509cdf78236 Change-Id: Ibe30526ac0ff52e2e4fe9bc846576509cdf78236
-rw-r--r--services/core/java/com/android/server/am/ActiveServices.java8
-rw-r--r--services/core/java/com/android/server/am/ServiceRecord.java4
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerInternal.java3
-rw-r--r--services/core/java/com/android/server/notification/NotificationManagerService.java37
-rwxr-xr-xservices/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java56
5 files changed, 70 insertions, 38 deletions
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index d5f41a109042..a7107161777c 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -2414,7 +2414,7 @@ public final class ActiveServices {
// Even if the service is already a FGS, we need to update the notification,
// so we need to call it again.
signalForegroundServiceObserversLocked(r);
- r.postNotification();
+ r.postNotification(true);
if (r.app != null) {
updateServiceForegroundLocked(psr, true);
}
@@ -2472,7 +2472,7 @@ public final class ActiveServices {
} else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.LOLLIPOP) {
// if it's been deferred, force to visibility
if (!r.mFgsNotificationShown) {
- r.postNotification();
+ r.postNotification(false);
}
dropFgsNotificationStateLocked(r);
if ((flags & Service.STOP_FOREGROUND_DETACH) != 0) {
@@ -2916,7 +2916,7 @@ public final class ActiveServices {
// in the interval, so we lazy check whether we still need to show
// the notification.
if (r.isForeground && r.app != null) {
- r.postNotification();
+ r.postNotification(true);
r.mFgsNotificationShown = true;
} else {
if (DEBUG_FOREGROUND_SERVICE) {
@@ -5339,7 +5339,7 @@ public final class ActiveServices {
thread.scheduleCreateService(r, r.serviceInfo,
null /* compatInfo (unused but need to keep method signature) */,
app.mState.getReportedProcState());
- r.postNotification();
+ r.postNotification(false);
created = true;
} catch (DeadObjectException e) {
Slog.w(TAG, "Application dead when creating service " + r);
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 50fe6d71d26e..b9914faa469a 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -1212,7 +1212,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
});
}
- public void postNotification() {
+ public void postNotification(boolean byForegroundService) {
if (isForeground && foregroundNoti != null && app != null) {
final int appUid = appInfo.uid;
final int appPid = app.getPid();
@@ -1320,7 +1320,7 @@ final class ServiceRecord extends Binder implements ComponentName.WithComponentN
}
nm.enqueueNotification(localPackageName, localPackageName,
appUid, appPid, null, localForegroundId, localForegroundNoti,
- userId);
+ userId, byForegroundService /* byForegroundService */);
foregroundNoti = localForegroundNoti; // save it for amending next time
diff --git a/services/core/java/com/android/server/notification/NotificationManagerInternal.java b/services/core/java/com/android/server/notification/NotificationManagerInternal.java
index 919fc712c409..c240bcbce911 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerInternal.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerInternal.java
@@ -27,6 +27,9 @@ public interface NotificationManagerInternal {
NotificationChannelGroup getNotificationChannelGroup(String pkg, int uid, String channelId);
void enqueueNotification(String pkg, String basePkg, int callingUid, int callingPid,
String tag, int id, Notification notification, int userId);
+ void enqueueNotification(String pkg, String basePkg, int callingUid, int callingPid,
+ String tag, int id, Notification notification, int userId,
+ boolean byForegroundService);
void cancelNotification(String pkg, String basePkg, int callingUid, int callingPid,
String tag, int id, int userId);
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 7369e5ed5932..79559fdc34d6 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2528,7 +2528,8 @@ public class NotificationManagerService extends SystemService {
}
enqueueNotificationInternal(r.getSbn().getPackageName(), r.getSbn().getOpPkg(),
r.getSbn().getUid(), r.getSbn().getInitialPid(), r.getSbn().getTag(),
- r.getSbn().getId(), r.getSbn().getNotification(), userId, muteOnReturn);
+ r.getSbn().getId(), r.getSbn().getNotification(), userId, muteOnReturn,
+ false /* byForegroundService */);
} catch (Exception e) {
Slog.e(TAG, "Cannot un-snooze notification", e);
}
@@ -3518,7 +3519,8 @@ public class NotificationManagerService extends SystemService {
public void enqueueNotificationWithTag(String pkg, String opPkg, String tag, int id,
Notification notification, int userId) throws RemoteException {
enqueueNotificationInternal(pkg, opPkg, Binder.getCallingUid(),
- Binder.getCallingPid(), tag, id, notification, userId);
+ Binder.getCallingPid(), tag, id, notification, userId,
+ false /* byForegroundService */);
}
@Override
@@ -6074,7 +6076,7 @@ public class NotificationManagerService extends SystemService {
}
if (summaryRecord != null && checkDisqualifyingFeatures(userId, uid,
summaryRecord.getSbn().getId(), summaryRecord.getSbn().getTag(), summaryRecord,
- true)) {
+ true, false)) {
return summaryRecord;
}
}
@@ -6403,7 +6405,15 @@ public class NotificationManagerService extends SystemService {
public void enqueueNotification(String pkg, String opPkg, int callingUid, int callingPid,
String tag, int id, Notification notification, int userId) {
enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id, notification,
- userId);
+ userId, false /* byForegroundService */);
+ }
+
+ @Override
+ public void enqueueNotification(String pkg, String opPkg, int callingUid, int callingPid,
+ String tag, int id, Notification notification, int userId,
+ boolean byForegroundService) {
+ enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id, notification,
+ userId, byForegroundService);
}
@Override
@@ -6581,19 +6591,19 @@ public class NotificationManagerService extends SystemService {
void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
final int callingPid, final String tag, final int id, final Notification notification,
- int incomingUserId) {
+ int incomingUserId, boolean byForegroundService) {
enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id, notification,
- incomingUserId, false);
+ incomingUserId, false /* postSilently */, byForegroundService);
}
void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
final int callingPid, final String tag, final int id, final Notification notification,
- int incomingUserId, boolean postSilently) {
+ int incomingUserId, boolean postSilently, boolean byForegroundService) {
PostNotificationTracker tracker = acquireWakeLockForPost(pkg, callingUid);
boolean enqueued = false;
try {
enqueued = enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id,
- notification, incomingUserId, postSilently, tracker);
+ notification, incomingUserId, postSilently, tracker, byForegroundService);
} finally {
if (!enqueued) {
tracker.cancel();
@@ -6624,10 +6634,10 @@ public class NotificationManagerService extends SystemService {
* @return True if we successfully processed the notification and handed off the task of
* enqueueing it to a background thread; false otherwise.
*/
- private boolean enqueueNotificationInternal(final String pkg, final String opPkg,
+ private boolean enqueueNotificationInternal(final String pkg, final String opPkg, //HUI
final int callingUid, final int callingPid, final String tag, final int id,
final Notification notification, int incomingUserId, boolean postSilently,
- PostNotificationTracker tracker) {
+ PostNotificationTracker tracker, boolean byForegroundService) {
if (DBG) {
Slog.v(TAG, "enqueueNotificationInternal: pkg=" + pkg + " id=" + id
+ " notification=" + notification);
@@ -6773,7 +6783,7 @@ public class NotificationManagerService extends SystemService {
mPreferencesHelper.hasUserDemotedInvalidMsgApp(pkg, notificationUid));
if (!checkDisqualifyingFeatures(userId, notificationUid, id, tag, r,
- r.getSbn().getOverrideGroupKey() != null)) {
+ r.getSbn().getOverrideGroupKey() != null, byForegroundService)) {
return false;
}
@@ -7193,7 +7203,7 @@ public class NotificationManagerService extends SystemService {
* Has side effects.
*/
boolean checkDisqualifyingFeatures(int userId, int uid, int id, String tag,
- NotificationRecord r, boolean isAutogroup) {
+ NotificationRecord r, boolean isAutogroup, boolean byForegroundService) {
Notification n = r.getNotification();
final String pkg = r.getSbn().getPackageName();
final boolean isSystemNotification =
@@ -7283,7 +7293,8 @@ public class NotificationManagerService extends SystemService {
if (n.isStyle(Notification.CallStyle.class)) {
boolean hasFullScreenIntent = n.fullScreenIntent != null;
boolean requestedFullScreenIntent = (n.flags & FLAG_FSI_REQUESTED_BUT_DENIED) != 0;
- if (!n.isFgsOrUij() && !hasFullScreenIntent && !requestedFullScreenIntent) {
+ if (!n.isFgsOrUij() && !hasFullScreenIntent && !requestedFullScreenIntent
+ && !byForegroundService) {
throw new IllegalArgumentException(r.getKey() + " Not posted."
+ " CallStyle notifications must be for a foreground service or"
+ " user initated job or use a fullScreenIntent.");
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 4849665b0c44..72c9791a3ceb 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -10104,7 +10104,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
try {
mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(), r.getSbn().getId(),
- r.getSbn().getTag(), r,false);
+ r.getSbn().getTag(), r, false, false);
fail("Allowed a contextual direct reply with an immutable intent to be posted");
} catch (IllegalArgumentException e) {
// good
@@ -10135,7 +10135,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
r.applyAdjustments();
mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(), r.getSbn().getId(),
- r.getSbn().getTag(), r,false);
+ r.getSbn().getTag(), r, false, false);
}
@Test
@@ -10169,7 +10169,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
r.applyAdjustments();
mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(), r.getSbn().getId(),
- r.getSbn().getTag(), r,false);
+ r.getSbn().getTag(), r, false, false);
}
@Test
@@ -10382,7 +10382,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// normal blocked notifications - blocked
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false)).isFalse();
+ r.getSbn().getId(), r.getSbn().getTag(), r, false, false)).isFalse();
// just using the style - blocked
nb.setStyle(new Notification.MediaStyle());
@@ -10391,7 +10391,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false)).isFalse();
+ r.getSbn().getId(), r.getSbn().getTag(), r, false, false)).isFalse();
// using the style, but incorrect type in session - blocked
nb.setStyle(new Notification.MediaStyle());
@@ -10403,7 +10403,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false)).isFalse();
+ r.getSbn().getId(), r.getSbn().getTag(), r, false, false)).isFalse();
// style + media session - bypasses block
nb.setStyle(new Notification.MediaStyle().setMediaSession(mock(MediaSession.Token.class)));
@@ -10412,7 +10412,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+ r.getSbn().getId(), r.getSbn().getTag(), r, false, false)).isTrue();
}
@Test
@@ -10495,7 +10495,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
// normal blocked notifications - blocked
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false)).isFalse();
+ r.getSbn().getId(), r.getSbn().getTag(), r, false, false)).isFalse();
// just using the style - blocked
Person person = new Person.Builder()
@@ -10509,36 +10509,36 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false)).isFalse();
+ r.getSbn().getId(), r.getSbn().getTag(), r, false, false)).isFalse();
// style + managed call - bypasses block
when(mTelecomManager.isInManagedCall()).thenReturn(true);
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+ r.getSbn().getId(), r.getSbn().getTag(), r, false, false)).isTrue();
// style + self managed call - bypasses block
when(mTelecomManager.isInSelfManagedCall(
r.getSbn().getPackageName(), r.getUser())).thenReturn(true);
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+ r.getSbn().getId(), r.getSbn().getTag(), r, false, 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))
+ r.getSbn().getId(), r.getSbn().getTag(), r, false, 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))
+ r.getSbn().getId(), r.getSbn().getTag(), r, false, false))
.isFalse();
// telecom manager is not ready - blocked
mService.setTelecomManager(mTelecomManager);
when(mTelecomManager.isInCall()).thenThrow(new IllegalStateException("not ready"));
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false))
+ r.getSbn().getId(), r.getSbn().getTag(), r, false, false))
.isFalse();
}
@@ -11058,7 +11058,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
try {
mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false);
+ r.getSbn().getId(), r.getSbn().getTag(), r, false, false);
assertFalse("CallStyle should not be allowed without a valid use case", true);
} catch (IllegalArgumentException error) {
assertThat(error.getMessage()).contains("CallStyle");
@@ -11078,7 +11078,25 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+ r.getSbn().getId(), r.getSbn().getTag(), r, false, false)).isTrue();
+ }
+
+ @Test
+ public void checkCallStyleNotification_allowedForByForegroundService() throws Exception {
+ Person person = new Person.Builder().setName("caller").build();
+ Notification n = new Notification.Builder(mContext, "test")
+ // Without FLAG_FOREGROUND_SERVICE.
+ //.setFlag(FLAG_FOREGROUND_SERVICE, true)
+ .setStyle(Notification.CallStyle.forOngoingCall(
+ person, mock(PendingIntent.class)))
+ .build();
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 8, "tag", mUid, 0,
+ n, UserHandle.getUserHandleForUid(mUid), null, 0);
+ NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+ assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
+ r.getSbn().getId(), r.getSbn().getTag(), r, false,
+ true /* byForegroundService */)).isTrue();
}
@Test
@@ -11094,7 +11112,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+ r.getSbn().getId(), r.getSbn().getTag(), r, false, false)).isTrue();
}
@Test
@@ -11110,7 +11128,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+ r.getSbn().getId(), r.getSbn().getTag(), r, false, false)).isTrue();
}
@Test
@@ -11126,7 +11144,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
NotificationRecord r = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
assertThat(mService.checkDisqualifyingFeatures(r.getUserId(), r.getUid(),
- r.getSbn().getId(), r.getSbn().getTag(), r, false)).isTrue();
+ r.getSbn().getId(), r.getSbn().getTag(), r, false, false)).isTrue();
}
@Test