diff options
| author | 2018-05-02 11:05:11 -0700 | |
|---|---|---|
| committer | 2018-05-02 11:05:11 -0700 | |
| commit | 0c728e411a9f9a6549c6f9ec0bad14c858c5c767 (patch) | |
| tree | dd6dccfbaa1ad1527759fe5297af5df670e750f0 | |
| parent | 521ec6e67725574ebbd0a32ac12bd5c0422d46ef (diff) | |
| parent | 12f404e3e33c21a4f0d634698bef94c219ec48ab (diff) | |
Merge "Work on issue #77931346: The notification that should not be named appeared" into pi-dev
am: 12f404e3e3
Change-Id: I19f5b0cbafed7234e96edd0793413b37cd0a14a7
4 files changed, 73 insertions, 12 deletions
diff --git a/core/java/android/app/NotificationChannel.java b/core/java/android/app/NotificationChannel.java index 9e47ced433e3..ba355f9f9c1d 100644 --- a/core/java/android/app/NotificationChannel.java +++ b/core/java/android/app/NotificationChannel.java @@ -76,6 +76,7 @@ public final class NotificationChannel implements Parcelable { private static final String ATT_CONTENT_TYPE = "content_type"; private static final String ATT_SHOW_BADGE = "show_badge"; private static final String ATT_USER_LOCKED = "locked"; + private static final String ATT_FG_SERVICE_SHOWN = "fgservice"; private static final String ATT_GROUP = "group"; private static final String ATT_BLOCKABLE_SYSTEM = "blockable_system"; private static final String DELIMITER = ","; @@ -144,6 +145,7 @@ public final class NotificationChannel implements Parcelable { // Bitwise representation of fields that have been changed by the user, preventing the app from // making changes to these fields. private int mUserLockedFields; + private boolean mFgServiceShown; private boolean mVibrationEnabled; private boolean mShowBadge = DEFAULT_SHOW_BADGE; private boolean mDeleted = DEFAULT_DELETED; @@ -200,6 +202,7 @@ public final class NotificationChannel implements Parcelable { mLights = in.readByte() != 0; mVibration = in.createLongArray(); mUserLockedFields = in.readInt(); + mFgServiceShown = in.readByte() != 0; mVibrationEnabled = in.readByte() != 0; mShowBadge = in.readByte() != 0; mDeleted = in.readByte() != 0; @@ -245,6 +248,7 @@ public final class NotificationChannel implements Parcelable { dest.writeByte(mLights ? (byte) 1 : (byte) 0); dest.writeLongArray(mVibration); dest.writeInt(mUserLockedFields); + dest.writeByte(mFgServiceShown ? (byte) 1 : (byte) 0); dest.writeByte(mVibrationEnabled ? (byte) 1 : (byte) 0); dest.writeByte(mShowBadge ? (byte) 1 : (byte) 0); dest.writeByte(mDeleted ? (byte) 1 : (byte) 0); @@ -281,6 +285,13 @@ public final class NotificationChannel implements Parcelable { /** * @hide */ + public void setFgServiceShown(boolean shown) { + mFgServiceShown = shown; + } + + /** + * @hide + */ public void setDeleted(boolean deleted) { mDeleted = deleted; } @@ -576,6 +587,13 @@ public final class NotificationChannel implements Parcelable { /** * @hide */ + public boolean isFgServiceShown() { + return mFgServiceShown; + } + + /** + * @hide + */ public boolean isBlockableSystem() { return mBlockableSystem; } @@ -620,6 +638,7 @@ public final class NotificationChannel implements Parcelable { setDeleted(safeBool(parser, ATT_DELETED, false)); setGroup(parser.getAttributeValue(null, ATT_GROUP)); lockFields(safeInt(parser, ATT_USER_LOCKED, 0)); + setFgServiceShown(safeBool(parser, ATT_FG_SERVICE_SHOWN, false)); setBlockableSystem(safeBool(parser, ATT_BLOCKABLE_SYSTEM, false)); } @@ -724,6 +743,9 @@ public final class NotificationChannel implements Parcelable { if (getUserLockedFields() != 0) { out.attribute(null, ATT_USER_LOCKED, Integer.toString(getUserLockedFields())); } + if (isFgServiceShown()) { + out.attribute(null, ATT_FG_SERVICE_SHOWN, Boolean.toString(isFgServiceShown())); + } if (canShowBadge()) { out.attribute(null, ATT_SHOW_BADGE, Boolean.toString(canShowBadge())); } @@ -772,6 +794,7 @@ public final class NotificationChannel implements Parcelable { record.put(ATT_LIGHT_COLOR, Integer.toString(getLightColor())); record.put(ATT_VIBRATION_ENABLED, Boolean.toString(shouldVibrate())); record.put(ATT_USER_LOCKED, Integer.toString(getUserLockedFields())); + record.put(ATT_FG_SERVICE_SHOWN, Boolean.toString(isFgServiceShown())); record.put(ATT_VIBRATION, longArrayToString(getVibrationPattern())); record.put(ATT_SHOW_BADGE, Boolean.toString(canShowBadge())); record.put(ATT_DELETED, Boolean.toString(isDeleted())); @@ -933,6 +956,7 @@ public final class NotificationChannel implements Parcelable { + ", mLightColor=" + mLightColor + ", mVibration=" + Arrays.toString(mVibration) + ", mUserLockedFields=" + Integer.toHexString(mUserLockedFields) + + ", mFgServiceShown=" + mFgServiceShown + ", mVibrationEnabled=" + mVibrationEnabled + ", mShowBadge=" + mShowBadge + ", mDeleted=" + mDeleted @@ -963,6 +987,7 @@ public final class NotificationChannel implements Parcelable { } } proto.write(NotificationChannelProto.USER_LOCKED_FIELDS, mUserLockedFields); + proto.write(NotificationChannelProto.FG_SERVICE_SHOWN, mFgServiceShown); proto.write(NotificationChannelProto.IS_VIBRATION_ENABLED, mVibrationEnabled); proto.write(NotificationChannelProto.SHOW_BADGE, mShowBadge); proto.write(NotificationChannelProto.IS_DELETED, mDeleted); diff --git a/core/proto/android/app/notification_channel.proto b/core/proto/android/app/notification_channel.proto index 337aa1c20c7a..d3808e890025 100644 --- a/core/proto/android/app/notification_channel.proto +++ b/core/proto/android/app/notification_channel.proto @@ -53,4 +53,5 @@ message NotificationChannelProto { optional android.media.AudioAttributesProto audio_attributes = 16; // If this is a blockable system notification channel. optional bool is_blockable_system = 17; + optional bool fg_service_shown = 18; } diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index 9ee28d880a28..3614dd5a1260 100644 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -4052,17 +4052,29 @@ public class NotificationManagerService extends SystemService { final NotificationRecord r = new NotificationRecord(getContext(), n, channel); r.setIsAppImportanceLocked(mRankingHelper.getIsAppImportanceLocked(pkg, callingUid)); - if ((notification.flags & FLAG_FOREGROUND_SERVICE) != 0 - && (channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0 - && (r.getImportance() == IMPORTANCE_MIN || r.getImportance() == IMPORTANCE_NONE)) { - // Increase the importance of foreground service notifications unless the user had an - // opinion otherwise - if (TextUtils.isEmpty(channelId) - || NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) { - r.setImportance(IMPORTANCE_LOW, "Bumped for foreground service"); - } else { - channel.setImportance(IMPORTANCE_LOW); - mRankingHelper.updateNotificationChannel(pkg, notificationUid, channel, false); + if ((notification.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) { + final boolean fgServiceShown = channel.isFgServiceShown(); + if (((channel.getUserLockedFields() & NotificationChannel.USER_LOCKED_IMPORTANCE) == 0 + || !fgServiceShown) + && (r.getImportance() == IMPORTANCE_MIN + || r.getImportance() == IMPORTANCE_NONE)) { + // Increase the importance of foreground service notifications unless the user had + // an opinion otherwise (and the channel hasn't yet shown a fg service). + if (TextUtils.isEmpty(channelId) + || NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) { + r.setImportance(IMPORTANCE_LOW, "Bumped for foreground service"); + } else { + channel.setImportance(IMPORTANCE_LOW); + if (!fgServiceShown) { + channel.unlockFields(NotificationChannel.USER_LOCKED_IMPORTANCE); + channel.setFgServiceShown(true); + } + mRankingHelper.updateNotificationChannel(pkg, notificationUid, channel, false); + r.updateNotificationChannel(channel); + } + } else if (!fgServiceShown && !TextUtils.isEmpty(channelId) + && !NotificationChannel.DEFAULT_CHANNEL_ID.equals(channelId)) { + channel.setFgServiceShown(true); r.updateNotificationChannel(channel); } } 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 58f589850cb6..376cc645fabc 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java @@ -557,11 +557,34 @@ public class NotificationManagerServiceTest extends UiServiceTestCase { assertEquals(IMPORTANCE_NONE, mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance()); - final StatusBarNotification sbn = generateNotificationRecord(channel).sbn; + StatusBarNotification sbn = generateNotificationRecord(channel).sbn; + sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE; + mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", + sbn.getId(), sbn.getNotification(), sbn.getUserId()); + waitForIdle(); + // The first time a foreground service notification is shown, we allow the channel + // to be updated to allow it to be seen. + assertEquals(1, mBinderService.getActiveNotifications(sbn.getPackageName()).length); + assertEquals(IMPORTANCE_LOW, + mService.getNotificationRecord(sbn.getKey()).getImportance()); + assertEquals(IMPORTANCE_LOW, + mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance()); + mBinderService.cancelNotificationWithTag(PKG, "tag", sbn.getId(), sbn.getUserId()); + waitForIdle(); + + update = new NotificationChannel("blockedbyuser", "name", IMPORTANCE_NONE); + update.setFgServiceShown(true); + mBinderService.updateNotificationChannelForPackage(PKG, mUid, update); + waitForIdle(); + assertEquals(IMPORTANCE_NONE, + mBinderService.getNotificationChannel(PKG, channel.getId()).getImportance()); + + sbn = generateNotificationRecord(channel).sbn; sbn.getNotification().flags |= FLAG_FOREGROUND_SERVICE; mBinderService.enqueueNotificationWithTag(PKG, "opPkg", "tag", sbn.getId(), sbn.getNotification(), sbn.getUserId()); waitForIdle(); + // The second time it is shown, we keep the user's preference. assertEquals(0, mBinderService.getActiveNotifications(sbn.getPackageName()).length); assertNull(mService.getNotificationRecord(sbn.getKey())); assertEquals(IMPORTANCE_NONE, |