Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 989609de authored by Matías Hernández's avatar Matías Hernández
Browse files

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
parent 265bf0b2
Loading
Loading
Loading
Loading
+27 −9
Original line number Diff line number Diff line
@@ -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;
    }

+18 −14
Original line number Diff line number Diff line
@@ -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<ZenRule> 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<ZenRule> matchingRules = findMatchingRules(newConfig, ruleDefinition, condition);
            List<ZenRule> 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<ZenRule> 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);
+45 −0
Original line number Diff line number Diff line
@@ -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) -> {
        });