From 989609de4b0c5394ee19fa9733a9426179ab651d Mon Sep 17 00:00:00 2001 From: Matías Hernández Date: Wed, 15 Jan 2025 17:20:20 +0100 Subject: Improve bugreport logging of zen rule activation changes The previous format conflated rule owner with rule activator, but beginning with modes_ui user activation of app-owned rules is possible via SystemUI. Note that we did have the uid so it was possible to decode the correct flow in the previous logs too, but this is hopefully much clearer. Fixes: 371578616 Test: atest ZenModeHelperTest Flag: EXEMPT minor logging change Change-Id: Ia00ec806f6edb565404acade23df1069c1adfe40 --- .../com/android/server/notification/ZenLog.java | 36 ++++++++++++----- .../android/server/notification/ZenModeHelper.java | 32 ++++++++------- .../server/notification/ZenModeHelperTest.java | 45 ++++++++++++++++++++++ 3 files changed, 90 insertions(+), 23 deletions(-) diff --git a/services/core/java/com/android/server/notification/ZenLog.java b/services/core/java/com/android/server/notification/ZenLog.java index 1aa5ac046ae9..7e853d9d2d0b 100644 --- a/services/core/java/com/android/server/notification/ZenLog.java +++ b/services/core/java/com/android/server/notification/ZenLog.java @@ -16,6 +16,7 @@ package com.android.server.notification; +import android.annotation.Nullable; import android.app.NotificationManager; import android.content.ComponentName; import android.media.AudioManager; @@ -26,6 +27,7 @@ import android.provider.Settings.Global; import android.service.notification.IConditionProvider; import android.service.notification.NotificationListenerService; import android.service.notification.ZenModeConfig; +import android.service.notification.ZenModeConfig.ConfigOrigin; import android.service.notification.ZenModeDiff; import android.util.LocalLog; @@ -119,16 +121,17 @@ public class ZenLog { append(TYPE_UNSUBSCRIBE, uri + "," + subscribeResult(provider, e)); } - public static void traceConfig(String reason, ComponentName triggeringComponent, - ZenModeConfig oldConfig, ZenModeConfig newConfig, int callingUid) { + public static void traceConfig(@ConfigOrigin int origin, String reason, + @Nullable ComponentName triggeringComponent, ZenModeConfig oldConfig, + ZenModeConfig newConfig, int callingUid) { ZenModeDiff.ConfigDiff diff = new ZenModeDiff.ConfigDiff(oldConfig, newConfig); - if (diff == null || !diff.hasDiff()) { - append(TYPE_CONFIG, reason + " no changes"); + if (!diff.hasDiff()) { + append(TYPE_CONFIG, reason + " (" + originToString(origin) + ") no changes"); } else { - append(TYPE_CONFIG, reason - + " - " + triggeringComponent + " : " + callingUid - + ",\n" + (newConfig != null ? newConfig.toString() : null) - + ",\n" + diff); + append(TYPE_CONFIG, reason + " (" + originToString(origin) + ") from uid " + callingUid + + (triggeringComponent != null ? " - " + triggeringComponent : "") + ",\n" + + (newConfig != null ? newConfig.toString() : null) + ",\n" + + diff); } } @@ -241,7 +244,22 @@ public class ZenLog { } } - private static String componentToString(ComponentName component) { + private static String originToString(@ConfigOrigin int origin) { + return switch (origin) { + case ZenModeConfig.ORIGIN_UNKNOWN -> "ORIGIN_UNKNOWN"; + case ZenModeConfig.ORIGIN_INIT -> "ORIGIN_INIT"; + case ZenModeConfig.ORIGIN_INIT_USER -> "ORIGIN_INIT_USER"; + case ZenModeConfig.ORIGIN_USER_IN_SYSTEMUI -> "ORIGIN_USER_IN_SYSTEMUI"; + case ZenModeConfig.ORIGIN_APP -> "ORIGIN_APP"; + case ZenModeConfig.ORIGIN_SYSTEM -> "ORIGIN_SYSTEM"; + case ZenModeConfig.ORIGIN_RESTORE_BACKUP -> "ORIGIN_RESTORE_BACKUP"; + case ZenModeConfig.ORIGIN_USER_IN_APP -> "ORIGIN_USER_IN_APP"; + default -> origin + "??"; + }; + } + + @Nullable + private static String componentToString(@Nullable ComponentName component) { return component != null ? component.toShortString() : null; } diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java index 0a63f3fb36d0..f089c3acdd70 100644 --- a/services/core/java/com/android/server/notification/ZenModeHelper.java +++ b/services/core/java/com/android/server/notification/ZenModeHelper.java @@ -659,7 +659,8 @@ public class ZenModeHelper { mContext.getString(R.string.zen_mode_implicit_deactivated), STATE_FALSE); setAutomaticZenRuleStateLocked(newConfig, Collections.singletonList(rule), - deactivated, ORIGIN_APP, callingUid); + deactivated, ORIGIN_APP, + "applyGlobalZenModeAsImplicitZenRule: " + callingPkg, callingUid); } } else { // Either create a new rule with a default ZenPolicy, or update an existing rule's @@ -971,26 +972,27 @@ public class ZenModeHelper { if (Flags.modesApi()) { if (rule != null && canManageAutomaticZenRule(rule, callingUid)) { setAutomaticZenRuleStateLocked(newConfig, Collections.singletonList(rule), - condition, origin, callingUid); + condition, origin, "setAzrState: " + rule.id, callingUid); } } else { ArrayList rules = new ArrayList<>(); rules.add(rule); // rule may be null and throw NPE in the next method. - setAutomaticZenRuleStateLocked(newConfig, rules, condition, origin, callingUid); + setAutomaticZenRuleStateLocked(newConfig, rules, condition, origin, + "setAzrState: " + (rule != null ? rule.id : "null!"), callingUid); } } } - void setAutomaticZenRuleStateFromConditionProvider(UserHandle user, Uri ruleDefinition, + void setAutomaticZenRuleStateFromConditionProvider(UserHandle user, Uri ruleConditionId, Condition condition, @ConfigOrigin int origin, int callingUid) { - checkSetRuleStateOrigin("setAutomaticZenRuleState(Uri ruleDefinition)", origin); + checkSetRuleStateOrigin("setAutomaticZenRuleStateFromConditionProvider", origin); ZenModeConfig newConfig; synchronized (mConfigLock) { ZenModeConfig config = getConfigLocked(user); if (config == null) return; newConfig = config.copy(); - List matchingRules = findMatchingRules(newConfig, ruleDefinition, condition); + List matchingRules = findMatchingRules(newConfig, ruleConditionId, condition); if (Flags.modesApi()) { for (int i = matchingRules.size() - 1; i >= 0; i--) { if (!canManageAutomaticZenRule(matchingRules.get(i), callingUid)) { @@ -998,13 +1000,14 @@ public class ZenModeHelper { } } } - setAutomaticZenRuleStateLocked(newConfig, matchingRules, condition, origin, callingUid); + setAutomaticZenRuleStateLocked(newConfig, matchingRules, condition, origin, + "setAzrStateFromCps: " + ruleConditionId, callingUid); } } @GuardedBy("mConfigLock") private void setAutomaticZenRuleStateLocked(ZenModeConfig config, List rules, - Condition condition, @ConfigOrigin int origin, int callingUid) { + Condition condition, @ConfigOrigin int origin, String reason, int callingUid) { if (rules == null || rules.isEmpty()) return; if (!Flags.modesUi()) { @@ -1015,7 +1018,7 @@ public class ZenModeHelper { for (ZenRule rule : rules) { applyConditionAndReconsiderOverride(rule, condition, origin); - setConfigLocked(config, rule.component, origin, "conditionChanged", callingUid); + setConfigLocked(config, rule.component, origin, reason, callingUid); } } @@ -2111,13 +2114,14 @@ public class ZenModeHelper { } @GuardedBy("mConfigLock") - private boolean setConfigLocked(ZenModeConfig config, ComponentName triggeringComponent, - @ConfigOrigin int origin, String reason, int callingUid) { + private boolean setConfigLocked(ZenModeConfig config, + @Nullable ComponentName triggeringComponent, @ConfigOrigin int origin, String reason, + int callingUid) { return setConfigLocked(config, origin, reason, triggeringComponent, true /*setRingerMode*/, callingUid); } - void setConfig(ZenModeConfig config, ComponentName triggeringComponent, + void setConfig(ZenModeConfig config, @Nullable ComponentName triggeringComponent, @ConfigOrigin int origin, String reason, int callingUid) { synchronized (mConfigLock) { setConfigLocked(config, triggeringComponent, origin, reason, callingUid); @@ -2126,7 +2130,7 @@ public class ZenModeHelper { @GuardedBy("mConfigLock") private boolean setConfigLocked(ZenModeConfig config, @ConfigOrigin int origin, - String reason, ComponentName triggeringComponent, boolean setRingerMode, + String reason, @Nullable ComponentName triggeringComponent, boolean setRingerMode, int callingUid) { final long identity = Binder.clearCallingIdentity(); try { @@ -2149,7 +2153,7 @@ public class ZenModeHelper { mConfigs.put(config.user, config); } if (DEBUG) Log.d(TAG, "setConfigLocked reason=" + reason, new Throwable()); - ZenLog.traceConfig(reason, triggeringComponent, mConfig, config, callingUid); + ZenLog.traceConfig(origin, reason, triggeringComponent, mConfig, config, callingUid); // send some broadcasts Policy newPolicy = getNotificationPolicy(config); diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java index 6ef078b6da8a..96fddf13cdd0 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java @@ -211,7 +211,9 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; +import java.io.PrintWriter; import java.io.Reader; +import java.io.StringWriter; import java.time.Instant; import java.time.ZoneOffset; import java.time.temporal.ChronoUnit; @@ -7406,6 +7408,43 @@ public class ZenModeHelperTest extends UiServiceTestCase { .isEqualTo(mZenModeHelper.getDefaultZenPolicy()); } + @Test + public void setAutomaticZenRuleState_logsOriginToZenLog() { + AutomaticZenRule azr = new AutomaticZenRule.Builder("Rule", Uri.parse("cond")) + .setPackage(mPkg) + .build(); + String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, azr, + ORIGIN_APP, "adding", CUSTOM_PKG_UID); + ZenLog.clear(); + + // User enables manually from QS: + mZenModeHelper.setAutomaticZenRuleState(UserHandle.CURRENT, ruleId, + new Condition(azr.getConditionId(), "", STATE_TRUE), ORIGIN_USER_IN_SYSTEMUI, + 123456); + + assertThat(getZenLog()).contains( + "config: setAzrState: " + ruleId + " (ORIGIN_USER_IN_SYSTEMUI) from uid " + 1234); + } + + @Test + public void setAutomaticZenRuleStateFromConditionProvider_logsOriginToZenLog() { + AutomaticZenRule azr = new AutomaticZenRule.Builder("Rule", Uri.parse("cond/cond")) + .setOwner(new ComponentName(CUSTOM_PKG_NAME, "SomeConditionProvider")) + .setPackage(mPkg) + .build(); + String ruleId = mZenModeHelper.addAutomaticZenRule(UserHandle.CURRENT, mPkg, azr, + ORIGIN_APP, "adding", CUSTOM_PKG_UID); + ZenLog.clear(); + + // App enables rule through CPS + mZenModeHelper.setAutomaticZenRuleStateFromConditionProvider(UserHandle.CURRENT, + Uri.parse("cond/cond"), new Condition(azr.getConditionId(), "", STATE_TRUE), + ORIGIN_APP, CUSTOM_PKG_UID); + + assertThat(getZenLog()).contains( + "config: setAzrStateFromCps: cond/cond (ORIGIN_APP) from uid " + CUSTOM_PKG_UID); + } + private static void addZenRule(ZenModeConfig config, String id, String ownerPkg, int zenMode, @Nullable ZenPolicy zenPolicy) { ZenRule rule = new ZenRule(); @@ -7530,6 +7569,12 @@ public class ZenModeHelperTest extends UiServiceTestCase { assertThat(dndProto.getNotificationList().getNumber()).isEqualTo(STATE_ALLOW); } + private static String getZenLog() { + StringWriter zenLogWriter = new StringWriter(); + ZenLog.dump(new PrintWriter(zenLogWriter), ""); + return zenLogWriter.toString(); + } + private static void withoutWtfCrash(Runnable test) { Log.TerribleFailureHandler oldHandler = Log.setWtfHandler((tag, what, system) -> { }); -- cgit v1.2.3-59-g8ed1b