Loading core/java/android/app/NotificationChannel.java +34 −0 Original line number Diff line number Diff line Loading @@ -431,6 +431,40 @@ public final class NotificationChannel implements Parcelable { dest.writeBoolean(mImportanceLockedDefaultApp); } /** * @hide */ public NotificationChannel copy() { NotificationChannel copy = new NotificationChannel(mId, mName, mImportance); copy.setDescription(mDesc); copy.setBypassDnd(mBypassDnd); copy.setLockscreenVisibility(mLockscreenVisibility); copy.setSound(mSound, mAudioAttributes); copy.setLightColor(mLightColor); copy.enableLights(mLights); copy.setVibrationPattern(mVibrationPattern); if (Flags.notificationChannelVibrationEffectApi()) { copy.setVibrationEffect(mVibrationEffect); } copy.lockFields(mUserLockedFields); copy.setUserVisibleTaskShown(mUserVisibleTaskShown); copy.enableVibration(mVibrationEnabled); copy.setShowBadge(mShowBadge); copy.setDeleted(mDeleted); copy.setGroup(mGroup); copy.setBlockable(mBlockableSystem); copy.setAllowBubbles(mAllowBubbles); copy.setOriginalImportance(mOriginalImportance); copy.setConversationId(mParentId, mConversationId); copy.setDemoted(mDemoted); copy.setImportantConversation(mImportantConvo); copy.setDeletedTimeMs(mDeletedTime); copy.setImportanceLockedByCriticalDeviceFunction(mImportanceLockedDefaultApp); copy.setLastNotificationUpdateTimeMs(mLastNotificationUpdateTimeMs); return copy; } /** * @hide */ Loading core/java/android/app/notification.aconfig +21 −0 Original line number Diff line number Diff line Loading @@ -90,3 +90,24 @@ flag { description: "Changes notification sort order to be by time within a section" bug: "330193582" } flag { name: "restrict_audio_attributes_call" namespace: "systemui" description: "Only CallStyle notifs can use USAGE_NOTIFICATION_RINGTONE" bug: "331793339" } flag { name: "restrict_audio_attributes_alarm" namespace: "systemui" description: "Only alarm category notifs can use USAGE_ALARM" bug: "331793339" } flag { name: "restrict_audio_attributes_media" namespace: "systemui" description: "No notifs can use USAGE_UNKNOWN or USAGE_MEDIA" bug: "331793339" } No newline at end of file core/tests/coretests/src/android/app/NotificationChannelTest.java +36 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.annotation.FlaggedApi; import android.content.AttributionSource; import android.content.ContentProvider; import android.content.ContentResolver; Loading @@ -46,6 +47,7 @@ import android.os.Parcel; import android.os.RemoteCallback; import android.os.RemoteException; import android.os.VibrationEffect; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.MediaStore.Audio.AudioColumns; Loading Loading @@ -577,6 +579,40 @@ public class NotificationChannelTest { assertNull(channel.getVibrationEffect()); } @Test @EnableFlags({Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_MEDIA, Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_CALL, Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_ALARM}) public void testCopy() { NotificationChannel original = new NotificationChannel("id", "name", 2); original.setDescription("desc"); original.setBypassDnd(true); original.setLockscreenVisibility(7); original.setSound(Uri.EMPTY, new AudioAttributes.Builder().build()); original.setLightColor(5); original.enableLights(false); original.setVibrationPattern(new long[] {1, 9, 3}); if (Flags.notificationChannelVibrationEffectApi()) { original.setVibrationEffect(VibrationEffect.createOneShot(100, 5)); } original.lockFields(9999); original.setUserVisibleTaskShown(true); original.enableVibration(false); original.setShowBadge(true); original.setDeleted(false); original.setGroup("group"); original.setBlockable(false); original.setAllowBubbles(true); original.setOriginalImportance(6); original.setConversationId("parent", "convo"); original.setDemoted(false); original.setImportantConversation(true); original.setDeletedTimeMs(100); original.setImportanceLockedByCriticalDeviceFunction(false); NotificationChannel parcelCopy = writeToAndReadFromParcel(original); assertThat(original.copy()).isEqualTo(parcelCopy); } /** Backs up a given channel to an XML, and returns the channel read from the XML. */ private NotificationChannel backUpAndRestore(NotificationChannel channel) throws Exception { TypedXmlSerializer serializer = Xml.newFastSerializer(); Loading services/core/java/com/android/server/notification/NotificationChannelExtractor.java +38 −0 Original line number Diff line number Diff line Loading @@ -15,8 +15,16 @@ */ package com.android.server.notification; import static android.app.Flags.restrictAudioAttributesAlarm; import static android.app.Flags.restrictAudioAttributesCall; import static android.app.Flags.restrictAudioAttributesMedia; import static android.app.Notification.CATEGORY_ALARM; import static android.media.AudioAttributes.USAGE_NOTIFICATION; import android.app.Notification; import android.app.NotificationChannel; import android.content.Context; import android.media.AudioAttributes; import android.util.Slog; /** Loading Loading @@ -50,6 +58,36 @@ public class NotificationChannelExtractor implements NotificationSignalExtractor record.getSbn().getShortcutId(), true, false); record.updateNotificationChannel(updatedChannel); if (restrictAudioAttributesCall() || restrictAudioAttributesAlarm() || restrictAudioAttributesMedia()) { AudioAttributes attributes = record.getChannel().getAudioAttributes(); boolean updateAttributes = false; if (restrictAudioAttributesCall() && !record.getNotification().isStyle(Notification.CallStyle.class) && attributes.getUsage() == AudioAttributes.USAGE_NOTIFICATION_RINGTONE) { updateAttributes = true; } if (restrictAudioAttributesAlarm() && record.getNotification().category != CATEGORY_ALARM && attributes.getUsage() == AudioAttributes.USAGE_ALARM) { updateAttributes = true; } if (restrictAudioAttributesMedia() && (attributes.getUsage() == AudioAttributes.USAGE_UNKNOWN || attributes.getUsage() == AudioAttributes.USAGE_MEDIA)) { updateAttributes = true; } if (updateAttributes) { NotificationChannel clone = record.getChannel().copy(); clone.setSound(clone.getSound(), new AudioAttributes.Builder(attributes) .setUsage(USAGE_NOTIFICATION) .build()); record.updateNotificationChannel(clone); } } return null; } Loading services/core/java/com/android/server/notification/NotificationRecord.java +8 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ package com.android.server.notification; import static android.app.Flags.restrictAudioAttributesAlarm; import static android.app.Flags.restrictAudioAttributesCall; import static android.app.Flags.restrictAudioAttributesMedia; import static android.app.Flags.updateRankingTime; import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; Loading Loading @@ -1159,6 +1162,11 @@ public final class NotificationRecord { mChannel = channel; calculateImportance(); calculateUserSentiment(); mVibration = calculateVibration(); if (restrictAudioAttributesCall() || restrictAudioAttributesAlarm() || restrictAudioAttributesMedia()) { mAttributes = channel.getAudioAttributes(); } } } Loading Loading
core/java/android/app/NotificationChannel.java +34 −0 Original line number Diff line number Diff line Loading @@ -431,6 +431,40 @@ public final class NotificationChannel implements Parcelable { dest.writeBoolean(mImportanceLockedDefaultApp); } /** * @hide */ public NotificationChannel copy() { NotificationChannel copy = new NotificationChannel(mId, mName, mImportance); copy.setDescription(mDesc); copy.setBypassDnd(mBypassDnd); copy.setLockscreenVisibility(mLockscreenVisibility); copy.setSound(mSound, mAudioAttributes); copy.setLightColor(mLightColor); copy.enableLights(mLights); copy.setVibrationPattern(mVibrationPattern); if (Flags.notificationChannelVibrationEffectApi()) { copy.setVibrationEffect(mVibrationEffect); } copy.lockFields(mUserLockedFields); copy.setUserVisibleTaskShown(mUserVisibleTaskShown); copy.enableVibration(mVibrationEnabled); copy.setShowBadge(mShowBadge); copy.setDeleted(mDeleted); copy.setGroup(mGroup); copy.setBlockable(mBlockableSystem); copy.setAllowBubbles(mAllowBubbles); copy.setOriginalImportance(mOriginalImportance); copy.setConversationId(mParentId, mConversationId); copy.setDemoted(mDemoted); copy.setImportantConversation(mImportantConvo); copy.setDeletedTimeMs(mDeletedTime); copy.setImportanceLockedByCriticalDeviceFunction(mImportanceLockedDefaultApp); copy.setLastNotificationUpdateTimeMs(mLastNotificationUpdateTimeMs); return copy; } /** * @hide */ Loading
core/java/android/app/notification.aconfig +21 −0 Original line number Diff line number Diff line Loading @@ -90,3 +90,24 @@ flag { description: "Changes notification sort order to be by time within a section" bug: "330193582" } flag { name: "restrict_audio_attributes_call" namespace: "systemui" description: "Only CallStyle notifs can use USAGE_NOTIFICATION_RINGTONE" bug: "331793339" } flag { name: "restrict_audio_attributes_alarm" namespace: "systemui" description: "Only alarm category notifs can use USAGE_ALARM" bug: "331793339" } flag { name: "restrict_audio_attributes_media" namespace: "systemui" description: "No notifs can use USAGE_UNKNOWN or USAGE_MEDIA" bug: "331793339" } No newline at end of file
core/tests/coretests/src/android/app/NotificationChannelTest.java +36 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ import static org.mockito.Mockito.doAnswer; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import android.annotation.FlaggedApi; import android.content.AttributionSource; import android.content.ContentProvider; import android.content.ContentResolver; Loading @@ -46,6 +47,7 @@ import android.os.Parcel; import android.os.RemoteCallback; import android.os.RemoteException; import android.os.VibrationEffect; import android.platform.test.annotations.EnableFlags; import android.platform.test.annotations.Presubmit; import android.platform.test.flag.junit.SetFlagsRule; import android.provider.MediaStore.Audio.AudioColumns; Loading Loading @@ -577,6 +579,40 @@ public class NotificationChannelTest { assertNull(channel.getVibrationEffect()); } @Test @EnableFlags({Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_MEDIA, Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_CALL, Flags.FLAG_RESTRICT_AUDIO_ATTRIBUTES_ALARM}) public void testCopy() { NotificationChannel original = new NotificationChannel("id", "name", 2); original.setDescription("desc"); original.setBypassDnd(true); original.setLockscreenVisibility(7); original.setSound(Uri.EMPTY, new AudioAttributes.Builder().build()); original.setLightColor(5); original.enableLights(false); original.setVibrationPattern(new long[] {1, 9, 3}); if (Flags.notificationChannelVibrationEffectApi()) { original.setVibrationEffect(VibrationEffect.createOneShot(100, 5)); } original.lockFields(9999); original.setUserVisibleTaskShown(true); original.enableVibration(false); original.setShowBadge(true); original.setDeleted(false); original.setGroup("group"); original.setBlockable(false); original.setAllowBubbles(true); original.setOriginalImportance(6); original.setConversationId("parent", "convo"); original.setDemoted(false); original.setImportantConversation(true); original.setDeletedTimeMs(100); original.setImportanceLockedByCriticalDeviceFunction(false); NotificationChannel parcelCopy = writeToAndReadFromParcel(original); assertThat(original.copy()).isEqualTo(parcelCopy); } /** Backs up a given channel to an XML, and returns the channel read from the XML. */ private NotificationChannel backUpAndRestore(NotificationChannel channel) throws Exception { TypedXmlSerializer serializer = Xml.newFastSerializer(); Loading
services/core/java/com/android/server/notification/NotificationChannelExtractor.java +38 −0 Original line number Diff line number Diff line Loading @@ -15,8 +15,16 @@ */ package com.android.server.notification; import static android.app.Flags.restrictAudioAttributesAlarm; import static android.app.Flags.restrictAudioAttributesCall; import static android.app.Flags.restrictAudioAttributesMedia; import static android.app.Notification.CATEGORY_ALARM; import static android.media.AudioAttributes.USAGE_NOTIFICATION; import android.app.Notification; import android.app.NotificationChannel; import android.content.Context; import android.media.AudioAttributes; import android.util.Slog; /** Loading Loading @@ -50,6 +58,36 @@ public class NotificationChannelExtractor implements NotificationSignalExtractor record.getSbn().getShortcutId(), true, false); record.updateNotificationChannel(updatedChannel); if (restrictAudioAttributesCall() || restrictAudioAttributesAlarm() || restrictAudioAttributesMedia()) { AudioAttributes attributes = record.getChannel().getAudioAttributes(); boolean updateAttributes = false; if (restrictAudioAttributesCall() && !record.getNotification().isStyle(Notification.CallStyle.class) && attributes.getUsage() == AudioAttributes.USAGE_NOTIFICATION_RINGTONE) { updateAttributes = true; } if (restrictAudioAttributesAlarm() && record.getNotification().category != CATEGORY_ALARM && attributes.getUsage() == AudioAttributes.USAGE_ALARM) { updateAttributes = true; } if (restrictAudioAttributesMedia() && (attributes.getUsage() == AudioAttributes.USAGE_UNKNOWN || attributes.getUsage() == AudioAttributes.USAGE_MEDIA)) { updateAttributes = true; } if (updateAttributes) { NotificationChannel clone = record.getChannel().copy(); clone.setSound(clone.getSound(), new AudioAttributes.Builder(attributes) .setUsage(USAGE_NOTIFICATION) .build()); record.updateNotificationChannel(clone); } } return null; } Loading
services/core/java/com/android/server/notification/NotificationRecord.java +8 −0 Original line number Diff line number Diff line Loading @@ -15,6 +15,9 @@ */ package com.android.server.notification; import static android.app.Flags.restrictAudioAttributesAlarm; import static android.app.Flags.restrictAudioAttributesCall; import static android.app.Flags.restrictAudioAttributesMedia; import static android.app.Flags.updateRankingTime; import static android.app.NotificationChannel.USER_LOCKED_IMPORTANCE; import static android.app.NotificationManager.IMPORTANCE_DEFAULT; Loading Loading @@ -1159,6 +1162,11 @@ public final class NotificationRecord { mChannel = channel; calculateImportance(); calculateUserSentiment(); mVibration = calculateVibration(); if (restrictAudioAttributesCall() || restrictAudioAttributesAlarm() || restrictAudioAttributesMedia()) { mAttributes = channel.getAudioAttributes(); } } } Loading