diff options
8 files changed, 212 insertions, 75 deletions
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java index a0fe6c504932..330ab87cdd53 100644 --- a/core/java/android/app/Notification.java +++ b/core/java/android/app/Notification.java @@ -3413,8 +3413,11 @@ public class Notification implements Parcelable * * @hide */ - public void setAllowlistToken(@Nullable IBinder token) { - mAllowlistToken = token; + public void clearAllowlistToken() { + mAllowlistToken = null; + if (publicVersion != null) { + publicVersion.clearAllowlistToken(); + } } /** diff --git a/core/java/android/hardware/usb/UsbConfiguration.java b/core/java/android/hardware/usb/UsbConfiguration.java index 66269cb772f8..b25f47b11532 100644 --- a/core/java/android/hardware/usb/UsbConfiguration.java +++ b/core/java/android/hardware/usb/UsbConfiguration.java @@ -172,7 +172,8 @@ public class UsbConfiguration implements Parcelable { String name = in.readString(); int attributes = in.readInt(); int maxPower = in.readInt(); - Parcelable[] interfaces = in.readParcelableArray(UsbInterface.class.getClassLoader()); + Parcelable[] interfaces = in.readParcelableArray( + UsbInterface.class.getClassLoader(), UsbInterface.class); UsbConfiguration configuration = new UsbConfiguration(id, name, attributes, maxPower); configuration.setInterfaces(interfaces); return configuration; diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java index 1f7260972f24..a80061efb19a 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/BluetoothBroadcastUtils.java @@ -53,8 +53,8 @@ public final class BluetoothBroadcastUtils { static final String PREFIX_BT_SYNC_INTERVAL = "SI:"; static final String PREFIX_BT_IS_ENCRYPTED = "E:"; static final String PREFIX_BT_BROADCAST_CODE = "C:"; - static final String PREFIX_BT_PRESENTATION_DELAY = "D:"; - static final String PREFIX_BT_SUBGROUPS = "G:"; + static final String PREFIX_BT_PRESENTATION_DELAY = "PD:"; + static final String PREFIX_BT_SUBGROUPS = "SG:"; static final String PREFIX_BT_ANDROID_VERSION = "V:"; // BluetoothLeBroadcastSubgroup diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java index d2329c5f8f24..d7393abdafa5 100644 --- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java +++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java @@ -29,7 +29,9 @@ import java.io.ByteArrayOutputStream; import java.nio.charset.StandardCharsets; import java.util.ArrayList; import java.util.Arrays; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -39,6 +41,43 @@ public class LocalBluetoothLeBroadcastMetadata { private static final String METADATA_START = "<"; private static final String METADATA_END = ">"; private static final String PATTERN_REGEX = "<(.*?)>"; + private static final String PATTERN_BT_BROADCAST_METADATA = + "T:<(.*?)>;+D:<(.*?)>;+AS:<(.*?)>;+B:<(.*?)>;+SI:<(.*?)>;+E:<(.*?)>;+C:<(.*?)>;" + + "+PD:<(.*?)>;+SG:(.*)"; + private static final String PATTERN_BT_SUBGROUP = + "CID:<(.*?)>;+CC:<(.*?);>;+AC:<(.*?);>;+CP:<(.*?)>;+BC:<(.*)>;>;"; + private static final String PATTERN_BT_CHANNEL = "CI:<(.*?)>;+BCCM:<(.*?);>;"; + + /* Index for BluetoothLeBroadcastMetadata */ + private static int MATCH_INDEX_ADDRESS_TYPE = 1; + private static int MATCH_INDEX_DEVICE = 2; + private static int MATCH_INDEX_ADVERTISING_SID = 3; + private static int MATCH_INDEX_BROADCAST_ID = 4; + private static int MATCH_INDEX_SYNC_INTERVAL = 5; + private static int MATCH_INDEX_IS_ENCRYPTED = 6; + private static int MATCH_INDEX_BROADCAST_CODE = 7; + private static int MATCH_INDEX_PRESENTATION_DELAY = 8; + private static int MATCH_INDEX_SUBGROUPS = 9; + + /* Index for BluetoothLeBroadcastSubgroup */ + private static int MATCH_INDEX_CODEC_ID = 1; + private static int MATCH_INDEX_CODEC_CONFIG = 2; + private static int MATCH_INDEX_AUDIO_CONTENT = 3; + private static int MATCH_INDEX_CHANNEL_PREF = 4; + private static int MATCH_INDEX_BROADCAST_CHANNEL = 5; + + /* Index for BluetoothLeAudioCodecConfigMetadata */ + private static int LIST_INDEX_AUDIO_LOCATION = 0; + private static int LIST_INDEX_CODEC_CONFIG_RAW_METADATA = 1; + + /* Index for BluetoothLeAudioContentMetadata */ + private static int LIST_INDEX_PROGRAM_INFO = 0; + private static int LIST_INDEX_LANGUAGE = 1; + private static int LIST_INDEX_AUDIO_CONTENT_RAW_METADATA = 2; + + /* Index for BluetoothLeBroadcastChannel */ + private static int MATCH_INDEX_CHANNEL_INDEX = 1; + private static int MATCH_INDEX_CHANNEL_CODEC_CONFIG = 2; private BluetoothLeBroadcastSubgroup mSubgroup; private List<BluetoothLeBroadcastSubgroup> mSubgroupList; @@ -56,17 +95,20 @@ public class LocalBluetoothLeBroadcastMetadata { private byte[] mBroadcastCode; // BluetoothLeBroadcastSubgroup - private long mCodecId; + private int mCodecId; private BluetoothLeAudioContentMetadata mContentMetadata; private BluetoothLeAudioCodecConfigMetadata mConfigMetadata; - private BluetoothLeBroadcastChannel mChannel; + private Boolean mNoChannelPreference; + private List<BluetoothLeBroadcastChannel> mChannel; // BluetoothLeAudioCodecConfigMetadata private long mAudioLocation; + private byte[] mCodecConfigMetadata; // BluetoothLeAudioContentMetadata private String mLanguage; private String mProgramInfo; + private byte[] mAudioContentMetadata; // BluetoothLeBroadcastChannel private boolean mIsSelected; @@ -136,6 +178,7 @@ public class LocalBluetoothLeBroadcastMetadata { for (BluetoothLeBroadcastSubgroup subgroup: subgroupList) { String audioCodec = convertAudioCodecConfigToString(subgroup.getCodecSpecificConfig()); String audioContent = convertAudioContentToString(subgroup.getContentMetadata()); + boolean hasChannelPreference = subgroup.hasChannelPreference(); String channels = convertChannelToString(subgroup.getChannels()); subgroupString = new StringBuilder() .append(BluetoothBroadcastUtils.PREFIX_BTSG_CODEC_ID) @@ -147,6 +190,9 @@ public class LocalBluetoothLeBroadcastMetadata { .append(BluetoothBroadcastUtils.PREFIX_BTSG_AUDIO_CONTENT) .append(METADATA_START).append(audioContent).append(METADATA_END) .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE) + .append(BluetoothBroadcastUtils.PREFIX_BTSG_CHANNEL_PREF) + .append(METADATA_START).append(hasChannelPreference).append(METADATA_END) + .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE) .append(BluetoothBroadcastUtils.PREFIX_BTSG_BROADCAST_CHANNEL) .append(METADATA_START).append(channels).append(METADATA_END) .append(BluetoothBroadcastUtils.DELIMITER_QR_CODE) @@ -212,19 +258,18 @@ public class LocalBluetoothLeBroadcastMetadata { if (DEBUG) { Log.d(TAG, "Convert " + qrCodeString + "to BluetoothLeBroadcastMetadata"); } - Pattern pattern = Pattern.compile(PATTERN_REGEX); + + Pattern pattern = Pattern.compile(PATTERN_BT_BROADCAST_METADATA, Pattern.DOTALL); Matcher match = pattern.matcher(qrCodeString); if (match.find()) { - ArrayList<String> resultList = new ArrayList<>(); - resultList.add(match.group(1)); - mSourceAddressType = Integer.parseInt(resultList.get(0)); + mSourceAddressType = Integer.parseInt(match.group(MATCH_INDEX_ADDRESS_TYPE)); mSourceDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice( - resultList.get(1)); - mSourceAdvertisingSid = Integer.parseInt(resultList.get(2)); - mBroadcastId = Integer.parseInt(resultList.get(3)); - mPaSyncInterval = Integer.parseInt(resultList.get(4)); - mIsEncrypted = Boolean.valueOf(resultList.get(5)); - String bcode = resultList.get(6); + match.group(MATCH_INDEX_DEVICE)); + mSourceAdvertisingSid = Integer.parseInt(match.group(MATCH_INDEX_ADVERTISING_SID)); + mBroadcastId = Integer.parseInt(match.group(MATCH_INDEX_BROADCAST_ID)); + mPaSyncInterval = Integer.parseInt(match.group(MATCH_INDEX_SYNC_INTERVAL)); + mIsEncrypted = Boolean.valueOf(match.group(MATCH_INDEX_IS_ENCRYPTED)); + String bcode = match.group(MATCH_INDEX_BROADCAST_CODE); mBroadcastCode = null; if (!bcode.equals("[]")) { mBroadcastCode = Arrays.stream(bcode.substring(1, bcode.length()-1).split(",")) @@ -235,13 +280,22 @@ public class LocalBluetoothLeBroadcastMetadata { (b1, b2)->b1.write(b2.toByteArray(), 0, b2.size())) .toByteArray(); } - mPresentationDelayMicros = Integer.parseInt(resultList.get(7)); - mSubgroup = convertToSubgroup(resultList.get(8)); - + mPresentationDelayMicros = + Integer.parseInt(match.group(MATCH_INDEX_PRESENTATION_DELAY)); if (DEBUG) { - Log.d(TAG, "Converted qrCodeString result: " + match.group()); + Log.d(TAG, "Converted qrCodeString result: " + + " ,Type = " + mSourceAddressType + + " ,Device = " + mSourceDevice + + " ,AdSid = " + mSourceAdvertisingSid + + " ,BroadcastId = " + mBroadcastId + + " ,paSync = " + mPaSyncInterval + + " ,encrypted = " + mIsEncrypted + + " ,BroadcastCode = " + Arrays.toString(mBroadcastCode) + + " ,delay = " + mPresentationDelayMicros); } + mSubgroup = convertToSubgroup(match.group(MATCH_INDEX_SUBGROUPS)); + return new BluetoothLeBroadcastMetadata.Builder() .setSourceDevice(mSourceDevice, mSourceAddressType) .setSourceAdvertisingSid(mSourceAdvertisingSid) @@ -265,26 +319,26 @@ public class LocalBluetoothLeBroadcastMetadata { if (DEBUG) { Log.d(TAG, "Convert " + subgroupString + "to BluetoothLeBroadcastSubgroup"); } - Pattern pattern = Pattern.compile(PATTERN_REGEX); + Pattern pattern = Pattern.compile(PATTERN_BT_SUBGROUP, Pattern.DOTALL); Matcher match = pattern.matcher(subgroupString); if (match.find()) { - ArrayList<String> resultList = new ArrayList<>(); - resultList.add(match.group(1)); - mCodecId = Long.getLong(resultList.get(0)); - mConfigMetadata = convertToConfigMetadata(resultList.get(1)); - mContentMetadata = convertToContentMetadata(resultList.get(2)); - mChannel = convertToChannel(resultList.get(3), mConfigMetadata); - - if (DEBUG) { - Log.d(TAG, "Converted subgroupString result: " + match.group()); + mCodecId = Integer.parseInt(match.group(MATCH_INDEX_CODEC_ID)); + mConfigMetadata = convertToConfigMetadata(match.group(MATCH_INDEX_CODEC_CONFIG)); + mContentMetadata = convertToContentMetadata(match.group(MATCH_INDEX_AUDIO_CONTENT)); + mNoChannelPreference = Boolean.valueOf(match.group(MATCH_INDEX_CHANNEL_PREF)); + mChannel = + convertToChannel(match.group(MATCH_INDEX_BROADCAST_CHANNEL), mConfigMetadata); + + BluetoothLeBroadcastSubgroup.Builder subgroupBuilder = + new BluetoothLeBroadcastSubgroup.Builder(); + subgroupBuilder.setCodecId(mCodecId); + subgroupBuilder.setCodecSpecificConfig(mConfigMetadata); + subgroupBuilder.setContentMetadata(mContentMetadata); + + for (BluetoothLeBroadcastChannel channel : mChannel) { + subgroupBuilder.addChannel(channel); } - - return new BluetoothLeBroadcastSubgroup.Builder() - .setCodecId(mCodecId) - .setCodecSpecificConfig(mConfigMetadata) - .setContentMetadata(mContentMetadata) - .addChannel(mChannel) - .build(); + return subgroupBuilder.build(); } else { if (DEBUG) { Log.d(TAG, @@ -300,17 +354,19 @@ public class LocalBluetoothLeBroadcastMetadata { Log.d(TAG, "Convert " + configMetadataString + "to BluetoothLeAudioCodecConfigMetadata"); } - Pattern pattern = Pattern.compile(PATTERN_REGEX); + Pattern pattern = Pattern.compile(PATTERN_REGEX, Pattern.DOTALL); Matcher match = pattern.matcher(configMetadataString); - if (match.find()) { - ArrayList<String> resultList = new ArrayList<>(); + ArrayList<String> resultList = new ArrayList<>(); + while (match.find()) { resultList.add(match.group(1)); - mAudioLocation = Long.getLong(resultList.get(0)); - - if (DEBUG) { - Log.d(TAG, "Converted configMetadataString result: " + match.group()); - } - + Log.d(TAG, "Codec Config match : " + match.group(1)); + } + if (DEBUG) { + Log.d(TAG, "Converted configMetadataString result: " + resultList.size()); + } + if (resultList.size() > 0) { + mAudioLocation = Long.parseLong(resultList.get(LIST_INDEX_AUDIO_LOCATION)); + mCodecConfigMetadata = resultList.get(LIST_INDEX_CODEC_CONFIG_RAW_METADATA).getBytes(); return new BluetoothLeAudioCodecConfigMetadata.Builder() .setAudioLocation(mAudioLocation) .build(); @@ -328,16 +384,27 @@ public class LocalBluetoothLeBroadcastMetadata { if (DEBUG) { Log.d(TAG, "Convert " + contentMetadataString + "to BluetoothLeAudioContentMetadata"); } - Pattern pattern = Pattern.compile(PATTERN_REGEX); + Pattern pattern = Pattern.compile(PATTERN_REGEX, Pattern.DOTALL); Matcher match = pattern.matcher(contentMetadataString); - if (match.find()) { - ArrayList<String> resultList = new ArrayList<>(); + ArrayList<String> resultList = new ArrayList<>(); + while (match.find()) { + Log.d(TAG, "Audio Content match : " + match.group(1)); resultList.add(match.group(1)); - mProgramInfo = resultList.get(0); - mLanguage = resultList.get(1); - - if (DEBUG) { - Log.d(TAG, "Converted contentMetadataString result: " + match.group()); + } + if (DEBUG) { + Log.d(TAG, "Converted contentMetadataString result: " + resultList.size()); + } + if (resultList.size() > 0) { + mProgramInfo = resultList.get(LIST_INDEX_PROGRAM_INFO); + mLanguage = resultList.get(LIST_INDEX_LANGUAGE); + mAudioContentMetadata = + resultList.get(LIST_INDEX_AUDIO_CONTENT_RAW_METADATA).getBytes(); + + /* TODO(b/265253566) : Need to set the default value for language when the user starts + * the broadcast. + */ + if (mLanguage.equals("null")) { + mLanguage = "eng"; } return new BluetoothLeAudioContentMetadata.Builder() @@ -353,28 +420,34 @@ public class LocalBluetoothLeBroadcastMetadata { } } - private BluetoothLeBroadcastChannel convertToChannel(String channelString, + private List<BluetoothLeBroadcastChannel> convertToChannel(String channelString, BluetoothLeAudioCodecConfigMetadata configMetadata) { if (DEBUG) { Log.d(TAG, "Convert " + channelString + "to BluetoothLeBroadcastChannel"); } - Pattern pattern = Pattern.compile(PATTERN_REGEX); + Pattern pattern = Pattern.compile(PATTERN_BT_CHANNEL, Pattern.DOTALL); Matcher match = pattern.matcher(channelString); - if (match.find()) { - ArrayList<String> resultList = new ArrayList<>(); - resultList.add(match.group(1)); - mIsSelected = Boolean.valueOf(resultList.get(0)); - mChannelIndex = Integer.parseInt(resultList.get(1)); + Map<Integer, BluetoothLeAudioCodecConfigMetadata> channel = + new HashMap<Integer, BluetoothLeAudioCodecConfigMetadata>(); + while (match.find()) { + channel.put(Integer.parseInt(match.group(MATCH_INDEX_CHANNEL_INDEX)), + convertToConfigMetadata(match.group(MATCH_INDEX_CHANNEL_CODEC_CONFIG))); + } - if (DEBUG) { - Log.d(TAG, "Converted channelString result: " + match.group()); + if (channel.size() > 0) { + mIsSelected = false; + ArrayList<BluetoothLeBroadcastChannel> broadcastChannelList = new ArrayList<>(); + for (Map.Entry<Integer, BluetoothLeAudioCodecConfigMetadata> entry : + channel.entrySet()) { + + broadcastChannelList.add( + new BluetoothLeBroadcastChannel.Builder() + .setSelected(mIsSelected) + .setChannelIndex(entry.getKey()) + .setCodecMetadata(entry.getValue()) + .build()); } - - return new BluetoothLeBroadcastChannel.Builder() - .setSelected(mIsSelected) - .setChannelIndex(mChannelIndex) - .setCodecMetadata(configMetadata) - .build(); + return broadcastChannelList; } else { if (DEBUG) { Log.d(TAG, diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java index 77d97129cd65..565b7d28fbf8 100644 --- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java +++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java @@ -1928,6 +1928,9 @@ public class SettingsProvider extends ContentProvider { cacheName = Settings.System.ALARM_ALERT_CACHE; } if (cacheName != null) { + if (!isValidAudioUri(name, value)) { + return false; + } final File cacheFile = new File( getRingtoneCacheDir(owningUserId), cacheName); cacheFile.delete(); @@ -1960,6 +1963,34 @@ public class SettingsProvider extends ContentProvider { } } + private boolean isValidAudioUri(String name, String uri) { + if (uri != null) { + Uri audioUri = Uri.parse(uri); + if (Settings.AUTHORITY.equals( + ContentProvider.getAuthorityWithoutUserId(audioUri.getAuthority()))) { + // Don't accept setting the default uri to self-referential URIs like + // Settings.System.DEFAULT_RINGTONE_URI, which is an alias to the value of this + // setting. + return false; + } + final String mimeType = getContext().getContentResolver().getType(audioUri); + if (mimeType == null) { + Slog.e(LOG_TAG, + "mutateSystemSetting for setting: " + name + " URI: " + audioUri + + " ignored: failure to find mimeType (no access from this context?)"); + return false; + } + if (!(mimeType.startsWith("audio/") || mimeType.equals("application/ogg") + || mimeType.equals("application/x-flac"))) { + Slog.e(LOG_TAG, + "mutateSystemSetting for setting: " + name + " URI: " + audioUri + + " ignored: associated mimeType: " + mimeType + " is not an audio type"); + return false; + } + } + return true; + } + private boolean hasWriteSecureSettingsPermission() { // Write secure settings is a more protected permission. If caller has it we are good. return getContext().checkCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index 3e53bcff792a..f3b3c49fe3ec 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -3005,6 +3005,22 @@ public class ActivityManagerService extends IActivityManager.Stub } } + /** + * Enforces that the uid of the caller matches the uid of the package. + * + * @param packageName the name of the package to match uid against. + * @param callingUid the uid of the caller. + * @throws SecurityException if the calling uid doesn't match uid of the package. + */ + private void enforceCallingPackage(String packageName, int callingUid) { + final int userId = UserHandle.getUserId(callingUid); + final int packageUid = getPackageManagerInternal().getPackageUid(packageName, + /*flags=*/ 0, userId); + if (packageUid != callingUid) { + throw new SecurityException(packageName + " does not belong to uid " + callingUid); + } + } + @Override public void setPackageScreenCompatMode(String packageName, int mode) { mActivityTaskManager.setPackageScreenCompatMode(packageName, mode); @@ -13061,13 +13077,16 @@ public class ActivityManagerService extends IActivityManager.Stub // A backup agent has just come up @Override public void backupAgentCreated(String agentPackageName, IBinder agent, int userId) { + final int callingUid = Binder.getCallingUid(); + enforceCallingPackage(agentPackageName, callingUid); + // Resolve the target user id and enforce permissions. - userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), + userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId, /* allowAll */ false, ALLOW_FULL_ONLY, "backupAgentCreated", null); if (DEBUG_BACKUP) { Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName + " = " + agent + " callingUserId = " + UserHandle.getCallingUserId() + " userId = " + userId - + " callingUid = " + Binder.getCallingUid() + " uid = " + Process.myUid()); + + " callingUid = " + callingUid + " uid = " + Process.myUid()); } synchronized(this) { diff --git a/services/core/java/com/android/server/locksettings/LockSettingsService.java b/services/core/java/com/android/server/locksettings/LockSettingsService.java index 1700268fdff3..c88ea5f70d15 100644 --- a/services/core/java/com/android/server/locksettings/LockSettingsService.java +++ b/services/core/java/com/android/server/locksettings/LockSettingsService.java @@ -3044,9 +3044,19 @@ public class LockSettingsService extends ILockSettings.Stub { } activateEscrowTokens(authToken, userId); - if (isProfileWithSeparatedLock(userId)) { - setDeviceUnlockedForUser(userId); + if (isCredentialSharableWithParent(userId)) { + if (getSeparateProfileChallengeEnabledInternal(userId)) { + setDeviceUnlockedForUser(userId); + } else { + // Here only clear StrongAuthFlags for a profile that has a unified challenge. + // StrongAuth for a profile with a separate challenge is handled differently and + // is cleared after the user successfully confirms the separate challenge to enter + // the profile. StrongAuth for the full user (e.g. userId 0) is also handled + // separately by Keyguard. + mStrongAuth.reportUnlock(userId); + } } + mStrongAuth.reportSuccessfulStrongAuthUnlock(userId); onAuthTokenKnownForUser(userId, authToken); diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java index d0ae7d59a784..b10c51c67ce4 100755 --- a/services/core/java/com/android/server/notification/NotificationManagerService.java +++ b/services/core/java/com/android/server/notification/NotificationManagerService.java @@ -4368,7 +4368,7 @@ public class NotificationManagerService extends SystemService { // Remove background token before returning notification to untrusted app, this // ensures the app isn't able to perform background operations that are // associated with notification interactions. - notification.setAllowlistToken(null); + notification.clearAllowlistToken(); return new StatusBarNotification( sbn.getPackageName(), sbn.getOpPkg(), |