Loading core/java/android/app/AutomaticZenRule.java +6 −6 Original line number Diff line number Diff line Loading @@ -228,7 +228,7 @@ public final class AutomaticZenRule implements Parcelable { public AutomaticZenRule(Parcel source) { enabled = source.readInt() == ENABLED; if (source.readInt() == ENABLED) { name = getTrimmedString(source.readString8()); name = getTrimmedString(source.readString()); } interruptionFilter = source.readInt(); conditionId = getTrimmedUri(source.readParcelable(null, android.net.Uri.class)); Loading @@ -238,11 +238,11 @@ public final class AutomaticZenRule implements Parcelable { source.readParcelable(null, android.content.ComponentName.class)); creationTime = source.readLong(); mZenPolicy = source.readParcelable(null, ZenPolicy.class); mPkg = source.readString8(); mPkg = source.readString(); mDeviceEffects = source.readParcelable(null, ZenDeviceEffects.class); mAllowManualInvocation = source.readBoolean(); mIconResId = source.readInt(); mTriggerDescription = getTrimmedString(source.readString8(), MAX_DESC_LENGTH); mTriggerDescription = getTrimmedString(source.readString(), MAX_DESC_LENGTH); mType = source.readInt(); } Loading Loading @@ -514,7 +514,7 @@ public final class AutomaticZenRule implements Parcelable { dest.writeInt(enabled ? ENABLED : DISABLED); if (name != null) { dest.writeInt(1); dest.writeString8(name); dest.writeString(name); } else { dest.writeInt(0); } Loading @@ -524,11 +524,11 @@ public final class AutomaticZenRule implements Parcelable { dest.writeParcelable(configurationActivity, 0); dest.writeLong(creationTime); dest.writeParcelable(mZenPolicy, 0); dest.writeString8(mPkg); dest.writeString(mPkg); dest.writeParcelable(mDeviceEffects, 0); dest.writeBoolean(mAllowManualInvocation); dest.writeInt(mIconResId); dest.writeString8(mTriggerDescription); dest.writeString(mTriggerDescription); dest.writeInt(mType); } Loading core/java/android/service/notification/ZenModeConfig.java +12 −12 Original line number Diff line number Diff line Loading @@ -2636,7 +2636,7 @@ public class ZenModeConfig implements Parcelable { enabled = source.readInt() == 1; snoozing = source.readInt() == 1; if (source.readInt() == 1) { name = source.readString8(); name = source.readString(); } zenMode = source.readInt(); conditionId = source.readParcelable(null, android.net.Uri.class); Loading @@ -2644,18 +2644,18 @@ public class ZenModeConfig implements Parcelable { component = source.readParcelable(null, android.content.ComponentName.class); configurationActivity = source.readParcelable(null, android.content.ComponentName.class); if (source.readInt() == 1) { id = source.readString8(); id = source.readString(); } creationTime = source.readLong(); if (source.readInt() == 1) { enabler = source.readString8(); enabler = source.readString(); } zenPolicy = source.readParcelable(null, android.service.notification.ZenPolicy.class); zenDeviceEffects = source.readParcelable(null, ZenDeviceEffects.class); pkg = source.readString8(); pkg = source.readString(); allowManualInvocation = source.readBoolean(); iconResName = source.readString8(); triggerDescription = source.readString8(); iconResName = source.readString(); triggerDescription = source.readString(); type = source.readInt(); userModifiedFields = source.readInt(); zenPolicyUserModifiedFields = source.readInt(); Loading Loading @@ -2703,7 +2703,7 @@ public class ZenModeConfig implements Parcelable { dest.writeInt(snoozing ? 1 : 0); if (name != null) { dest.writeInt(1); dest.writeString8(name); dest.writeString(name); } else { dest.writeInt(0); } Loading @@ -2714,23 +2714,23 @@ public class ZenModeConfig implements Parcelable { dest.writeParcelable(configurationActivity, 0); if (id != null) { dest.writeInt(1); dest.writeString8(id); dest.writeString(id); } else { dest.writeInt(0); } dest.writeLong(creationTime); if (enabler != null) { dest.writeInt(1); dest.writeString8(enabler); dest.writeString(enabler); } else { dest.writeInt(0); } dest.writeParcelable(zenPolicy, 0); dest.writeParcelable(zenDeviceEffects, 0); dest.writeString8(pkg); dest.writeString(pkg); dest.writeBoolean(allowManualInvocation); dest.writeString8(iconResName); dest.writeString8(triggerDescription); dest.writeString(iconResName); dest.writeString(triggerDescription); dest.writeInt(type); dest.writeInt(userModifiedFields); dest.writeInt(zenPolicyUserModifiedFields); Loading services/core/java/com/android/server/notification/ConditionProviders.java +2 −11 Original line number Diff line number Diff line Loading @@ -46,7 +46,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class ConditionProviders extends ManagedServices { Loading Loading @@ -203,14 +202,7 @@ public class ConditionProviders extends ManagedServices { @Override protected void loadDefaultsFromConfig() { for (String dndPackage : getDefaultDndAccessPackages(mContext)) { addDefaultComponentOrPackage(dndPackage); } } static List<String> getDefaultDndAccessPackages(Context context) { ArrayList<String> packages = new ArrayList<>(); String defaultDndAccess = context.getResources().getString( String defaultDndAccess = mContext.getResources().getString( R.string.config_defaultDndAccessPackages); if (defaultDndAccess != null) { String[] dnds = defaultDndAccess.split(ManagedServices.ENABLED_SERVICES_SEPARATOR); Loading @@ -218,10 +210,9 @@ public class ConditionProviders extends ManagedServices { if (TextUtils.isEmpty(dnds[i])) { continue; } packages.add(dnds[i]); addDefaultComponentOrPackage(dnds[i]); } } return packages; } @Override Loading services/core/java/com/android/server/notification/ZenConfigTrimmer.javadeleted 100644 → 0 +0 −109 Original line number Diff line number Diff line /* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.notification; import android.content.Context; import android.os.Parcel; import android.service.notification.SystemZenRules; import android.service.notification.ZenModeConfig; import android.util.Slog; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; class ZenConfigTrimmer { private static final String TAG = "ZenConfigTrimmer"; private static final int MAXIMUM_PARCELED_SIZE = 150_000; // bytes private final HashSet<String> mTrustedPackages; ZenConfigTrimmer(Context context) { mTrustedPackages = new HashSet<>(); mTrustedPackages.add(SystemZenRules.PACKAGE_ANDROID); mTrustedPackages.addAll(ConditionProviders.getDefaultDndAccessPackages(context)); } void trimToMaximumSize(ZenModeConfig config) { Map<String, PackageRules> rulesPerPackage = new HashMap<>(); for (ZenModeConfig.ZenRule rule : config.automaticRules.values()) { PackageRules pkgRules = rulesPerPackage.computeIfAbsent(rule.pkg, PackageRules::new); pkgRules.mRules.add(rule); } int totalSize = 0; for (PackageRules pkgRules : rulesPerPackage.values()) { totalSize += pkgRules.dataSize(); } if (totalSize > MAXIMUM_PARCELED_SIZE) { List<PackageRules> deletionCandidates = new ArrayList<>(); for (PackageRules pkgRules : rulesPerPackage.values()) { if (!mTrustedPackages.contains(pkgRules.mPkg)) { deletionCandidates.add(pkgRules); } } deletionCandidates.sort(Comparator.comparingInt(PackageRules::dataSize).reversed()); evictPackagesFromConfig(config, deletionCandidates, totalSize); } } private static void evictPackagesFromConfig(ZenModeConfig config, List<PackageRules> deletionCandidates, int currentSize) { while (currentSize > MAXIMUM_PARCELED_SIZE && !deletionCandidates.isEmpty()) { PackageRules rulesToDelete = deletionCandidates.removeFirst(); Slog.w(TAG, String.format("Evicting %s zen rules from package '%s' (%s bytes)", rulesToDelete.mRules.size(), rulesToDelete.mPkg, rulesToDelete.dataSize())); for (ZenModeConfig.ZenRule rule : rulesToDelete.mRules) { config.automaticRules.remove(rule.id); } currentSize -= rulesToDelete.dataSize(); } } private static class PackageRules { private final String mPkg; private final List<ZenModeConfig.ZenRule> mRules; private int mParceledSize = -1; PackageRules(String pkg) { mPkg = pkg; mRules = new ArrayList<>(); } private int dataSize() { if (mParceledSize >= 0) { return mParceledSize; } Parcel parcel = Parcel.obtain(); try { parcel.writeParcelableList(mRules, 0); mParceledSize = parcel.dataSize(); return mParceledSize; } finally { parcel.recycle(); } } } } services/core/java/com/android/server/notification/ZenModeHelper.java +6 −9 Original line number Diff line number Diff line Loading @@ -48,7 +48,6 @@ import static android.service.notification.ZenModeConfig.isImplicitRuleId; import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE; import static com.android.internal.util.Preconditions.checkArgument; import static com.android.server.notification.Flags.preventZenDeviceEffectsWhileDriving; import static com.android.server.notification.Flags.limitZenConfigSize; import static java.util.Objects.requireNonNull; Loading Loading @@ -193,7 +192,6 @@ public class ZenModeHelper { private final ConditionProviders.Config mServiceConfig; private final SystemUiSystemPropertiesFlags.FlagResolver mFlagResolver; private final ZenModeEventLogger mZenModeEventLogger; private final ZenConfigTrimmer mConfigTrimmer; @VisibleForTesting protected int mZenMode; @VisibleForTesting protected NotificationManager.Policy mConsolidatedPolicy; Loading Loading @@ -228,7 +226,6 @@ public class ZenModeHelper { mClock = clock; addCallback(mMetrics); mAppOps = context.getSystemService(AppOpsManager.class); mConfigTrimmer = new ZenConfigTrimmer(mContext); mDefaultConfig = Flags.modesUi() ? ZenModeConfig.getDefaultConfig() Loading Loading @@ -2064,20 +2061,20 @@ public class ZenModeHelper { Log.w(TAG, "Invalid config in setConfigLocked; " + config); return false; } if (limitZenConfigSize() && (origin == ORIGIN_APP || origin == ORIGIN_USER_IN_APP)) { mConfigTrimmer.trimToMaximumSize(config); } if (config.user != mUser) { // simply store away for background users synchronized (mConfigLock) { mConfigs.put(config.user, config); } if (DEBUG) Log.d(TAG, "setConfigLocked: store config for user " + config.user); return true; } // handle CPS backed conditions - danger! may modify config mConditions.evaluateConfig(config, null, false /*processSubscriptions*/); synchronized (mConfigLock) { mConfigs.put(config.user, config); } if (DEBUG) Log.d(TAG, "setConfigLocked reason=" + reason, new Throwable()); ZenLog.traceConfig(origin, reason, triggeringComponent, mConfig, config, callingUid); Loading Loading
core/java/android/app/AutomaticZenRule.java +6 −6 Original line number Diff line number Diff line Loading @@ -228,7 +228,7 @@ public final class AutomaticZenRule implements Parcelable { public AutomaticZenRule(Parcel source) { enabled = source.readInt() == ENABLED; if (source.readInt() == ENABLED) { name = getTrimmedString(source.readString8()); name = getTrimmedString(source.readString()); } interruptionFilter = source.readInt(); conditionId = getTrimmedUri(source.readParcelable(null, android.net.Uri.class)); Loading @@ -238,11 +238,11 @@ public final class AutomaticZenRule implements Parcelable { source.readParcelable(null, android.content.ComponentName.class)); creationTime = source.readLong(); mZenPolicy = source.readParcelable(null, ZenPolicy.class); mPkg = source.readString8(); mPkg = source.readString(); mDeviceEffects = source.readParcelable(null, ZenDeviceEffects.class); mAllowManualInvocation = source.readBoolean(); mIconResId = source.readInt(); mTriggerDescription = getTrimmedString(source.readString8(), MAX_DESC_LENGTH); mTriggerDescription = getTrimmedString(source.readString(), MAX_DESC_LENGTH); mType = source.readInt(); } Loading Loading @@ -514,7 +514,7 @@ public final class AutomaticZenRule implements Parcelable { dest.writeInt(enabled ? ENABLED : DISABLED); if (name != null) { dest.writeInt(1); dest.writeString8(name); dest.writeString(name); } else { dest.writeInt(0); } Loading @@ -524,11 +524,11 @@ public final class AutomaticZenRule implements Parcelable { dest.writeParcelable(configurationActivity, 0); dest.writeLong(creationTime); dest.writeParcelable(mZenPolicy, 0); dest.writeString8(mPkg); dest.writeString(mPkg); dest.writeParcelable(mDeviceEffects, 0); dest.writeBoolean(mAllowManualInvocation); dest.writeInt(mIconResId); dest.writeString8(mTriggerDescription); dest.writeString(mTriggerDescription); dest.writeInt(mType); } Loading
core/java/android/service/notification/ZenModeConfig.java +12 −12 Original line number Diff line number Diff line Loading @@ -2636,7 +2636,7 @@ public class ZenModeConfig implements Parcelable { enabled = source.readInt() == 1; snoozing = source.readInt() == 1; if (source.readInt() == 1) { name = source.readString8(); name = source.readString(); } zenMode = source.readInt(); conditionId = source.readParcelable(null, android.net.Uri.class); Loading @@ -2644,18 +2644,18 @@ public class ZenModeConfig implements Parcelable { component = source.readParcelable(null, android.content.ComponentName.class); configurationActivity = source.readParcelable(null, android.content.ComponentName.class); if (source.readInt() == 1) { id = source.readString8(); id = source.readString(); } creationTime = source.readLong(); if (source.readInt() == 1) { enabler = source.readString8(); enabler = source.readString(); } zenPolicy = source.readParcelable(null, android.service.notification.ZenPolicy.class); zenDeviceEffects = source.readParcelable(null, ZenDeviceEffects.class); pkg = source.readString8(); pkg = source.readString(); allowManualInvocation = source.readBoolean(); iconResName = source.readString8(); triggerDescription = source.readString8(); iconResName = source.readString(); triggerDescription = source.readString(); type = source.readInt(); userModifiedFields = source.readInt(); zenPolicyUserModifiedFields = source.readInt(); Loading Loading @@ -2703,7 +2703,7 @@ public class ZenModeConfig implements Parcelable { dest.writeInt(snoozing ? 1 : 0); if (name != null) { dest.writeInt(1); dest.writeString8(name); dest.writeString(name); } else { dest.writeInt(0); } Loading @@ -2714,23 +2714,23 @@ public class ZenModeConfig implements Parcelable { dest.writeParcelable(configurationActivity, 0); if (id != null) { dest.writeInt(1); dest.writeString8(id); dest.writeString(id); } else { dest.writeInt(0); } dest.writeLong(creationTime); if (enabler != null) { dest.writeInt(1); dest.writeString8(enabler); dest.writeString(enabler); } else { dest.writeInt(0); } dest.writeParcelable(zenPolicy, 0); dest.writeParcelable(zenDeviceEffects, 0); dest.writeString8(pkg); dest.writeString(pkg); dest.writeBoolean(allowManualInvocation); dest.writeString8(iconResName); dest.writeString8(triggerDescription); dest.writeString(iconResName); dest.writeString(triggerDescription); dest.writeInt(type); dest.writeInt(userModifiedFields); dest.writeInt(zenPolicyUserModifiedFields); Loading
services/core/java/com/android/server/notification/ConditionProviders.java +2 −11 Original line number Diff line number Diff line Loading @@ -46,7 +46,6 @@ import java.io.IOException; import java.io.PrintWriter; import java.util.ArrayList; import java.util.Arrays; import java.util.List; public class ConditionProviders extends ManagedServices { Loading Loading @@ -203,14 +202,7 @@ public class ConditionProviders extends ManagedServices { @Override protected void loadDefaultsFromConfig() { for (String dndPackage : getDefaultDndAccessPackages(mContext)) { addDefaultComponentOrPackage(dndPackage); } } static List<String> getDefaultDndAccessPackages(Context context) { ArrayList<String> packages = new ArrayList<>(); String defaultDndAccess = context.getResources().getString( String defaultDndAccess = mContext.getResources().getString( R.string.config_defaultDndAccessPackages); if (defaultDndAccess != null) { String[] dnds = defaultDndAccess.split(ManagedServices.ENABLED_SERVICES_SEPARATOR); Loading @@ -218,10 +210,9 @@ public class ConditionProviders extends ManagedServices { if (TextUtils.isEmpty(dnds[i])) { continue; } packages.add(dnds[i]); addDefaultComponentOrPackage(dnds[i]); } } return packages; } @Override Loading
services/core/java/com/android/server/notification/ZenConfigTrimmer.javadeleted 100644 → 0 +0 −109 Original line number Diff line number Diff line /* * Copyright (C) 2025 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.notification; import android.content.Context; import android.os.Parcel; import android.service.notification.SystemZenRules; import android.service.notification.ZenModeConfig; import android.util.Slog; import java.util.ArrayList; import java.util.Comparator; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; class ZenConfigTrimmer { private static final String TAG = "ZenConfigTrimmer"; private static final int MAXIMUM_PARCELED_SIZE = 150_000; // bytes private final HashSet<String> mTrustedPackages; ZenConfigTrimmer(Context context) { mTrustedPackages = new HashSet<>(); mTrustedPackages.add(SystemZenRules.PACKAGE_ANDROID); mTrustedPackages.addAll(ConditionProviders.getDefaultDndAccessPackages(context)); } void trimToMaximumSize(ZenModeConfig config) { Map<String, PackageRules> rulesPerPackage = new HashMap<>(); for (ZenModeConfig.ZenRule rule : config.automaticRules.values()) { PackageRules pkgRules = rulesPerPackage.computeIfAbsent(rule.pkg, PackageRules::new); pkgRules.mRules.add(rule); } int totalSize = 0; for (PackageRules pkgRules : rulesPerPackage.values()) { totalSize += pkgRules.dataSize(); } if (totalSize > MAXIMUM_PARCELED_SIZE) { List<PackageRules> deletionCandidates = new ArrayList<>(); for (PackageRules pkgRules : rulesPerPackage.values()) { if (!mTrustedPackages.contains(pkgRules.mPkg)) { deletionCandidates.add(pkgRules); } } deletionCandidates.sort(Comparator.comparingInt(PackageRules::dataSize).reversed()); evictPackagesFromConfig(config, deletionCandidates, totalSize); } } private static void evictPackagesFromConfig(ZenModeConfig config, List<PackageRules> deletionCandidates, int currentSize) { while (currentSize > MAXIMUM_PARCELED_SIZE && !deletionCandidates.isEmpty()) { PackageRules rulesToDelete = deletionCandidates.removeFirst(); Slog.w(TAG, String.format("Evicting %s zen rules from package '%s' (%s bytes)", rulesToDelete.mRules.size(), rulesToDelete.mPkg, rulesToDelete.dataSize())); for (ZenModeConfig.ZenRule rule : rulesToDelete.mRules) { config.automaticRules.remove(rule.id); } currentSize -= rulesToDelete.dataSize(); } } private static class PackageRules { private final String mPkg; private final List<ZenModeConfig.ZenRule> mRules; private int mParceledSize = -1; PackageRules(String pkg) { mPkg = pkg; mRules = new ArrayList<>(); } private int dataSize() { if (mParceledSize >= 0) { return mParceledSize; } Parcel parcel = Parcel.obtain(); try { parcel.writeParcelableList(mRules, 0); mParceledSize = parcel.dataSize(); return mParceledSize; } finally { parcel.recycle(); } } } }
services/core/java/com/android/server/notification/ZenModeHelper.java +6 −9 Original line number Diff line number Diff line Loading @@ -48,7 +48,6 @@ import static android.service.notification.ZenModeConfig.isImplicitRuleId; import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE; import static com.android.internal.util.Preconditions.checkArgument; import static com.android.server.notification.Flags.preventZenDeviceEffectsWhileDriving; import static com.android.server.notification.Flags.limitZenConfigSize; import static java.util.Objects.requireNonNull; Loading Loading @@ -193,7 +192,6 @@ public class ZenModeHelper { private final ConditionProviders.Config mServiceConfig; private final SystemUiSystemPropertiesFlags.FlagResolver mFlagResolver; private final ZenModeEventLogger mZenModeEventLogger; private final ZenConfigTrimmer mConfigTrimmer; @VisibleForTesting protected int mZenMode; @VisibleForTesting protected NotificationManager.Policy mConsolidatedPolicy; Loading Loading @@ -228,7 +226,6 @@ public class ZenModeHelper { mClock = clock; addCallback(mMetrics); mAppOps = context.getSystemService(AppOpsManager.class); mConfigTrimmer = new ZenConfigTrimmer(mContext); mDefaultConfig = Flags.modesUi() ? ZenModeConfig.getDefaultConfig() Loading Loading @@ -2064,20 +2061,20 @@ public class ZenModeHelper { Log.w(TAG, "Invalid config in setConfigLocked; " + config); return false; } if (limitZenConfigSize() && (origin == ORIGIN_APP || origin == ORIGIN_USER_IN_APP)) { mConfigTrimmer.trimToMaximumSize(config); } if (config.user != mUser) { // simply store away for background users synchronized (mConfigLock) { mConfigs.put(config.user, config); } if (DEBUG) Log.d(TAG, "setConfigLocked: store config for user " + config.user); return true; } // handle CPS backed conditions - danger! may modify config mConditions.evaluateConfig(config, null, false /*processSubscriptions*/); synchronized (mConfigLock) { mConfigs.put(config.user, config); } if (DEBUG) Log.d(TAG, "setConfigLocked reason=" + reason, new Throwable()); ZenLog.traceConfig(origin, reason, triggeringComponent, mConfig, config, callingUid); Loading