Merge "Remove FLAG_FOREGROUND_SERVICE on Service.stopForeground()" into lmp-dev
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index d38074f..3f83a02 100755
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -24,6 +24,7 @@
import java.util.Iterator;
import java.util.List;
+import android.os.Build;
import android.os.DeadObjectException;
import android.os.Handler;
import android.os.Looper;
@@ -590,6 +591,8 @@
r.cancelNotification();
r.foregroundId = 0;
r.foregroundNoti = null;
+ } else if (r.appInfo.targetSdkVersion >= Build.VERSION_CODES.L) {
+ r.stripForegroundServiceFlagFromNotification();
}
}
}
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 0a66a5c..d4a378b 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -517,6 +517,31 @@
});
}
}
+
+ public void stripForegroundServiceFlagFromNotification() {
+ if (foregroundId == 0) {
+ return;
+ }
+
+ final int localForegroundId = foregroundId;
+ final int localUserId = userId;
+ final String localPackageName = packageName;
+
+ // Do asynchronous communication with notification manager to
+ // avoid deadlocks.
+ ams.mHandler.post(new Runnable() {
+ @Override
+ public void run() {
+ NotificationManagerInternal nmi = LocalServices.getService(
+ NotificationManagerInternal.class);
+ if (nmi == null) {
+ return;
+ }
+ nmi.removeForegroundServiceFlagFromNotification(localPackageName, localForegroundId,
+ localUserId);
+ }
+ });
+ }
public void clearDeliveredStartsLocked() {
for (int i=deliveredStarts.size()-1; i>=0; i--) {
diff --git a/services/core/java/com/android/server/notification/NotificationManagerInternal.java b/services/core/java/com/android/server/notification/NotificationManagerInternal.java
index b695b68..c6b0d36 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerInternal.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerInternal.java
@@ -21,4 +21,6 @@
public interface NotificationManagerInternal {
void enqueueNotification(String pkg, String basePkg, int callingUid, int callingPid,
String tag, int id, Notification notification, int[] idReceived, int userId);
+
+ void removeForegroundServiceFlagFromNotification(String pkg, int notificationId, 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 14587e6..2829e2b 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -1610,6 +1610,30 @@
enqueueNotificationInternal(pkg, opPkg, callingUid, callingPid, tag, id, notification,
idReceived, userId);
}
+
+ @Override
+ public void removeForegroundServiceFlagFromNotification(String pkg, int notificationId,
+ int userId) {
+ checkCallerIsSystem();
+ synchronized (mNotificationList) {
+ int i = indexOfNotificationLocked(pkg, null, notificationId, userId);
+ if (i < 0) {
+ Log.d(TAG, "stripForegroundServiceFlag: Could not find notification with "
+ + "pkg=" + pkg + " / id=" + notificationId + " / userId=" + userId);
+ return;
+ }
+ NotificationRecord r = mNotificationList.get(i);
+ StatusBarNotification sbn = r.sbn;
+ // NoMan adds flags FLAG_NO_CLEAR and FLAG_ONGOING_EVENT when it sees
+ // FLAG_FOREGROUND_SERVICE. Hence it's not enough to remove FLAG_FOREGROUND_SERVICE,
+ // we have to revert to the flags we received initially *and* force remove
+ // FLAG_FOREGROUND_SERVICE.
+ sbn.getNotification().flags =
+ (r.mOriginalFlags & ~Notification.FLAG_FOREGROUND_SERVICE);
+ mRankingHelper.sort(mNotificationList);
+ mListeners.notifyPostedLocked(sbn, sbn /* oldSbn */);
+ }
+ }
};
void enqueueNotificationInternal(final String pkg, final String opPkg, final int callingUid,
diff --git a/services/core/java/com/android/server/notification/NotificationRecord.java b/services/core/java/com/android/server/notification/NotificationRecord.java
index fd34aa5..ea6f2db 100644
--- a/services/core/java/com/android/server/notification/NotificationRecord.java
+++ b/services/core/java/com/android/server/notification/NotificationRecord.java
@@ -45,6 +45,8 @@
*/
public final class NotificationRecord {
final StatusBarNotification sbn;
+ final int mOriginalFlags;
+
NotificationUsageStats.SingleNotificationStats stats;
boolean isCanceled;
int score;
@@ -73,6 +75,7 @@
{
this.sbn = sbn;
this.score = score;
+ mOriginalFlags = sbn.getNotification().flags;
mRankingTimeMs = calculateRankingTimeMs(0L);
}