Merge changes from topic "apply-night" into main

* changes:
  Fix BroadcastReceiver registration in DefaultDeviceEffectsApplier
  Apply Night Mode as part of ZenDeviceEffects
diff --git a/core/java/android/service/notification/DeviceEffectsApplier.java b/core/java/android/service/notification/DeviceEffectsApplier.java
index 234ff4d..5194cdd 100644
--- a/core/java/android/service/notification/DeviceEffectsApplier.java
+++ b/core/java/android/service/notification/DeviceEffectsApplier.java
@@ -16,6 +16,8 @@
 
 package android.service.notification;
 
+import android.service.notification.ZenModeConfig.ConfigChangeOrigin;
+
 /**
  * Responsible for making any service calls needed to apply the set of {@link ZenDeviceEffects} that
  * make sense for the current platform.
@@ -33,6 +35,13 @@
      *
      * <p>This will be called whenever the set of consolidated effects changes (normally through
      * the activation or deactivation of zen rules).
+     *
+     * @param effects The effects that should be active and inactive.
+     * @param source The origin of the change. Because the application of specific effects can be
+     *               disruptive (e.g. lead to Activity recreation), that operation can in some
+     *               cases be deferred (e.g. until screen off). However, if the effects are
+     *               changing as a result of an explicit user action, then it makes sense to
+     *               apply them immediately regardless.
      */
-    void apply(ZenDeviceEffects effects);
+    void apply(ZenDeviceEffects effects, @ConfigChangeOrigin int source);
 }
diff --git a/core/java/android/service/notification/ZenModeConfig.java b/core/java/android/service/notification/ZenModeConfig.java
index f6128ea..a5b087c 100644
--- a/core/java/android/service/notification/ZenModeConfig.java
+++ b/core/java/android/service/notification/ZenModeConfig.java
@@ -26,6 +26,7 @@
 import static android.app.NotificationManager.Policy.SUPPRESSED_EFFECT_SCREEN_OFF;
 
 import android.annotation.FlaggedApi;
+import android.annotation.IntDef;
 import android.annotation.Nullable;
 import android.app.ActivityManager;
 import android.app.AlarmManager;
@@ -61,6 +62,8 @@
 import org.xmlpull.v1.XmlPullParserException;
 
 import java.io.IOException;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
 import java.util.Arrays;
 import java.util.Calendar;
 import java.util.Date;
@@ -79,7 +82,66 @@
  * @hide
  */
 public class ZenModeConfig implements Parcelable {
-    private static String TAG = "ZenModeConfig";
+    private static final String TAG = "ZenModeConfig";
+
+    /**
+     * The {@link ZenModeConfig} is being updated because of an unknown reason.
+     */
+    public static final int UPDATE_ORIGIN_UNKNOWN = 0;
+
+    /**
+     * The {@link ZenModeConfig} is being updated because of system initialization (i.e. load from
+     * storage, on device boot).
+     */
+    public static final int UPDATE_ORIGIN_INIT = 1;
+
+    /** The {@link ZenModeConfig} is being updated (replaced) because of a user switch or unlock. */
+    public static final int UPDATE_ORIGIN_INIT_USER = 2;
+
+    /** The {@link ZenModeConfig} is being updated because of a user action, for example:
+     * <ul>
+     *     <li>{@link NotificationManager#setAutomaticZenRuleState} with a
+     *     {@link Condition#source} equal to {@link Condition#SOURCE_USER_ACTION}.</li>
+     *     <li>Adding, updating, or removing a rule from Settings.</li>
+     *     <li>Directly activating or deactivating/snoozing a rule through some UI affordance (e.g.
+     *     Quick Settings).</li>
+     * </ul>
+     */
+    public static final int UPDATE_ORIGIN_USER = 3;
+
+    /**
+     * The {@link ZenModeConfig} is being "independently" updated by an app, and not as a result of
+     * a user's action inside that app (for example, activating an {@link AutomaticZenRule} based on
+     * a previously set schedule).
+     */
+    public static final int UPDATE_ORIGIN_APP = 4;
+
+    /**
+     * The {@link ZenModeConfig} is being updated by the System or SystemUI. Note that this only
+     * includes cases where the call is coming from the System/SystemUI but the change is not due to
+     * a user action (e.g. automatically activating a schedule-based rule). If the change is a
+     * result of a user action (e.g. activating a rule by tapping on its QS tile) then
+     * {@link #UPDATE_ORIGIN_USER} is used instead.
+     */
+    public static final int UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI = 5;
+
+    /**
+     * The {@link ZenModeConfig} is being updated (replaced) because the user's DND configuration
+     * is being restored from a backup.
+     */
+    public static final int UPDATE_ORIGIN_RESTORE_BACKUP = 6;
+
+    @IntDef(prefix = { "UPDATE_ORIGIN_" }, value = {
+            UPDATE_ORIGIN_UNKNOWN,
+            UPDATE_ORIGIN_INIT,
+            UPDATE_ORIGIN_INIT_USER,
+            UPDATE_ORIGIN_USER,
+            UPDATE_ORIGIN_APP,
+            UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI,
+            UPDATE_ORIGIN_RESTORE_BACKUP
+    })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface ConfigChangeOrigin {}
 
     public static final int SOURCE_ANYONE = Policy.PRIORITY_SENDERS_ANY;
     public static final int SOURCE_CONTACT = Policy.PRIORITY_SENDERS_CONTACTS;
diff --git a/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java b/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java
index 9fdeda4..8855666 100644
--- a/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java
+++ b/services/core/java/com/android/server/notification/DefaultDeviceEffectsApplier.java
@@ -16,14 +16,23 @@
 
 package com.android.server.notification;
 
+import static android.app.UiModeManager.MODE_NIGHT_CUSTOM_TYPE_BEDTIME;
+
 import android.app.UiModeManager;
 import android.app.WallpaperManager;
+import android.content.BroadcastReceiver;
 import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.hardware.display.ColorDisplayManager;
 import android.os.Binder;
 import android.os.PowerManager;
 import android.service.notification.DeviceEffectsApplier;
 import android.service.notification.ZenDeviceEffects;
+import android.service.notification.ZenModeConfig;
+import android.service.notification.ZenModeConfig.ConfigChangeOrigin;
+
+import com.android.internal.annotations.GuardedBy;
 
 /** Default implementation for {@link DeviceEffectsApplier}. */
 class DefaultDeviceEffectsApplier implements DeviceEffectsApplier {
@@ -34,13 +43,24 @@
     private static final int SATURATION_LEVEL_FULL_COLOR = 100;
     private static final float WALLPAPER_DIM_AMOUNT_DIMMED = 0.6f;
     private static final float WALLPAPER_DIM_AMOUNT_NORMAL = 0f;
+    private static final IntentFilter SCREEN_OFF_INTENT_FILTER = new IntentFilter(
+            Intent.ACTION_SCREEN_OFF);
 
+    private final Context mContext;
     private final ColorDisplayManager mColorDisplayManager;
     private final PowerManager mPowerManager;
     private final UiModeManager mUiModeManager;
     private final WallpaperManager mWallpaperManager;
 
+    private final Object mRegisterReceiverLock = new Object();
+    @GuardedBy("mRegisterReceiverLock")
+    private boolean mIsScreenOffReceiverRegistered;
+
+    private ZenDeviceEffects mLastAppliedEffects = new ZenDeviceEffects.Builder().build();
+    private boolean mPendingNightMode;
+
     DefaultDeviceEffectsApplier(Context context) {
+        mContext = context;
         mColorDisplayManager = context.getSystemService(ColorDisplayManager.class);
         mPowerManager = context.getSystemService(PowerManager.class);
         mUiModeManager = context.getSystemService(UiModeManager.class);
@@ -48,24 +68,90 @@
     }
 
     @Override
-    public void apply(ZenDeviceEffects effects) {
+    public void apply(ZenDeviceEffects effects, @ConfigChangeOrigin int origin) {
         Binder.withCleanCallingIdentity(() -> {
-            mPowerManager.suppressAmbientDisplay(SUPPRESS_AMBIENT_DISPLAY_TOKEN,
-                    effects.shouldSuppressAmbientDisplay());
-
-            if (mColorDisplayManager != null) {
-                mColorDisplayManager.setSaturationLevel(
-                        effects.shouldDisplayGrayscale() ? SATURATION_LEVEL_GRAYSCALE
-                                : SATURATION_LEVEL_FULL_COLOR);
+            if (mLastAppliedEffects.shouldSuppressAmbientDisplay()
+                    != effects.shouldSuppressAmbientDisplay()) {
+                mPowerManager.suppressAmbientDisplay(SUPPRESS_AMBIENT_DISPLAY_TOKEN,
+                        effects.shouldSuppressAmbientDisplay());
             }
 
-            if (mWallpaperManager != null) {
-                mWallpaperManager.setWallpaperDimAmount(
-                        effects.shouldDimWallpaper() ? WALLPAPER_DIM_AMOUNT_DIMMED
-                                : WALLPAPER_DIM_AMOUNT_NORMAL);
+            if (mLastAppliedEffects.shouldDisplayGrayscale() != effects.shouldDisplayGrayscale()) {
+                if (mColorDisplayManager != null) {
+                    mColorDisplayManager.setSaturationLevel(
+                            effects.shouldDisplayGrayscale() ? SATURATION_LEVEL_GRAYSCALE
+                                    : SATURATION_LEVEL_FULL_COLOR);
+                }
             }
 
-            // TODO: b/308673343 - Apply dark theme (via UiModeManager) when screen is off.
+            if (mLastAppliedEffects.shouldDimWallpaper() != effects.shouldDimWallpaper()) {
+                if (mWallpaperManager != null) {
+                    mWallpaperManager.setWallpaperDimAmount(
+                            effects.shouldDimWallpaper() ? WALLPAPER_DIM_AMOUNT_DIMMED
+                                    : WALLPAPER_DIM_AMOUNT_NORMAL);
+                }
+            }
+
+            if (mLastAppliedEffects.shouldUseNightMode() != effects.shouldUseNightMode()) {
+                updateOrScheduleNightMode(effects.shouldUseNightMode(), origin);
+            }
         });
+
+        mLastAppliedEffects = effects;
+    }
+
+    private void updateOrScheduleNightMode(boolean useNightMode, @ConfigChangeOrigin int origin) {
+        mPendingNightMode = useNightMode;
+
+        // Changing the theme can be disruptive for the user (Activities are likely recreated, may
+        // lose some state). Therefore we only apply the change immediately if the rule was
+        // activated manually, or we are initializing, or the screen is currently off/dreaming.
+        if (origin == ZenModeConfig.UPDATE_ORIGIN_INIT
+                || origin == ZenModeConfig.UPDATE_ORIGIN_INIT_USER
+                || origin == ZenModeConfig.UPDATE_ORIGIN_USER
+                || origin == ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI
+                || !mPowerManager.isInteractive()) {
+            unregisterScreenOffReceiver();
+            updateNightModeImmediately(useNightMode);
+        } else {
+            registerScreenOffReceiver();
+        }
+    }
+
+    @GuardedBy("mRegisterReceiverLock")
+    private final BroadcastReceiver mNightModeWhenScreenOff = new BroadcastReceiver() {
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            unregisterScreenOffReceiver();
+            updateNightModeImmediately(mPendingNightMode);
+        }
+    };
+
+    private void updateNightModeImmediately(boolean useNightMode) {
+        Binder.withCleanCallingIdentity(() -> {
+            // TODO: b/314285749 - Placeholder; use real APIs when available.
+            mUiModeManager.setNightModeCustomType(MODE_NIGHT_CUSTOM_TYPE_BEDTIME);
+            mUiModeManager.setNightModeActivatedForCustomMode(MODE_NIGHT_CUSTOM_TYPE_BEDTIME,
+                    useNightMode);
+        });
+    }
+
+    private void registerScreenOffReceiver() {
+        synchronized (mRegisterReceiverLock) {
+            if (!mIsScreenOffReceiverRegistered) {
+                mContext.registerReceiver(mNightModeWhenScreenOff, SCREEN_OFF_INTENT_FILTER,
+                        Context.RECEIVER_NOT_EXPORTED);
+                mIsScreenOffReceiverRegistered = true;
+            }
+        }
+    }
+
+    private void unregisterScreenOffReceiver() {
+        synchronized (mRegisterReceiverLock) {
+            if (mIsScreenOffReceiverRegistered) {
+                mIsScreenOffReceiverRegistered = false;
+                mContext.unregisterReceiver(mNightModeWhenScreenOff);
+            }
+        }
     }
 }
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 02845fb..c2a145d 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -5299,11 +5299,11 @@
         public void setZenMode(int mode, Uri conditionId, String reason) throws RemoteException {
             enforceSystemOrSystemUI("INotificationManager.setZenMode");
             final int callingUid = Binder.getCallingUid();
-            final boolean isSystemOrSystemUi = isCallerSystemOrSystemUi();
             final long identity = Binder.clearCallingIdentity();
             try {
-                mZenModeHelper.setManualZenMode(mode, conditionId, null, reason, callingUid,
-                        isSystemOrSystemUi);
+                mZenModeHelper.setManualZenMode(mode, conditionId,
+                        ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, // Checked by enforce()
+                        reason, /* caller= */ null, callingUid);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -5360,10 +5360,11 @@
             }
 
             return mZenModeHelper.addAutomaticZenRule(rulePkg, automaticZenRule,
-                    "addAutomaticZenRule", Binder.getCallingUid(),
-                    // TODO: b/308670715: Distinguish FROM_APP from FROM_USER
-                    isCallerSystemOrSystemUi() ? ZenModeHelper.FROM_SYSTEM_OR_SYSTEMUI
-                            : ZenModeHelper.FROM_APP);
+                    // TODO: b/308670715: Distinguish origin properly (e.g. USER if creating a rule
+                    //  manually in Settings).
+                    isCallerSystemOrSystemUi() ? ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI
+                            : ZenModeConfig.UPDATE_ORIGIN_APP,
+                    "addAutomaticZenRule", Binder.getCallingUid());
         }
 
         @Override
@@ -5379,11 +5380,12 @@
             Objects.requireNonNull(automaticZenRule.getConditionId(), "ConditionId is null");
             enforcePolicyAccess(Binder.getCallingUid(), "updateAutomaticZenRule");
 
+            // TODO: b/308670715: Distinguish origin properly (e.g. USER if updating a rule
+            //  manually in Settings).
             return mZenModeHelper.updateAutomaticZenRule(id, automaticZenRule,
-                    "updateAutomaticZenRule", Binder.getCallingUid(),
-                    // TODO: b/308670715: Distinguish FROM_APP from FROM_USER
-                    isCallerSystemOrSystemUi() ? ZenModeHelper.FROM_SYSTEM_OR_SYSTEMUI
-                            : ZenModeHelper.FROM_APP);
+                    isCallerSystemOrSystemUi() ? ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI
+                            : ZenModeConfig.UPDATE_ORIGIN_APP,
+                    "updateAutomaticZenRule", Binder.getCallingUid());
         }
 
         @Override
@@ -5392,8 +5394,12 @@
             // Verify that they can modify zen rules.
             enforcePolicyAccess(Binder.getCallingUid(), "removeAutomaticZenRule");
 
-            return mZenModeHelper.removeAutomaticZenRule(id, "removeAutomaticZenRule",
-                    Binder.getCallingUid(), isCallerSystemOrSystemUi());
+            // TODO: b/308670715: Distinguish origin properly (e.g. USER if removing a rule
+            //  manually in Settings).
+            return mZenModeHelper.removeAutomaticZenRule(id,
+                    isCallerSystemOrSystemUi() ? ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI
+                            : ZenModeConfig.UPDATE_ORIGIN_APP,
+                    "removeAutomaticZenRule", Binder.getCallingUid());
         }
 
         @Override
@@ -5402,8 +5408,9 @@
             enforceSystemOrSystemUI("removeAutomaticZenRules");
 
             return mZenModeHelper.removeAutomaticZenRules(packageName,
-                    packageName + "|removeAutomaticZenRules", Binder.getCallingUid(),
-                    isCallerSystemOrSystemUi());
+                    isCallerSystemOrSystemUi() ? ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI
+                            : ZenModeConfig.UPDATE_ORIGIN_APP,
+                    packageName + "|removeAutomaticZenRules", Binder.getCallingUid());
         }
 
         @Override
@@ -5421,8 +5428,12 @@
 
             enforcePolicyAccess(Binder.getCallingUid(), "setAutomaticZenRuleState");
 
-            mZenModeHelper.setAutomaticZenRuleState(id, condition, Binder.getCallingUid(),
-                    isCallerSystemOrSystemUi());
+            // TODO: b/308670715: Distinguish origin properly (e.g. USER if toggling a rule
+            //  manually in Settings).
+            mZenModeHelper.setAutomaticZenRuleState(id, condition,
+                    isCallerSystemOrSystemUi() ? ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI
+                            : ZenModeConfig.UPDATE_ORIGIN_APP,
+                    Binder.getCallingUid());
         }
 
         @Override
@@ -5440,8 +5451,11 @@
 
             final long identity = Binder.clearCallingIdentity();
             try {
-                mZenModeHelper.setManualZenMode(zen, null, pkg, "setInterruptionFilter",
-                        callingUid, isSystemOrSystemUi);
+                mZenModeHelper.setManualZenMode(zen, null,
+                        isSystemOrSystemUi ? ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI
+                                : ZenModeConfig.UPDATE_ORIGIN_APP,
+                        /* reason= */ "setInterruptionFilter", /* caller= */ pkg,
+                        callingUid);
             } finally {
                 Binder.restoreCallingIdentity(identity);
             }
@@ -5806,7 +5820,10 @@
                 } else {
                     ZenLog.traceSetNotificationPolicy(pkg, applicationInfo.targetSdkVersion,
                             policy);
-                    mZenModeHelper.setNotificationPolicy(policy, callingUid, isSystemOrSystemUi);
+                    mZenModeHelper.setNotificationPolicy(policy,
+                            isSystemOrSystemUi ? ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI
+                                    : ZenModeConfig.UPDATE_ORIGIN_APP,
+                            callingUid);
                 }
             } catch (RemoteException e) {
                 Slog.e(TAG, "Failed to set notification policy", e);
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 6a7eebb..fd86870 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -59,6 +59,7 @@
 import android.service.notification.ConversationChannelWrapper;
 import android.service.notification.NotificationListenerService;
 import android.service.notification.RankingHelperProto;
+import android.service.notification.ZenModeConfig;
 import android.text.TextUtils;
 import android.text.format.DateUtils;
 import android.util.ArrayMap;
@@ -1862,12 +1863,16 @@
     public void updateZenPolicy(boolean areChannelsBypassingDnd, int callingUid,
             boolean fromSystemOrSystemUi) {
         NotificationManager.Policy policy = mZenModeHelper.getNotificationPolicy();
-        mZenModeHelper.setNotificationPolicy(new NotificationManager.Policy(
-                policy.priorityCategories, policy.priorityCallSenders,
-                policy.priorityMessageSenders, policy.suppressedVisualEffects,
-                (areChannelsBypassingDnd ? NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND
-                        : 0),
-                policy.priorityConversationSenders), callingUid, fromSystemOrSystemUi);
+        mZenModeHelper.setNotificationPolicy(
+                new NotificationManager.Policy(
+                        policy.priorityCategories, policy.priorityCallSenders,
+                        policy.priorityMessageSenders, policy.suppressedVisualEffects,
+                        (areChannelsBypassingDnd
+                                ? NotificationManager.Policy.STATE_CHANNELS_BYPASSING_DND : 0),
+                        policy.priorityConversationSenders),
+                fromSystemOrSystemUi ? ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI
+                        : ZenModeConfig.UPDATE_ORIGIN_APP,
+                callingUid);
     }
 
     // TODO: b/310620812 - rename to hasPriorityChannels() when modes_api is inlined.
diff --git a/services/core/java/com/android/server/notification/ZenModeConditions.java b/services/core/java/com/android/server/notification/ZenModeConditions.java
index 6ecd799..86aa2d8 100644
--- a/services/core/java/com/android/server/notification/ZenModeConditions.java
+++ b/services/core/java/com/android/server/notification/ZenModeConditions.java
@@ -111,8 +111,10 @@
     public void onServiceAdded(ComponentName component) {
         if (DEBUG) Log.d(TAG, "onServiceAdded " + component);
         final int callingUid = Binder.getCallingUid();
-        mHelper.setConfig(mHelper.getConfig(), component, "zmc.onServiceAdded:" + component,
-                callingUid, callingUid == Process.SYSTEM_UID);
+        mHelper.setConfig(mHelper.getConfig(), component,
+                callingUid == Process.SYSTEM_UID ? ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI
+                        : ZenModeConfig.UPDATE_ORIGIN_APP,
+                "zmc.onServiceAdded:" + component, callingUid);
     }
 
     @Override
@@ -121,8 +123,10 @@
         ZenModeConfig config = mHelper.getConfig();
         if (config == null) return;
         final int callingUid = Binder.getCallingUid();
-        mHelper.setAutomaticZenRuleState(id, condition, callingUid,
-                callingUid == Process.SYSTEM_UID);
+        mHelper.setAutomaticZenRuleState(id, condition,
+                callingUid == Process.SYSTEM_UID ? ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI
+                        : ZenModeConfig.UPDATE_ORIGIN_APP,
+                callingUid);
     }
 
     // Only valid for CPS backed rules
diff --git a/services/core/java/com/android/server/notification/ZenModeHelper.java b/services/core/java/com/android/server/notification/ZenModeHelper.java
index 218519f..7ec94c3 100644
--- a/services/core/java/com/android/server/notification/ZenModeHelper.java
+++ b/services/core/java/com/android/server/notification/ZenModeHelper.java
@@ -1,4 +1,4 @@
-/**
+/*
  * Copyright (c) 2014, The Android Open Source Project
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
@@ -24,11 +24,16 @@
 import static android.app.NotificationManager.AUTOMATIC_RULE_STATUS_UNKNOWN;
 import static android.app.NotificationManager.Policy.PRIORITY_SENDERS_ANY;
 import static android.service.notification.NotificationServiceProto.ROOT_CONFIG;
+import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_APP;
+import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_INIT;
+import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_INIT_USER;
+import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_RESTORE_BACKUP;
+import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI;
+import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_USER;
 
 import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE;
 
 import android.annotation.DrawableRes;
-import android.annotation.IntDef;
 import android.annotation.NonNull;
 import android.annotation.Nullable;
 import android.annotation.SuppressLint;
@@ -79,6 +84,7 @@
 import android.service.notification.DeviceEffectsApplier;
 import android.service.notification.ZenDeviceEffects;
 import android.service.notification.ZenModeConfig;
+import android.service.notification.ZenModeConfig.ConfigChangeOrigin;
 import android.service.notification.ZenModeConfig.ZenRule;
 import android.service.notification.ZenModeProto;
 import android.service.notification.ZenPolicy;
@@ -111,8 +117,6 @@
 
 import java.io.IOException;
 import java.io.PrintWriter;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
 import java.util.ArrayList;
 import java.util.HashMap;
 import java.util.List;
@@ -137,21 +141,6 @@
     @EnabledSince(targetSdkVersion = Build.VERSION_CODES.VANILLA_ICE_CREAM)
     static final long SEND_ACTIVATION_AZR_STATUSES = 308673617L;
 
-    /** A rule addition or update that is initiated by the System or SystemUI. */
-    static final int FROM_SYSTEM_OR_SYSTEMUI = 1;
-    /** A rule addition or update that is initiated by the user (through system settings). */
-    static final int FROM_USER = 2;
-    /** A rule addition or update that is initiated by an app (via NotificationManager APIs). */
-    static final int FROM_APP = 3;
-
-    @IntDef(prefix = { "FROM_" }, value = {
-            FROM_SYSTEM_OR_SYSTEMUI,
-            FROM_USER,
-            FROM_APP
-    })
-    @Retention(RetentionPolicy.SOURCE)
-    @interface ChangeOrigin {}
-
     // pkg|userId => uid
     @VisibleForTesting protected final ArrayMap<String, Integer> mRulesUidCache = new ArrayMap<>();
 
@@ -160,7 +149,7 @@
     private final SettingsObserver mSettingsObserver;
     private final AppOpsManager mAppOps;
     private final NotificationManager mNotificationManager;
-    private ZenModeConfig mDefaultConfig;
+    private final ZenModeConfig mDefaultConfig;
     private final ArrayList<Callback> mCallbacks = new ArrayList<Callback>();
     private final ZenModeFiltering mFiltering;
     private final RingerModeDelegate mRingerModeDelegate = new
@@ -275,9 +264,8 @@
             // "update" config to itself, which will have no effect in the case where a config
             // was read in via XML, but will initialize zen mode if nothing was read in and the
             // config remains the default.
-            updateConfigAndZenModeLocked(mConfig, "init", true /*setRingerMode*/,
-                    Process.SYSTEM_UID /* callingUid */, true /* is system */,
-                    false /* no broadcasts*/);
+            updateConfigAndZenModeLocked(mConfig, UPDATE_ORIGIN_INIT, "init",
+                    true /*setRingerMode*/, Process.SYSTEM_UID /* callingUid */);
         }
     }
 
@@ -297,24 +285,20 @@
     /**
      * Set the {@link DeviceEffectsApplier} used to apply the consolidated effects.
      *
-     * <p>If effects were calculated previously (for example, when we loaded a {@link ZenModeConfig}
-     * that includes activated rules), they will be applied immediately.
+     * <p>Previously calculated effects (as loaded from the user's {@link ZenModeConfig}) will be
+     * applied immediately.
      */
     void setDeviceEffectsApplier(@NonNull DeviceEffectsApplier deviceEffectsApplier) {
         if (!Flags.modesApi()) {
             return;
         }
-        ZenDeviceEffects consolidatedDeviceEffects;
         synchronized (mConfigLock) {
             if (mDeviceEffectsApplier != null) {
                 throw new IllegalStateException("Already set up a DeviceEffectsApplier!");
             }
             mDeviceEffectsApplier = deviceEffectsApplier;
-            consolidatedDeviceEffects = mConsolidatedDeviceEffects;
         }
-        if (consolidatedDeviceEffects.hasEffects()) {
-            applyConsolidatedDeviceEffects();
-        }
+        applyConsolidatedDeviceEffects(UPDATE_ORIGIN_INIT);
     }
 
     public void onUserSwitched(int user) {
@@ -353,7 +337,8 @@
             config.user = user;
         }
         synchronized (mConfigLock) {
-            setConfigLocked(config, null, reason, Process.SYSTEM_UID, true);
+            setConfigLocked(config, null, UPDATE_ORIGIN_INIT_USER, reason,
+                    Process.SYSTEM_UID);
         }
         cleanUpZenRules();
     }
@@ -366,9 +351,11 @@
             boolean fromSystemOrSystemUi) {
         final int newZen = NotificationManager.zenModeFromInterruptionFilter(filter, -1);
         if (newZen != -1) {
-            setManualZenMode(newZen, null, name != null ? name.getPackageName() : null,
-                    "listener:" + (name != null ? name.flattenToShortString() : null),
-                    callingUid, fromSystemOrSystemUi);
+            setManualZenMode(newZen, null,
+                    fromSystemOrSystemUi ? UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI : UPDATE_ORIGIN_APP,
+                    /* reason= */ "listener:" + (name != null ? name.flattenToShortString() : null),
+                    /* caller= */ name != null ? name.getPackageName() : null,
+                    callingUid);
         }
     }
 
@@ -428,7 +415,7 @@
     }
 
     public String addAutomaticZenRule(String pkg, AutomaticZenRule automaticZenRule,
-            String reason, int callingUid, @ChangeOrigin int origin) {
+            @ConfigChangeOrigin int origin, String reason, int callingUid) {
         if (!ZenModeConfig.SYSTEM_AUTHORITY.equals(pkg)) {
             PackageItemInfo component = getServiceInfo(automaticZenRule.getOwner());
             if (component == null) {
@@ -462,10 +449,9 @@
             }
             newConfig = mConfig.copy();
             ZenRule rule = new ZenRule();
-            populateZenRule(pkg, automaticZenRule, rule, true, origin);
+            populateZenRule(pkg, automaticZenRule, rule, origin, /* isNew= */ true);
             newConfig.automaticRules.put(rule.id, rule);
-            if (setConfigLocked(newConfig, reason, rule.component, true, callingUid,
-                    origin == FROM_SYSTEM_OR_SYSTEMUI)) {
+            if (setConfigLocked(newConfig, origin, reason, rule.component, true, callingUid)) {
                 return rule.id;
             } else {
                 throw new AndroidRuntimeException("Could not create rule");
@@ -474,7 +460,7 @@
     }
 
     public boolean updateAutomaticZenRule(String ruleId, AutomaticZenRule automaticZenRule,
-            String reason, int callingUid, @ChangeOrigin int origin) {
+            @ConfigChangeOrigin int origin, String reason, int callingUid) {
         ZenModeConfig newConfig;
         synchronized (mConfigLock) {
             if (mConfig == null) return false;
@@ -502,9 +488,9 @@
                 }
             }
 
-            populateZenRule(rule.pkg, automaticZenRule, rule, false, origin);
-            return setConfigLocked(newConfig, reason, rule.component, true, callingUid,
-                    origin == FROM_SYSTEM_OR_SYSTEMUI);
+            populateZenRule(rule.pkg, automaticZenRule, rule, origin, /* isNew= */ false);
+            return setConfigLocked(newConfig, origin, reason,
+                    rule.component, true, callingUid);
         }
     }
 
@@ -541,8 +527,7 @@
                     Condition deactivated = new Condition(rule.conditionId,
                             mContext.getString(R.string.zen_mode_implicit_deactivated),
                             Condition.STATE_FALSE);
-                    setAutomaticZenRuleState(rule.id, deactivated,
-                            callingUid, /* fromSystemOrSystemUi= */ false);
+                    setAutomaticZenRuleState(rule.id, deactivated, UPDATE_ORIGIN_APP, callingUid);
                 }
             } else {
                 // Either create a new rule with a default ZenPolicy, or update an existing rule's
@@ -558,9 +543,8 @@
                 rule.condition = new Condition(rule.conditionId,
                         mContext.getString(R.string.zen_mode_implicit_activated),
                         Condition.STATE_TRUE);
-                setConfigLocked(newConfig, /* triggeringComponent= */ null,
-                        "applyGlobalZenModeAsImplicitZenRule",
-                        callingUid, /* fromSystemOrSystemUi= */ false);
+                setConfigLocked(newConfig, /* triggeringComponent= */ null, UPDATE_ORIGIN_APP,
+                        "applyGlobalZenModeAsImplicitZenRule", callingUid);
             }
         }
     }
@@ -595,9 +579,8 @@
             }
             // TODO: b/308673679 - Keep user customization of this rule!
             rule.zenPolicy = ZenAdapters.notificationPolicyToZenPolicy(policy);
-            setConfigLocked(newConfig, /* triggeringComponent= */ null,
-                    "applyGlobalPolicyAsImplicitZenRule",
-                    callingUid, /* fromSystemOrSystemUi= */ false);
+            setConfigLocked(newConfig, /* triggeringComponent= */ null, UPDATE_ORIGIN_APP,
+                    "applyGlobalPolicyAsImplicitZenRule", callingUid);
         }
     }
 
@@ -669,8 +652,8 @@
         return "implicit_" + forPackage;
     }
 
-    public boolean removeAutomaticZenRule(String id, String reason, int callingUid,
-            boolean fromSystemOrSystemUi) {
+    boolean removeAutomaticZenRule(String id, @ConfigChangeOrigin int origin, String reason,
+            int callingUid) {
         ZenModeConfig newConfig;
         synchronized (mConfigLock) {
             if (mConfig == null) return false;
@@ -695,13 +678,12 @@
             }
             dispatchOnAutomaticRuleStatusChanged(
                     mConfig.user, ruleToRemove.getPkg(), id, AUTOMATIC_RULE_STATUS_REMOVED);
-            return setConfigLocked(newConfig, reason, null, true, callingUid,
-                    fromSystemOrSystemUi);
+            return setConfigLocked(newConfig, origin, reason, null, true, callingUid);
         }
     }
 
-    public boolean removeAutomaticZenRules(String packageName, String reason, int callingUid,
-            boolean fromSystemOrSystemUi) {
+    boolean removeAutomaticZenRules(String packageName, @ConfigChangeOrigin int origin,
+            String reason, int callingUid) {
         ZenModeConfig newConfig;
         synchronized (mConfigLock) {
             if (mConfig == null) return false;
@@ -712,13 +694,12 @@
                     newConfig.automaticRules.removeAt(i);
                 }
             }
-            return setConfigLocked(newConfig, reason, null, true, callingUid,
-                    fromSystemOrSystemUi);
+            return setConfigLocked(newConfig, origin, reason, null, true, callingUid);
         }
     }
 
-    public void setAutomaticZenRuleState(String id, Condition condition, int callingUid,
-            boolean fromSystemOrSystemUi) {
+    void setAutomaticZenRuleState(String id, Condition condition, @ConfigChangeOrigin int origin,
+            int callingUid) {
         ZenModeConfig newConfig;
         synchronized (mConfigLock) {
             if (mConfig == null) return;
@@ -726,13 +707,12 @@
             newConfig = mConfig.copy();
             ArrayList<ZenRule> rules = new ArrayList<>();
             rules.add(newConfig.automaticRules.get(id));
-            setAutomaticZenRuleStateLocked(newConfig, rules, condition, callingUid,
-                    fromSystemOrSystemUi);
+            setAutomaticZenRuleStateLocked(newConfig, rules, condition, origin, callingUid);
         }
     }
 
-    public void setAutomaticZenRuleState(Uri ruleDefinition, Condition condition, int callingUid,
-            boolean fromSystemOrSystemUi) {
+    void setAutomaticZenRuleState(Uri ruleDefinition, Condition condition,
+            @ConfigChangeOrigin int origin, int callingUid) {
         ZenModeConfig newConfig;
         synchronized (mConfigLock) {
             if (mConfig == null) return;
@@ -740,20 +720,23 @@
 
             setAutomaticZenRuleStateLocked(newConfig,
                     findMatchingRules(newConfig, ruleDefinition, condition),
-                    condition, callingUid, fromSystemOrSystemUi);
+                    condition, origin, callingUid);
         }
     }
 
     @GuardedBy("mConfigLock")
     private void setAutomaticZenRuleStateLocked(ZenModeConfig config, List<ZenRule> rules,
-            Condition condition, int callingUid, boolean fromSystemOrSystemUi) {
+            Condition condition, @ConfigChangeOrigin int origin, int callingUid) {
         if (rules == null || rules.isEmpty()) return;
 
+        if (Flags.modesApi() && condition.source == Condition.SOURCE_USER_ACTION) {
+            origin = UPDATE_ORIGIN_USER; // Although coming from app, it's actually a user action.
+        }
+
         for (ZenRule rule : rules) {
             rule.condition = condition;
             updateSnoozing(rule);
-            setConfigLocked(config, rule.component, "conditionChanged", callingUid,
-                    fromSystemOrSystemUi);
+            setConfigLocked(config, rule.component, origin, "conditionChanged", callingUid);
         }
     }
 
@@ -857,7 +840,7 @@
                         // update default rule (if locale changed, name of rule will change)
                         currRule.name = defaultRule.name;
                         updateAutomaticZenRule(defaultRule.id, zenRuleToAutomaticZenRule(currRule),
-                                "locale changed", callingUid, FROM_SYSTEM_OR_SYSTEMUI);
+                                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "locale changed", callingUid);
                     }
                 }
             }
@@ -899,13 +882,12 @@
         return null;
     }
 
-    @VisibleForTesting
     void populateZenRule(String pkg, AutomaticZenRule automaticZenRule, ZenRule rule,
-            boolean isNew, @ChangeOrigin int origin) {
-            // TODO: b/308671593,b/311406021 - Handle origins more precisely:
-            //  - FROM_USER can override anything and updates bitmask of user-modified fields;
-            //  - FROM_SYSTEM_OR_SYSTEMUI can override anything and preserves bitmask;
-            //  - FROM_APP can only update if not user-modified.
+            @ConfigChangeOrigin int origin, boolean isNew) {
+        // TODO: b/308671593,b/311406021 - Handle origins more precisely:
+        //  - USER can override anything and updates bitmask of user-modified fields;
+        //  - SYSTEM_OR_SYSTEMUI can override anything and preserves bitmask;
+        //  - APP can only update if not user-modified.
         if (rule.enabled != automaticZenRule.isEnabled()) {
             rule.snoozing = false;
         }
@@ -951,12 +933,12 @@
      */
     @Nullable
     private static ZenDeviceEffects fixZenDeviceEffects(@Nullable ZenDeviceEffects oldEffects,
-            @Nullable ZenDeviceEffects newEffects, @ChangeOrigin int origin) {
+            @Nullable ZenDeviceEffects newEffects, @ConfigChangeOrigin int origin) {
         // TODO: b/308671593,b/311406021 - Handle origins more precisely:
-        //  - FROM_USER can override anything and updates bitmask of user-modified fields;
-        //  - FROM_SYSTEM_OR_SYSTEMUI can override anything and preserves bitmask;
-        //  - FROM_APP can only update if not user-modified.
-        if (origin == FROM_SYSTEM_OR_SYSTEMUI || origin == FROM_USER) {
+        //  - USER can override anything and updates bitmask of user-modified fields;
+        //  - SYSTEM_OR_SYSTEMUI can override anything and preserves bitmask;
+        //  - APP can only update if not user-modified.
+        if (origin != UPDATE_ORIGIN_APP) {
             return newEffects;
         }
 
@@ -1033,16 +1015,16 @@
                 : AUTOMATIC_RULE_STATUS_DISABLED);
     }
 
-    public void setManualZenMode(int zenMode, Uri conditionId, String caller, String reason,
-            int callingUid, boolean fromSystemOrSystemUi) {
-        setManualZenMode(zenMode, conditionId, reason, caller, true /*setRingerMode*/, callingUid,
-                fromSystemOrSystemUi);
+    void setManualZenMode(int zenMode, Uri conditionId, @ConfigChangeOrigin int origin,
+            String reason, @Nullable String caller, int callingUid) {
+        setManualZenMode(zenMode, conditionId, origin, reason, caller, true /*setRingerMode*/,
+                callingUid);
         Settings.Secure.putInt(mContext.getContentResolver(),
                 Settings.Secure.SHOW_ZEN_SETTINGS_SUGGESTION, 0);
     }
 
-    private void setManualZenMode(int zenMode, Uri conditionId, String reason, String caller,
-            boolean setRingerMode, int callingUid, boolean fromSystemOrSystemUi) {
+    private void setManualZenMode(int zenMode, Uri conditionId, @ConfigChangeOrigin int origin,
+            String reason, @Nullable String caller, boolean setRingerMode, int callingUid) {
         ZenModeConfig newConfig;
         synchronized (mConfigLock) {
             if (mConfig == null) return;
@@ -1069,8 +1051,7 @@
                 }
                 newConfig.manualRule = newRule;
             }
-            setConfigLocked(newConfig, reason, null, setRingerMode, callingUid,
-                    fromSystemOrSystemUi);
+            setConfigLocked(newConfig, origin, reason, null, setRingerMode, callingUid);
         }
     }
 
@@ -1199,7 +1180,9 @@
             }
             if (DEBUG) Log.d(TAG, reason);
             synchronized (mConfigLock) {
-                setConfigLocked(config, null, reason, Process.SYSTEM_UID, true);
+                setConfigLocked(config, null,
+                        forRestore ? UPDATE_ORIGIN_RESTORE_BACKUP : UPDATE_ORIGIN_INIT, reason,
+                        Process.SYSTEM_UID);
             }
         }
     }
@@ -1233,13 +1216,13 @@
     /**
      * Sets the global notification policy used for priority only do not disturb
      */
-    public void setNotificationPolicy(Policy policy, int callingUid, boolean fromSystemOrSystemUi) {
+    public void setNotificationPolicy(Policy policy, @ConfigChangeOrigin int origin,
+            int callingUid) {
         synchronized (mConfigLock) {
             if (policy == null || mConfig == null) return;
             final ZenModeConfig newConfig = mConfig.copy();
             newConfig.applyNotificationPolicy(policy);
-            setConfigLocked(newConfig, null, "setNotificationPolicy", callingUid,
-                    fromSystemOrSystemUi);
+            setConfigLocked(newConfig, null, origin, "setNotificationPolicy", callingUid);
         }
     }
 
@@ -1264,8 +1247,8 @@
                     }
                 }
             }
-            setConfigLocked(newConfig, null, "cleanUpZenRules", Process.SYSTEM_UID,
-                    true);
+            setConfigLocked(newConfig, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "cleanUpZenRules",
+                    Process.SYSTEM_UID);
         }
     }
 
@@ -1287,22 +1270,22 @@
 
     @GuardedBy("mConfigLock")
     private boolean setConfigLocked(ZenModeConfig config, ComponentName triggeringComponent,
-            String reason, int callingUid, boolean fromSystemOrSystemUi) {
-        return setConfigLocked(config, reason, triggeringComponent, true /*setRingerMode*/,
-                callingUid, fromSystemOrSystemUi);
+            @ConfigChangeOrigin int origin, String reason, int callingUid) {
+        return setConfigLocked(config, origin, reason, triggeringComponent, true /*setRingerMode*/,
+                callingUid);
     }
 
-    public void setConfig(ZenModeConfig config, ComponentName triggeringComponent, String reason,
-            int callingUid, boolean fromSystemOrSystemUi) {
+    void setConfig(ZenModeConfig config, ComponentName triggeringComponent,
+            @ConfigChangeOrigin int origin, String reason, int callingUid) {
         synchronized (mConfigLock) {
-            setConfigLocked(config, triggeringComponent, reason, callingUid, fromSystemOrSystemUi);
+            setConfigLocked(config, triggeringComponent, origin, reason, callingUid);
         }
     }
 
     @GuardedBy("mConfigLock")
-    private boolean setConfigLocked(ZenModeConfig config, String reason,
-            ComponentName triggeringComponent, boolean setRingerMode, int callingUid,
-            boolean fromSystemOrSystemUi) {
+    private boolean setConfigLocked(ZenModeConfig config, @ConfigChangeOrigin int origin,
+            String reason, ComponentName triggeringComponent, boolean setRingerMode,
+            int callingUid) {
         final long identity = Binder.clearCallingIdentity();
         try {
             if (config == null || !config.isValid()) {
@@ -1332,8 +1315,7 @@
             if (policyChanged) {
                 dispatchOnPolicyChanged();
             }
-            updateConfigAndZenModeLocked(config, reason, setRingerMode, callingUid,
-                    fromSystemOrSystemUi, true);
+            updateConfigAndZenModeLocked(config, origin, reason, setRingerMode, callingUid);
             mConditions.evaluateConfig(config, triggeringComponent, true /*processSubscriptions*/);
             return true;
         } catch (SecurityException e) {
@@ -1349,17 +1331,16 @@
      * If logging is enabled, will also request logging of the outcome of this change if needed.
      */
     @GuardedBy("mConfigLock")
-    private void updateConfigAndZenModeLocked(ZenModeConfig config, String reason,
-            boolean setRingerMode, int callingUid, boolean fromSystemOrSystemUi,
-            boolean sendBroadcasts) {
+    private void updateConfigAndZenModeLocked(ZenModeConfig config, @ConfigChangeOrigin int origin,
+            String reason, boolean setRingerMode, int callingUid) {
         final boolean logZenModeEvents = mFlagResolver.isEnabled(
                 SystemUiSystemPropertiesFlags.NotificationFlags.LOG_DND_STATE_EVENTS);
         // Store (a copy of) all config and zen mode info prior to any changes taking effect
         ZenModeEventLogger.ZenModeInfo prevInfo = new ZenModeEventLogger.ZenModeInfo(
                 mZenMode, mConfig, mConsolidatedPolicy);
         if (!config.equals(mConfig)) {
-            // schedule broadcasts
-            if (Flags.modesApi() && sendBroadcasts) {
+            // Schedule broadcasts. Cannot be sent during boot, though.
+            if (Flags.modesApi() && origin != UPDATE_ORIGIN_INIT) {
                 for (ZenRule rule : config.automaticRules.values()) {
                     ZenRule original = mConfig.automaticRules.get(rule.id);
                     if (original != null) {
@@ -1377,15 +1358,19 @@
 
             mConfig = config;
             dispatchOnConfigChanged();
-            updateAndApplyConsolidatedPolicyAndDeviceEffects(reason);
+            updateAndApplyConsolidatedPolicyAndDeviceEffects(origin, reason);
         }
         final String val = Integer.toString(config.hashCode());
         Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_CONFIG_ETAG, val);
-        evaluateZenModeLocked(reason, setRingerMode);
+        evaluateZenModeLocked(origin, reason, setRingerMode);
         // After all changes have occurred, log if requested
         if (logZenModeEvents) {
             ZenModeEventLogger.ZenModeInfo newInfo = new ZenModeEventLogger.ZenModeInfo(
                     mZenMode, mConfig, mConsolidatedPolicy);
+            boolean fromSystemOrSystemUi = origin == UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI
+                    || origin == UPDATE_ORIGIN_INIT
+                    || origin == UPDATE_ORIGIN_INIT_USER
+                    || origin == UPDATE_ORIGIN_RESTORE_BACKUP;
             mZenModeEventLogger.maybeLogZenChange(prevInfo, newInfo, callingUid,
                     fromSystemOrSystemUi);
         }
@@ -1416,7 +1401,8 @@
 
     @VisibleForTesting
     @GuardedBy("mConfigLock")
-    protected void evaluateZenModeLocked(String reason, boolean setRingerMode) {
+    protected void evaluateZenModeLocked(@ConfigChangeOrigin int origin, String reason,
+            boolean setRingerMode) {
         if (DEBUG) Log.d(TAG, "evaluateZenMode");
         if (mConfig == null) return;
         final int policyHashBefore = mConsolidatedPolicy == null ? 0
@@ -1426,7 +1412,7 @@
         ZenLog.traceSetZenMode(zen, reason);
         mZenMode = zen;
         setZenModeSetting(mZenMode);
-        updateAndApplyConsolidatedPolicyAndDeviceEffects(reason);
+        updateAndApplyConsolidatedPolicyAndDeviceEffects(origin, reason);
         boolean shouldApplyToRinger = setRingerMode && (zen != zenBefore || (
                 zen == Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS
                         && policyHashBefore != mConsolidatedPolicy.hashCode()));
@@ -1468,6 +1454,7 @@
         }
     }
 
+    @GuardedBy("mConfigLock")
     private void applyCustomPolicy(ZenPolicy policy, ZenRule rule) {
         if (rule.zenMode == Global.ZEN_MODE_NO_INTERRUPTIONS) {
             policy.apply(new ZenPolicy.Builder()
@@ -1487,7 +1474,9 @@
         }
     }
 
-    private void updateAndApplyConsolidatedPolicyAndDeviceEffects(String reason) {
+    @GuardedBy("mConfigLock")
+    private void updateAndApplyConsolidatedPolicyAndDeviceEffects(@ConfigChangeOrigin int origin,
+            String reason) {
         synchronized (mConfigLock) {
             if (mConfig == null) return;
             ZenPolicy policy = new ZenPolicy();
@@ -1519,13 +1508,13 @@
                 ZenDeviceEffects deviceEffects = deviceEffectsBuilder.build();
                 if (!deviceEffects.equals(mConsolidatedDeviceEffects)) {
                     mConsolidatedDeviceEffects = deviceEffects;
-                    mHandler.postApplyDeviceEffects();
+                    mHandler.postApplyDeviceEffects(origin);
                 }
             }
         }
     }
 
-    private void applyConsolidatedDeviceEffects() {
+    private void applyConsolidatedDeviceEffects(@ConfigChangeOrigin int source) {
         if (!Flags.modesApi()) {
             return;
         }
@@ -1536,7 +1525,7 @@
             effects = mConsolidatedDeviceEffects;
         }
         if (applier != null) {
-            applier.apply(effects);
+            applier.apply(effects, source);
         }
     }
 
@@ -1801,8 +1790,8 @@
         }
 
         @Override
-        public int onSetRingerModeInternal(int ringerModeOld, int ringerModeNew, String caller,
-                int ringerModeExternal, VolumePolicy policy) {
+        public int onSetRingerModeInternal(int ringerModeOld, int ringerModeNew,
+                @Nullable String caller, int ringerModeExternal, VolumePolicy policy) {
             final boolean isChange = ringerModeOld != ringerModeNew;
 
             int ringerModeExternalOut = ringerModeNew;
@@ -1839,8 +1828,9 @@
             }
 
             if (newZen != -1) {
-                setManualZenMode(newZen, null, "ringerModeInternal", null,
-                        false /*setRingerMode*/, Process.SYSTEM_UID, true);
+                setManualZenMode(newZen, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI,
+                        "ringerModeInternal", /* caller= */ null, /* setRingerMode= */ false,
+                        Process.SYSTEM_UID);
             }
             if (isChange || newZen != -1 || ringerModeExternal != ringerModeExternalOut) {
                 ZenLog.traceSetRingerModeInternal(ringerModeOld, ringerModeNew, caller,
@@ -1856,8 +1846,8 @@
         }
 
         @Override
-        public int onSetRingerModeExternal(int ringerModeOld, int ringerModeNew, String caller,
-                int ringerModeInternal, VolumePolicy policy) {
+        public int onSetRingerModeExternal(int ringerModeOld, int ringerModeNew,
+                @Nullable String caller, int ringerModeInternal, VolumePolicy policy) {
             int ringerModeInternalOut = ringerModeNew;
             final boolean isChange = ringerModeOld != ringerModeNew;
             final boolean isVibrate = ringerModeInternal == AudioManager.RINGER_MODE_VIBRATE;
@@ -1883,8 +1873,8 @@
                     break;
             }
             if (newZen != -1) {
-                setManualZenMode(newZen, null, "ringerModeExternal", caller,
-                        false /*setRingerMode*/, Process.SYSTEM_UID, true);
+                setManualZenMode(newZen, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI,
+                        "ringerModeExternal", caller, false /*setRingerMode*/, Process.SYSTEM_UID);
             }
 
             ZenLog.traceSetRingerModeExternal(ringerModeOld, ringerModeNew, caller,
@@ -2024,11 +2014,9 @@
         }
         try {
             final Resources res = mPm.getResourcesForApplication(packageName);
-            final String fullName = res.getResourceName(resId);
-
-            return fullName;
+            return res.getResourceName(resId);
         } catch (PackageManager.NameNotFoundException | Resources.NotFoundException e) {
-            Log.e(TAG, "Resource name for ID=" + resId + " not found in package " + packageName
+            Slog.e(TAG, "Resource name for ID=" + resId + " not found in package " + packageName
                     + ". Resource IDs may change when the application is upgraded, and the system"
                     + " may not be able to find the correct resource.");
             return null;
@@ -2149,9 +2137,9 @@
             sendMessage(obtainMessage(MSG_RINGER_AUDIO, shouldApplyToRinger));
         }
 
-        private void postApplyDeviceEffects() {
+        private void postApplyDeviceEffects(@ConfigChangeOrigin int origin) {
             removeMessages(MSG_APPLY_EFFECTS);
-            sendEmptyMessage(MSG_APPLY_EFFECTS);
+            sendMessage(obtainMessage(MSG_APPLY_EFFECTS, origin, 0));
         }
 
         @Override
@@ -2168,7 +2156,8 @@
                     updateRingerAndAudio(shouldApplyToRinger);
                     break;
                 case MSG_APPLY_EFFECTS:
-                    applyConsolidatedDeviceEffects();
+                    @ConfigChangeOrigin int origin = msg.arg1;
+                    applyConsolidatedDeviceEffects(origin);
                     break;
             }
         }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java b/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java
index 5febd02..8936dc6 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/DefaultDeviceEffectsApplierTest.java
@@ -16,13 +16,28 @@
 
 package com.android.server.notification;
 
+import static android.app.UiModeManager.MODE_NIGHT_CUSTOM_TYPE_BEDTIME;
+import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_APP;
+import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_USER;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.spy;
 import static org.mockito.Mockito.verify;
 import static org.mockito.Mockito.verifyZeroInteractions;
+import static org.mockito.Mockito.when;
 
 import android.app.UiModeManager;
 import android.app.WallpaperManager;
+import android.content.BroadcastReceiver;
+import android.content.Intent;
+import android.content.IntentFilter;
 import android.hardware.display.ColorDisplayManager;
 import android.os.PowerManager;
 import android.platform.test.flag.junit.SetFlagsRule;
@@ -36,6 +51,7 @@
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
 import org.mockito.Mock;
 import org.mockito.MockitoAnnotations;
 
@@ -55,7 +71,7 @@
     @Before
     public void setUp() {
         MockitoAnnotations.initMocks(this);
-        mContext = new TestableContext(InstrumentationRegistry.getContext(), null);
+        mContext = spy(new TestableContext(InstrumentationRegistry.getContext(), null));
         mContext.addMockSystemService(PowerManager.class, mPowerManager);
         mContext.addMockSystemService(ColorDisplayManager.class, mColorDisplayManager);
         mContext.addMockSystemService(UiModeManager.class, mUiModeManager);
@@ -74,25 +90,33 @@
                 .setShouldDisplayGrayscale(true)
                 .setShouldUseNightMode(true)
                 .build();
-        mApplier.apply(effects);
+        mApplier.apply(effects, UPDATE_ORIGIN_USER);
 
         verify(mPowerManager).suppressAmbientDisplay(anyString(), eq(true));
         verify(mColorDisplayManager).setSaturationLevel(eq(0));
         verify(mWallpaperManager).setWallpaperDimAmount(eq(0.6f));
-        verifyZeroInteractions(mUiModeManager); // Coming later; adding now so test fails then. :)
+        verify(mUiModeManager).setNightModeActivatedForCustomMode(
+                eq(MODE_NIGHT_CUSTOM_TYPE_BEDTIME), eq(true));
     }
 
     @Test
-    public void apply_removesEffects() {
+    public void apply_removesPreviouslyAppliedEffects() {
         mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API);
 
+        ZenDeviceEffects previousEffects = new ZenDeviceEffects.Builder()
+                .setShouldSuppressAmbientDisplay(true)
+                .setShouldDimWallpaper(true)
+                .build();
+        mApplier.apply(previousEffects, UPDATE_ORIGIN_USER);
+        verify(mPowerManager).suppressAmbientDisplay(anyString(), eq(true));
+        verify(mWallpaperManager).setWallpaperDimAmount(eq(0.6f));
+
         ZenDeviceEffects noEffects = new ZenDeviceEffects.Builder().build();
-        mApplier.apply(noEffects);
+        mApplier.apply(noEffects, UPDATE_ORIGIN_USER);
 
         verify(mPowerManager).suppressAmbientDisplay(anyString(), eq(false));
-        verify(mColorDisplayManager).setSaturationLevel(eq(100));
         verify(mWallpaperManager).setWallpaperDimAmount(eq(0.0f));
-        verifyZeroInteractions(mUiModeManager);
+        verifyZeroInteractions(mColorDisplayManager, mUiModeManager);
     }
 
     @Test
@@ -107,9 +131,104 @@
                 .setShouldDisplayGrayscale(true)
                 .setShouldUseNightMode(true)
                 .build();
-        mApplier.apply(effects);
+        mApplier.apply(effects, UPDATE_ORIGIN_USER);
 
         verify(mPowerManager).suppressAmbientDisplay(anyString(), eq(true));
         // (And no crash from missing services).
     }
+
+    @Test
+    public void apply_someEffects_onlyThoseEffectsApplied() {
+        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API);
+
+        ZenDeviceEffects effects = new ZenDeviceEffects.Builder()
+                .setShouldDimWallpaper(true)
+                .setShouldDisplayGrayscale(true)
+                .build();
+        mApplier.apply(effects, UPDATE_ORIGIN_USER);
+
+        verify(mColorDisplayManager).setSaturationLevel(eq(0));
+        verify(mWallpaperManager).setWallpaperDimAmount(eq(0.6f));
+
+        verify(mPowerManager, never()).suppressAmbientDisplay(anyString(), anyBoolean());
+        verify(mUiModeManager, never()).setNightModeActivatedForCustomMode(anyInt(), anyBoolean());
+    }
+
+    @Test
+    public void apply_onlyEffectDeltaApplied() {
+        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API);
+
+        mApplier.apply(new ZenDeviceEffects.Builder().setShouldDimWallpaper(true).build(),
+                UPDATE_ORIGIN_USER);
+        verify(mWallpaperManager).setWallpaperDimAmount(eq(0.6f));
+
+        // Apply a second effect and remove the first one.
+        mApplier.apply(new ZenDeviceEffects.Builder().setShouldDisplayGrayscale(true).build(),
+                UPDATE_ORIGIN_USER);
+
+        // Wallpaper dimming was undone, Grayscale was applied, nothing else was touched.
+        verify(mWallpaperManager).setWallpaperDimAmount(eq(0.0f));
+        verify(mColorDisplayManager).setSaturationLevel(eq(0));
+        verifyZeroInteractions(mPowerManager);
+        verifyZeroInteractions(mUiModeManager);
+    }
+
+    @Test
+    public void apply_darkThemeFromApp_appliedOnScreenOff() {
+        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API);
+        ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
+                ArgumentCaptor.forClass(BroadcastReceiver.class);
+        ArgumentCaptor<IntentFilter> intentFilterCaptor =
+                ArgumentCaptor.forClass(IntentFilter.class);
+
+        when(mPowerManager.isInteractive()).thenReturn(true);
+
+        mApplier.apply(new ZenDeviceEffects.Builder().setShouldUseNightMode(true).build(),
+                UPDATE_ORIGIN_APP);
+
+        // Effect was not yet applied, but a broadcast receiver was registered.
+        verifyZeroInteractions(mUiModeManager);
+        verify(mContext).registerReceiver(broadcastReceiverCaptor.capture(),
+                intentFilterCaptor.capture(), anyInt());
+        assertThat(intentFilterCaptor.getValue().getAction(0)).isEqualTo(Intent.ACTION_SCREEN_OFF);
+        BroadcastReceiver screenOffReceiver = broadcastReceiverCaptor.getValue();
+
+        // Now the "screen off" event comes.
+        screenOffReceiver.onReceive(mContext, new Intent(Intent.ACTION_SCREEN_OFF));
+
+        // So the effect is applied, and we stopped listening for this event.
+        verify(mUiModeManager).setNightModeActivatedForCustomMode(
+                eq(MODE_NIGHT_CUSTOM_TYPE_BEDTIME), eq(true));
+        verify(mContext).unregisterReceiver(eq(screenOffReceiver));
+    }
+
+    @Test
+    public void apply_darkThemeFromAppWithScreenOff_appliedImmediately() {
+        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API);
+
+        when(mPowerManager.isInteractive()).thenReturn(false);
+
+        mApplier.apply(new ZenDeviceEffects.Builder().setShouldUseNightMode(true).build(),
+                UPDATE_ORIGIN_APP);
+
+        // Effect was applied, and no broadcast receiver was registered.
+        verify(mUiModeManager).setNightModeActivatedForCustomMode(
+                eq(MODE_NIGHT_CUSTOM_TYPE_BEDTIME), eq(true));
+        verify(mContext, never()).registerReceiver(any(), any(), anyInt());
+    }
+
+    @Test
+    public void testDeviceEffects_darkThemeFromUser_appliedImmediately() {
+        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API);
+
+        when(mPowerManager.isInteractive()).thenReturn(true);
+
+        mApplier.apply(new ZenDeviceEffects.Builder().setShouldUseNightMode(true).build(),
+                UPDATE_ORIGIN_USER);
+
+        // Effect was applied, and no broadcast receiver was registered.
+        verify(mUiModeManager).setNightModeActivatedForCustomMode(
+                eq(MODE_NIGHT_CUSTOM_TYPE_BEDTIME), eq(true));
+        verify(mContext, never()).registerReceiver(any(), any(), anyInt());
+    }
 }
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index ee08fd2..8bb11a4 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -220,6 +220,7 @@
 import android.service.notification.NotificationRankingUpdate;
 import android.service.notification.NotificationStats;
 import android.service.notification.StatusBarNotification;
+import android.service.notification.ZenModeConfig;
 import android.service.notification.ZenPolicy;
 import android.telecom.TelecomManager;
 import android.telephony.TelephonyManager;
@@ -8929,8 +8930,8 @@
         mBinderService.addAutomaticZenRule(rule, "com.android.settings");
 
         // verify that zen mode helper gets passed in a package name of "android"
-        verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule), anyString(),
-                anyInt(), eq(ZenModeHelper.FROM_SYSTEM_OR_SYSTEMUI)); // system call
+        verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule),
+                eq(ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI), anyString(), anyInt());
     }
 
     @Test
@@ -8951,8 +8952,8 @@
         mBinderService.addAutomaticZenRule(rule, "com.android.settings");
 
         // verify that zen mode helper gets passed in a package name of "android"
-        verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule), anyString(),
-                anyInt(), eq(ZenModeHelper.FROM_SYSTEM_OR_SYSTEMUI));  // system call
+        verify(mockZenModeHelper).addAutomaticZenRule(eq("android"), eq(rule),
+                eq(ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI), anyString(), anyInt());
     }
 
     @Test
@@ -8972,8 +8973,8 @@
 
         // verify that zen mode helper gets passed in the package name from the arg, not the owner
         verify(mockZenModeHelper).addAutomaticZenRule(
-                eq("another.package"), eq(rule), anyString(), anyInt(),
-                eq(ZenModeHelper.FROM_APP));  // doesn't count as a system/systemui call
+                eq("another.package"), eq(rule), eq(ZenModeConfig.UPDATE_ORIGIN_APP),
+                anyString(), anyInt());  // doesn't count as a system/systemui call
     }
 
     @Test
@@ -13185,7 +13186,7 @@
         NotificationManager.Policy policy = new NotificationManager.Policy(0, 0, 0);
         mBinderService.setNotificationPolicy("package", policy);
 
-        verify(zenModeHelper).setNotificationPolicy(eq(policy), anyInt(), anyBoolean());
+        verify(zenModeHelper).setNotificationPolicy(eq(policy), anyInt(), anyInt());
     }
 
     @Test
@@ -13207,7 +13208,7 @@
         NotificationManager.Policy policy = new NotificationManager.Policy(0, 0, 0);
         mBinderService.setNotificationPolicy("package", policy);
 
-        verify(zenModeHelper).setNotificationPolicy(eq(policy), anyInt(), anyBoolean());
+        verify(zenModeHelper).setNotificationPolicy(eq(policy), anyInt(), anyInt());
     }
 
     @Test
@@ -13223,7 +13224,7 @@
         NotificationManager.Policy policy = new NotificationManager.Policy(0, 0, 0);
         mBinderService.setNotificationPolicy("package", policy);
 
-        verify(zenModeHelper).setNotificationPolicy(eq(policy), anyInt(), anyBoolean());
+        verify(zenModeHelper).setNotificationPolicy(eq(policy), anyInt(), anyInt());
     }
 
     @Test
@@ -13271,7 +13272,8 @@
         mBinderService.setInterruptionFilter("package", INTERRUPTION_FILTER_PRIORITY);
 
         verify(zenModeHelper).setManualZenMode(eq(ZEN_MODE_IMPORTANT_INTERRUPTIONS), eq(null),
-                eq("package"), anyString(), anyInt(), anyBoolean());
+                eq(ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI), anyString(), eq("package"),
+                anyInt());
     }
 
     @Test
@@ -13280,6 +13282,7 @@
         mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API);
         ZenModeHelper zenModeHelper = mock(ZenModeHelper.class);
         mService.mZenModeHelper = zenModeHelper;
+        mService.setCallerIsNormalPackage();
         when(mConditionProviders.isPackageOrComponentAllowed(anyString(), anyInt()))
                 .thenReturn(true);
         when(mCompanionMgr.getAssociations(anyString(), anyInt()))
@@ -13292,7 +13295,7 @@
         mBinderService.setInterruptionFilter("package", INTERRUPTION_FILTER_PRIORITY);
 
         verify(zenModeHelper).setManualZenMode(eq(ZEN_MODE_IMPORTANT_INTERRUPTIONS), eq(null),
-                eq("package"), anyString(), anyInt(), anyBoolean());
+                eq(ZenModeConfig.UPDATE_ORIGIN_APP), anyString(), eq("package"), anyInt());
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index fe21103..5ddac03 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -67,7 +67,6 @@
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.ArgumentMatchers.anyBoolean;
 import static org.mockito.ArgumentMatchers.anyInt;
 import static org.mockito.ArgumentMatchers.anyString;
 import static org.mockito.ArgumentMatchers.eq;
@@ -2370,7 +2369,7 @@
         mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false,
                 uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
 
         // create notification channel that can bypass dnd
@@ -2380,18 +2379,18 @@
         mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
                 uid, false);
         assertTrue(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
 
         // delete channels
         mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel.getId(), uid, false);
         assertTrue(mHelper.areChannelsBypassingDnd()); // channel2 can still bypass DND
-        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
 
         mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel2.getId(), uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
     }
 
@@ -2407,7 +2406,7 @@
         mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false,
                 uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
 
         // Recreate a channel & now the app has dnd access granted and can set the bypass dnd field
@@ -2417,7 +2416,7 @@
                 uid, false);
 
         assertTrue(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
     }
 
@@ -2433,7 +2432,7 @@
         mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false,
                 uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
 
         // create notification channel that can bypass dnd, using local app level settings
@@ -2443,18 +2442,18 @@
         mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
                 uid, false);
         assertTrue(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
 
         // delete channels
         mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel.getId(), uid, false);
         assertTrue(mHelper.areChannelsBypassingDnd()); // channel2 can still bypass DND
-        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
 
         mHelper.deleteNotificationChannel(PKG_N_MR1, uid, channel2.getId(), uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
     }
 
@@ -2481,8 +2480,7 @@
         mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
                 uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(),
-                anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
     }
 
@@ -2504,7 +2502,7 @@
         mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
                 uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
     }
 
@@ -2526,7 +2524,7 @@
         mHelper.createNotificationChannel(PKG_N_MR1, uid, channel2, true, true,
                 uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
     }
 
@@ -2542,7 +2540,7 @@
         mHelper.createNotificationChannel(PKG_N_MR1, uid, channel, true, false,
                 uid, false);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
 
         // update channel so it CAN bypass dnd:
@@ -2550,7 +2548,7 @@
         channel.setBypassDnd(true);
         mHelper.updateNotificationChannel(PKG_N_MR1, uid, channel, true, SYSTEM_UID, true);
         assertTrue(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
 
         // update channel so it can't bypass dnd:
@@ -2558,7 +2556,7 @@
         channel.setBypassDnd(false);
         mHelper.updateNotificationChannel(PKG_N_MR1, uid, channel, true, SYSTEM_UID, true);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
     }
 
@@ -2571,7 +2569,7 @@
         when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
         mHelper.syncChannelsBypassingDnd();
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, times(1)).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
     }
 
@@ -2581,7 +2579,7 @@
         mTestNotificationPolicy = new NotificationManager.Policy(0, 0, 0, 0, 0, 0);
         when(mMockZenModeHelper.getNotificationPolicy()).thenReturn(mTestNotificationPolicy);
         assertFalse(mHelper.areChannelsBypassingDnd());
-        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyBoolean());
+        verify(mMockZenModeHelper, never()).setNotificationPolicy(any(), anyInt(), anyInt());
         resetZenModeHelper();
     }
 
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 ef6fced..646ee3f 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ZenModeHelperTest.java
@@ -45,6 +45,12 @@
 import static android.provider.Settings.Global.ZEN_MODE_OFF;
 import static android.service.notification.Condition.STATE_FALSE;
 import static android.service.notification.Condition.STATE_TRUE;
+import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_APP;
+import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_INIT;
+import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_INIT_USER;
+import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI;
+import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_UNKNOWN;
+import static android.service.notification.ZenModeConfig.UPDATE_ORIGIN_USER;
 import static android.service.notification.ZenPolicy.PEOPLE_TYPE_CONTACTS;
 import static android.service.notification.ZenPolicy.PEOPLE_TYPE_STARRED;
 
@@ -53,9 +59,6 @@
 import static com.android.os.dnd.DNDProtoEnums.ROOT_CONFIG;
 import static com.android.os.dnd.DNDProtoEnums.STATE_ALLOW;
 import static com.android.os.dnd.DNDProtoEnums.STATE_DISALLOW;
-import static com.android.server.notification.ZenModeHelper.FROM_APP;
-import static com.android.server.notification.ZenModeHelper.FROM_SYSTEM_OR_SYSTEMUI;
-import static com.android.server.notification.ZenModeHelper.FROM_USER;
 import static com.android.server.notification.ZenModeHelper.RULE_LIMIT_PER_PACKAGE;
 
 import static com.google.common.truth.Truth.assertThat;
@@ -305,8 +308,8 @@
         mZenModeHelper.writeXml(serializer, false, version, UserHandle.USER_ALL);
         serializer.endDocument();
         serializer.flush();
-        mZenModeHelper.setConfig(new ZenModeConfig(), null, "writing xml", Process.SYSTEM_UID,
-                true);
+        mZenModeHelper.setConfig(new ZenModeConfig(), null, UPDATE_ORIGIN_INIT, "writing xml",
+                Process.SYSTEM_UID);
         return baos;
     }
 
@@ -321,7 +324,8 @@
         serializer.flush();
         ZenModeConfig newConfig = new ZenModeConfig();
         newConfig.user = userId;
-        mZenModeHelper.setConfig(newConfig, null, "writing xml", Process.SYSTEM_UID, true);
+        mZenModeHelper.setConfig(newConfig, null, UPDATE_ORIGIN_INIT, "writing xml",
+                Process.SYSTEM_UID);
         return baos;
     }
 
@@ -838,7 +842,7 @@
         mZenModeHelper.mConfig = null; // will evaluate config to zen mode off
         for (int i = 0; i < 3; i++) {
             // if zen doesn't change, zen should not reapply itself to the ringer
-            mZenModeHelper.evaluateZenModeLocked("test", true);
+            mZenModeHelper.evaluateZenModeLocked(UPDATE_ORIGIN_UNKNOWN, "test", true);
         }
         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
                 mZenModeHelper.TAG);
@@ -865,7 +869,7 @@
         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         for (int i = 0; i < 3; i++) {
             // if zen doesn't change, zen should not reapply itself to the ringer
-            mZenModeHelper.evaluateZenModeLocked("test", true);
+            mZenModeHelper.evaluateZenModeLocked(UPDATE_ORIGIN_UNKNOWN, "test", true);
         }
         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
                 mZenModeHelper.TAG);
@@ -892,7 +896,7 @@
         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
         for (int i = 0; i < 3; i++) {
             // if zen doesn't change, zen should not reapply itself to the ringer
-            mZenModeHelper.evaluateZenModeLocked("test", true);
+            mZenModeHelper.evaluateZenModeLocked(UPDATE_ORIGIN_UNKNOWN, "test", true);
         }
         verify(mAudioManager, never()).setRingerModeInternal(AudioManager.RINGER_MODE_NORMAL,
                 mZenModeHelper.TAG);
@@ -905,8 +909,8 @@
         setupZenConfig();
 
         // Turn manual zen mode on
-        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null,
-                "test", CUSTOM_PKG_UID, false);
+        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, UPDATE_ORIGIN_APP,
+                null, "test", CUSTOM_PKG_UID);
 
         // audio manager shouldn't do anything until the handler processes its messages
         verify(mAudioManager, never()).updateRingerModeAffectedStreamsInternal();
@@ -1185,7 +1189,8 @@
         List<StatsEvent> events = new LinkedList<>();
 
         mZenModeHelper.pullRules(events);
-        mZenModeHelper.removeAutomaticZenRule(CUSTOM_RULE_ID, "test", CUSTOM_PKG_UID, false);
+        mZenModeHelper.removeAutomaticZenRule(CUSTOM_RULE_ID, UPDATE_ORIGIN_APP, "test",
+                CUSTOM_PKG_UID);
         assertTrue(-1
                 == mZenModeHelper.mRulesUidCache.getOrDefault(CUSTOM_PKG_NAME + "|" + 0, -1));
     }
@@ -1240,12 +1245,14 @@
         config10.user = 10;
         config10.allowAlarms = true;
         config10.allowMedia = true;
-        mZenModeHelper.setConfig(config10, null, "writeXml", Process.SYSTEM_UID, true);
+        mZenModeHelper.setConfig(config10, null, UPDATE_ORIGIN_INIT, "writeXml",
+                Process.SYSTEM_UID);
         ZenModeConfig config11 = mZenModeHelper.mConfig.copy();
         config11.user = 11;
         config11.allowAlarms = false;
         config11.allowMedia = false;
-        mZenModeHelper.setConfig(config11, null, "writeXml", Process.SYSTEM_UID, true);
+        mZenModeHelper.setConfig(config11, null, UPDATE_ORIGIN_INIT, "writeXml",
+                Process.SYSTEM_UID);
 
         // Backup user 10 and reset values.
         ByteArrayOutputStream baos = writeXmlAndPurgeForUser(null, 10);
@@ -1849,8 +1856,8 @@
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
             // We need the package name to be something that's not "android" so there aren't any
             // existing rules under that package.
-            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
-                    CUSTOM_PKG_UID, FROM_APP);
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, UPDATE_ORIGIN_APP,
+                    "test", CUSTOM_PKG_UID);
             assertNotNull(id);
         }
         try {
@@ -1860,8 +1867,8 @@
                     ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
-                    CUSTOM_PKG_UID, FROM_APP);
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, UPDATE_ORIGIN_APP,
+                    "test", CUSTOM_PKG_UID);
             fail("allowed too many rules to be created");
         } catch (IllegalArgumentException e) {
             // yay
@@ -1881,8 +1888,8 @@
                     ZenModeConfig.toScheduleConditionId(si),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
-                    CUSTOM_PKG_UID, FROM_APP);
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, UPDATE_ORIGIN_APP,
+                    "test", CUSTOM_PKG_UID);
             assertNotNull(id);
         }
         try {
@@ -1892,8 +1899,8 @@
                     ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
-                    CUSTOM_PKG_UID, FROM_APP);
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, UPDATE_ORIGIN_APP,
+                    "test", CUSTOM_PKG_UID);
             fail("allowed too many rules to be created");
         } catch (IllegalArgumentException e) {
             // yay
@@ -1913,8 +1920,8 @@
                     ZenModeConfig.toScheduleConditionId(si),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
-                    CUSTOM_PKG_UID, FROM_APP);
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, UPDATE_ORIGIN_APP,
+                    "test", CUSTOM_PKG_UID);
             assertNotNull(id);
         }
         try {
@@ -1924,8 +1931,8 @@
                     ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                     new ZenPolicy.Builder().build(),
                     NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, "test",
-                    CUSTOM_PKG_UID, FROM_APP);
+            String id = mZenModeHelper.addAutomaticZenRule("pkgname", zenRule, UPDATE_ORIGIN_APP,
+                    "test", CUSTOM_PKG_UID);
             fail("allowed too many rules to be created");
         } catch (IllegalArgumentException e) {
             // yay
@@ -1940,8 +1947,8 @@
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test",
-                Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+        String id = mZenModeHelper.addAutomaticZenRule("android", zenRule,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         assertTrue(id != null);
         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
@@ -1961,8 +1968,8 @@
                 new ComponentName("android", "ScheduleConditionProvider"),
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test",
-                Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+        String id = mZenModeHelper.addAutomaticZenRule("android", zenRule,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         assertTrue(id != null);
         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
@@ -1985,11 +1992,12 @@
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
 
-        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test",
-                CUSTOM_PKG_UID, FROM_APP);
+        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, UPDATE_ORIGIN_APP, "test",
+                CUSTOM_PKG_UID);
         mZenModeHelper.setAutomaticZenRuleState(zenRule.getConditionId(),
                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
-                CUSTOM_PKG_UID, false);
+                UPDATE_ORIGIN_APP,
+                CUSTOM_PKG_UID);
 
         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
         assertEquals(STATE_TRUE, ruleInConfig.condition.state);
@@ -2004,8 +2012,8 @@
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
 
-        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test",
-                CUSTOM_PKG_UID, FROM_APP);
+        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, UPDATE_ORIGIN_APP, "test",
+                CUSTOM_PKG_UID);
 
         AutomaticZenRule zenRule2 = new AutomaticZenRule("NEW",
                 null,
@@ -2014,7 +2022,7 @@
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
 
-        mZenModeHelper.updateAutomaticZenRule(id, zenRule2, "", CUSTOM_PKG_UID, FROM_APP);
+        mZenModeHelper.updateAutomaticZenRule(id, zenRule2, UPDATE_ORIGIN_APP, "", CUSTOM_PKG_UID);
 
         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
         assertEquals("NEW", ruleInConfig.name);
@@ -2029,15 +2037,15 @@
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
 
-        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test",
-                CUSTOM_PKG_UID, FROM_APP);
+        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, UPDATE_ORIGIN_APP, "test",
+                CUSTOM_PKG_UID);
 
         assertTrue(id != null);
         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
         assertTrue(ruleInConfig != null);
         assertEquals(zenRule.getName(), ruleInConfig.name);
 
-        mZenModeHelper.removeAutomaticZenRule(id, "test", CUSTOM_PKG_UID, false);
+        mZenModeHelper.removeAutomaticZenRule(id, UPDATE_ORIGIN_APP, "test", CUSTOM_PKG_UID);
         assertNull(mZenModeHelper.mConfig.automaticRules.get(id));
     }
 
@@ -2049,16 +2057,16 @@
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 new ZenPolicy.Builder().build(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, "test",
-                CUSTOM_PKG_UID, FROM_APP);
+        String id = mZenModeHelper.addAutomaticZenRule(null, zenRule, UPDATE_ORIGIN_APP, "test",
+                CUSTOM_PKG_UID);
 
         assertTrue(id != null);
         ZenModeConfig.ZenRule ruleInConfig = mZenModeHelper.mConfig.automaticRules.get(id);
         assertTrue(ruleInConfig != null);
         assertEquals(zenRule.getName(), ruleInConfig.name);
 
-        mZenModeHelper.removeAutomaticZenRules(mContext.getPackageName(), "test",
-                CUSTOM_PKG_UID, false);
+        mZenModeHelper.removeAutomaticZenRules(mContext.getPackageName(), UPDATE_ORIGIN_APP, "test",
+                CUSTOM_PKG_UID);
         assertNull(mZenModeHelper.mConfig.automaticRules.get(id));
     }
 
@@ -2073,17 +2081,18 @@
                 new ComponentName("android", "ScheduleConditionProvider"),
                 sharedUri,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelper.addAutomaticZenRule("android", zenRule, "test",
-                Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+        String id = mZenModeHelper.addAutomaticZenRule("android", zenRule,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
         AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
                 new ComponentName("android", "ScheduleConditionProvider"),
                 sharedUri,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id2 = mZenModeHelper.addAutomaticZenRule("android", zenRule2, "test",
-                Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+        String id2 = mZenModeHelper.addAutomaticZenRule("android", zenRule2,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         Condition condition = new Condition(sharedUri, "", STATE_TRUE);
-        mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition, Process.SYSTEM_UID, true);
+        mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
             if (rule.id.equals(id)) {
@@ -2097,7 +2106,8 @@
         }
 
         condition = new Condition(sharedUri, "", STATE_FALSE);
-        mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition, Process.SYSTEM_UID, true);
+        mZenModeHelper.setAutomaticZenRuleState(sharedUri, condition,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         for (ZenModeConfig.ZenRule rule : mZenModeHelper.mConfig.automaticRules.values()) {
             if (rule.id.equals(id)) {
@@ -2133,7 +2143,7 @@
                         .setOwner(OWNER)
                         .setDeviceEffects(zde)
                         .build(),
-                "reasons", 0, FROM_APP);
+                UPDATE_ORIGIN_APP, "reasons", 0);
 
         AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId);
         assertThat(savedRule.getDeviceEffects()).isEqualTo(
@@ -2167,7 +2177,7 @@
                         .setOwner(OWNER)
                         .setDeviceEffects(zde)
                         .build(),
-                "reasons", 0, FROM_SYSTEM_OR_SYSTEMUI);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "reasons", 0);
 
         AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId);
         assertThat(savedRule.getDeviceEffects()).isEqualTo(zde);
@@ -2195,7 +2205,8 @@
                         .setOwner(OWNER)
                         .setDeviceEffects(zde)
                         .build(),
-                "reasons", 0, FROM_USER);
+                UPDATE_ORIGIN_USER,
+                "reasons", 0);
 
         AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId);
         assertThat(savedRule.getDeviceEffects()).isEqualTo(zde);
@@ -2212,7 +2223,7 @@
                         .setOwner(OWNER)
                         .setDeviceEffects(original)
                         .build(),
-                "reasons", 0, FROM_SYSTEM_OR_SYSTEMUI);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "reasons", 0);
 
         ZenDeviceEffects updateFromApp = new ZenDeviceEffects.Builder()
                 .setShouldUseNightMode(true) // Good
@@ -2223,7 +2234,7 @@
                         .setOwner(OWNER)
                         .setDeviceEffects(updateFromApp)
                         .build(),
-                "reasons", 0, FROM_APP);
+                UPDATE_ORIGIN_APP, "reasons", 0);
 
         AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId);
         assertThat(savedRule.getDeviceEffects()).isEqualTo(
@@ -2244,7 +2255,7 @@
                         .setOwner(OWNER)
                         .setDeviceEffects(original)
                         .build(),
-                "reasons", 0, FROM_SYSTEM_OR_SYSTEMUI);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "reasons", 0);
 
         ZenDeviceEffects updateFromSystem = new ZenDeviceEffects.Builder()
                 .setShouldUseNightMode(true) // Good
@@ -2254,7 +2265,7 @@
                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
                         .setDeviceEffects(updateFromSystem)
                         .build(),
-                "reasons", 0, FROM_SYSTEM_OR_SYSTEMUI);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "reasons", 0);
 
         AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId);
         assertThat(savedRule.getDeviceEffects()).isEqualTo(updateFromSystem);
@@ -2271,7 +2282,7 @@
                         .setOwner(OWNER)
                         .setDeviceEffects(original)
                         .build(),
-                "reasons", 0, FROM_SYSTEM_OR_SYSTEMUI);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "reasons", 0);
 
         ZenDeviceEffects updateFromUser = new ZenDeviceEffects.Builder()
                 .setShouldUseNightMode(true) // Good
@@ -2281,7 +2292,7 @@
                 new AutomaticZenRule.Builder("Rule", CONDITION_ID)
                         .setDeviceEffects(updateFromUser)
                         .build(),
-                "reasons", 0, FROM_USER);
+                UPDATE_ORIGIN_USER, "reasons", 0);
 
         AutomaticZenRule savedRule = mZenModeHelper.getAutomaticZenRule(ruleId);
         assertThat(savedRule.getDeviceEffects()).isEqualTo(updateFromUser);
@@ -2293,16 +2304,16 @@
         setupZenConfig();
 
         // note that caller=null because that's how it comes in from NMS.setZenMode
-        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
-                Process.SYSTEM_UID, true);
+        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", null, Process.SYSTEM_UID);
 
         // confirm that setting zen mode via setManualZenMode changed the zen mode correctly
         assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeHelper.mZenMode);
         assertEquals(true, mZenModeHelper.mConfig.manualRule.allowManualInvocation);
 
         // and also that it works to turn it back off again
-        mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, null, "",
-                Process.SYSTEM_UID, true);
+        mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI,
+                "", null, Process.SYSTEM_UID);
 
         assertEquals(Global.ZEN_MODE_OFF, mZenModeHelper.mZenMode);
     }
@@ -2312,15 +2323,15 @@
         setupZenConfig();
 
         // note that caller=null because that's how it comes in from NMS.setZenMode
-        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
-                Process.SYSTEM_UID, true);
+        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", null, Process.SYSTEM_UID);
 
         // confirm that setting zen mode via setManualZenMode changed the zen mode correctly
         assertEquals(ZEN_MODE_IMPORTANT_INTERRUPTIONS, mZenModeHelper.mZenMode);
 
         // and also that it works to turn it back off again
-        mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, null, "",
-                Process.SYSTEM_UID, true);
+        mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "",
+                null, Process.SYSTEM_UID);
 
         assertEquals(ZEN_MODE_OFF, mZenModeHelper.mZenMode);
     }
@@ -2332,13 +2343,13 @@
 
         // Turn zen mode on (to important_interruptions)
         // Need to additionally call the looper in order to finish the post-apply-config process
-        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
-                Process.SYSTEM_UID, true);
+        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", null, Process.SYSTEM_UID);
 
         // Now turn zen mode off, but via a different package UID -- this should get registered as
         // "not an action by the user" because some other app is changing zen mode
-        mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, null, "", CUSTOM_PKG_UID,
-                false);
+        mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, UPDATE_ORIGIN_APP, "", null,
+                CUSTOM_PKG_UID);
 
         // In total, this should be 2 loggable changes
         assertEquals(2, mZenModeEventLogger.numLoggedChanges());
@@ -2397,17 +2408,18 @@
                 null,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
         String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule,
-                "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         // Event 1: Mimic the rule coming on automatically by setting the Condition to STATE_TRUE
         mZenModeHelper.setAutomaticZenRuleState(id,
                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI,
+                Process.SYSTEM_UID);
 
         // Event 2: "User" turns off the automatic rule (sets it to not enabled)
         zenRule.setEnabled(false);
-        mZenModeHelper.updateAutomaticZenRule(id, zenRule, "", Process.SYSTEM_UID,
-                FROM_SYSTEM_OR_SYSTEMUI);
+        mZenModeHelper.updateAutomaticZenRule(id, zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "",
+                Process.SYSTEM_UID);
 
         // Add a new system rule
         AutomaticZenRule systemRule = new AutomaticZenRule("systemRule",
@@ -2417,15 +2429,16 @@
                 null,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
         String systemId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), systemRule,
-                "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         // Event 3: turn on the system rule
         mZenModeHelper.setAutomaticZenRuleState(systemId,
                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // Event 4: "User" deletes the rule
-        mZenModeHelper.removeAutomaticZenRule(systemId, "", Process.SYSTEM_UID, true);
+        mZenModeHelper.removeAutomaticZenRule(systemId, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "",
+                Process.SYSTEM_UID);
 
         // In total, this represents 4 events
         assertEquals(4, mZenModeEventLogger.numLoggedChanges());
@@ -2486,26 +2499,26 @@
         setupZenConfig();
 
         // First just turn zen mode on
-        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
-                Process.SYSTEM_UID, true);
+        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", null, Process.SYSTEM_UID);
 
         // Now change the policy slightly; want to confirm that this'll be reflected in the logs
         ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
         newConfig.allowAlarms = true;
         newConfig.allowRepeatCallers = false;
-        mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
-                true);
+        mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(),
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // Turn zen mode off; we want to make sure policy changes do not get logged when zen mode
         // is off.
-        mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, null, "",
-                Process.SYSTEM_UID, true);
+        mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "",
+                null, Process.SYSTEM_UID);
 
         // Change the policy again
         newConfig.allowMessages = false;
         newConfig.allowRepeatCallers = true;
-        mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
-                true);
+        mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(),
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // Total events: we only expect ones for turning on, changing policy, and turning off
         assertEquals(3, mZenModeEventLogger.numLoggedChanges());
@@ -2548,8 +2561,8 @@
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 null,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test",
-                Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+        String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         // Rule 2, same as rule 1
         AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
@@ -2558,8 +2571,8 @@
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 null,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, "test",
-                Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+        String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         // Rule 3, has stricter settings than the default settings
         ZenModeConfig ruleConfig = mZenModeHelper.mConfig.copy();
@@ -2572,28 +2585,28 @@
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 ruleConfig.toZenPolicy(),
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id3 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule3, "test",
-                Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+        String id3 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule3,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         // First: turn on rule 1
         mZenModeHelper.setAutomaticZenRuleState(id,
                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI,  Process.SYSTEM_UID);
 
         // Second: turn on rule 2
         mZenModeHelper.setAutomaticZenRuleState(id2,
                 new Condition(zenRule2.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI,  Process.SYSTEM_UID);
 
         // Third: turn on rule 3
         mZenModeHelper.setAutomaticZenRuleState(id3,
                 new Condition(zenRule3.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI,  Process.SYSTEM_UID);
 
         // Fourth: Turn *off* rule 2
         mZenModeHelper.setAutomaticZenRuleState(id2,
                 new Condition(zenRule2.getConditionId(), "", STATE_FALSE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI,  Process.SYSTEM_UID);
 
         // This should result in a total of four events
         assertEquals(4, mZenModeEventLogger.numLoggedChanges());
@@ -2649,7 +2662,7 @@
         // Artificially turn zen mode "on". Re-evaluating zen mode should cause it to turn back off
         // given that we don't have any zen rules active.
         mZenModeHelper.mZenMode = ZEN_MODE_IMPORTANT_INTERRUPTIONS;
-        mZenModeHelper.evaluateZenModeLocked("test", true);
+        mZenModeHelper.evaluateZenModeLocked(UPDATE_ORIGIN_UNKNOWN, "test", true);
 
         // Check that the change actually took: zen mode should be off now
         assertEquals(ZEN_MODE_OFF, mZenModeHelper.mZenMode);
@@ -2672,8 +2685,8 @@
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 null,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test",
-                Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+        String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         // Rule 2, same as rule 1 but owned by the system
         AutomaticZenRule zenRule2 = new AutomaticZenRule("name2",
@@ -2682,37 +2695,37 @@
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 null,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2, "test",
-                Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+        String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         // Turn on rule 1; call looks like it's from the system. Because setting a condition is
         // typically an automatic (non-user-initiated) action, expect the calling UID to be
         // re-evaluated to the one associat.d with CUSTOM_PKG_NAME.
         mZenModeHelper.setAutomaticZenRuleState(id,
                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // Second: turn on rule 2. This is a system-owned rule and the UID should not be modified
         // (nor even looked up; the mock PackageManager won't handle "android" as input).
         mZenModeHelper.setAutomaticZenRuleState(id2,
                 new Condition(zenRule2.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // Disable rule 1. Because this looks like a user action, the UID should not be modified
         // from the system-provided one.
         zenRule.setEnabled(false);
-        mZenModeHelper.updateAutomaticZenRule(id, zenRule, "", Process.SYSTEM_UID,
-                FROM_SYSTEM_OR_SYSTEMUI);
+        mZenModeHelper.updateAutomaticZenRule(id, zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "",
+                Process.SYSTEM_UID);
 
         // Add a manual rule. Any manual rule changes should not get calling uids reassigned.
-        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
-                CUSTOM_PKG_UID, false);
+        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, UPDATE_ORIGIN_APP,
+                "", null, CUSTOM_PKG_UID);
 
         // Change rule 2's condition, but from some other UID. Since it doesn't look like it's from
         // the system, we keep the UID info.
         mZenModeHelper.setAutomaticZenRuleState(id2,
                 new Condition(zenRule2.getConditionId(), "", STATE_FALSE),
-                12345, false);
+                UPDATE_ORIGIN_APP, 12345);
 
         // That was 5 events total
         assertEquals(5, mZenModeEventLogger.numLoggedChanges());
@@ -2767,26 +2780,26 @@
         // Turn on zen mode with a manual rule with an enabler set. This should *not* count
         // as a user action, and *should* get its UID reassigned.
         mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
-                CUSTOM_PKG_NAME, "", Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", CUSTOM_PKG_NAME, Process.SYSTEM_UID);
 
         // Now change apps bypassing to true
         ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
         newConfig.areChannelsBypassingDnd = true;
-        mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
-                true);
+        mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(),
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // and then back to false, all without changing anything else
         newConfig.areChannelsBypassingDnd = false;
-        mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
-                true);
+        mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(),
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // Turn off manual mode, call from a package: don't reset UID even though enabler is set
-        mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null,
-                CUSTOM_PKG_NAME, "", 12345, false);
+        mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, UPDATE_ORIGIN_APP, "",
+                CUSTOM_PKG_NAME, 12345);
 
         // And likewise when turning it back on again
-        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
-                CUSTOM_PKG_NAME, "", 12345, false);
+        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, UPDATE_ORIGIN_APP,
+                "", CUSTOM_PKG_NAME, 12345);
 
         // These are 5 events in total.
         assertEquals(5, mZenModeEventLogger.numLoggedChanges());
@@ -2831,15 +2844,15 @@
         setupZenConfig();
 
         // First just turn zen mode on
-        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null, null, "",
-                Process.SYSTEM_UID, true);
+        mZenModeHelper.setManualZenMode(ZEN_MODE_IMPORTANT_INTERRUPTIONS, null,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "", null, Process.SYSTEM_UID);
 
         // Now change only the channels part of the policy; want to confirm that this'll be
         // reflected in the logs
         ZenModeConfig newConfig = mZenModeHelper.mConfig.copy();
         newConfig.allowPriorityChannels = false;
-        mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(), Process.SYSTEM_UID,
-                true);
+        mZenModeHelper.setNotificationPolicy(newConfig.toNotificationPolicy(),
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // Total events: one for turning on, one for changing policy
         assertThat(mZenModeEventLogger.numLoggedChanges()).isEqualTo(2);
@@ -2881,13 +2894,13 @@
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 null,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test",
-                Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+        String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         // enable the rule
         mZenModeHelper.setAutomaticZenRuleState(id,
                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // inspect the consolidated policy. Based on setupZenConfig() values.
         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowAlarms());
@@ -2924,13 +2937,13 @@
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 customPolicy,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test",
-                Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+        String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         // enable the rule; this will update the consolidated policy
         mZenModeHelper.setAutomaticZenRuleState(id,
                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // since this is the only active rule, the consolidated policy should match the custom
         // policy for every field specified, and take default values for unspecified things
@@ -2960,13 +2973,13 @@
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 null,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test",
-                Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+        String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         // enable rule 1
         mZenModeHelper.setAutomaticZenRuleState(id,
                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // custom policy for rule 2
         ZenPolicy customPolicy = new ZenPolicy.Builder()
@@ -2985,12 +2998,12 @@
                 customPolicy,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
         String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2,
-                "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         // enable rule 2; this will update the consolidated policy
         mZenModeHelper.setAutomaticZenRuleState(id2,
                 new Condition(zenRule2.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // now both rules should be on, and the consolidated policy should reflect the most
         // restrictive option of each of the two
@@ -3022,13 +3035,13 @@
                 ZenModeConfig.toScheduleConditionId(new ScheduleInfo()),
                 customPolicy,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
-        String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule, "test",
-                Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+        String id = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule,
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         // enable the rule; this will update the consolidated policy
         mZenModeHelper.setAutomaticZenRuleState(id,
                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // confirm that channels make it through
         assertTrue(mZenModeHelper.mConsolidatedPolicy.allowPriorityChannels());
@@ -3045,12 +3058,12 @@
                 strictPolicy,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
         String id2 = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(), zenRule2,
-                "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         // enable rule 2; this will update the consolidated policy
         mZenModeHelper.setAutomaticZenRuleState(id2,
                 new Condition(zenRule2.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // rule 2 should override rule 1
         assertFalse(mZenModeHelper.mConsolidatedPolicy.allowPriorityChannels());
@@ -3121,7 +3134,7 @@
 
         ZenModeConfig.ZenRule rule = new ZenModeConfig.ZenRule();
 
-        mZenModeHelper.populateZenRule(OWNER.getPackageName(), azr, rule, true, FROM_APP);
+        mZenModeHelper.populateZenRule(OWNER.getPackageName(), azr, rule, UPDATE_ORIGIN_APP, true);
 
         assertEquals(NAME, rule.name);
         assertEquals(OWNER, rule.component);
@@ -3149,7 +3162,7 @@
                 null,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
         final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(),
-                zenRule, "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+                zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         CountDownLatch latch = new CountDownLatch(1);
         final int[] actualStatus = new int[1];
@@ -3165,8 +3178,8 @@
         mZenModeHelper.addCallback(callback);
 
         zenRule.setEnabled(false);
-        mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, "", Process.SYSTEM_UID,
-                FROM_SYSTEM_OR_SYSTEMUI);
+        mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI,
+                "", Process.SYSTEM_UID);
 
         assertTrue(latch.await(500, TimeUnit.MILLISECONDS));
         assertEquals(AUTOMATIC_RULE_STATUS_DISABLED, actualStatus[0]);
@@ -3184,7 +3197,7 @@
                 null,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, false);
         final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(),
-                zenRule, "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+                zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         CountDownLatch latch = new CountDownLatch(1);
         final int[] actualStatus = new int[1];
@@ -3200,8 +3213,8 @@
         mZenModeHelper.addCallback(callback);
 
         zenRule.setEnabled(true);
-        mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, "", Process.SYSTEM_UID,
-                FROM_SYSTEM_OR_SYSTEMUI);
+        mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI,
+                "", Process.SYSTEM_UID);
 
         assertTrue(latch.await(500, TimeUnit.MILLISECONDS));
         assertEquals(AUTOMATIC_RULE_STATUS_ENABLED, actualStatus[0]);
@@ -3220,7 +3233,7 @@
                 null,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
         final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(),
-                zenRule, "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+                zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         CountDownLatch latch = new CountDownLatch(1);
         final int[] actualStatus = new int[1];
@@ -3237,7 +3250,7 @@
 
         mZenModeHelper.setAutomaticZenRuleState(createdId,
                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         assertTrue(latch.await(500, TimeUnit.MILLISECONDS));
         assertEquals(AUTOMATIC_RULE_STATUS_ACTIVATED, actualStatus[0]);
@@ -3256,7 +3269,7 @@
                 null,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
         final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(),
-                zenRule, "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+                zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         CountDownLatch latch = new CountDownLatch(1);
         final int[] actualStatus = new int[2];
@@ -3274,10 +3287,10 @@
 
         mZenModeHelper.setAutomaticZenRuleState(createdId,
                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
-        mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, null, "",
-                Process.SYSTEM_UID, true);
+        mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI,
+                null, "", Process.SYSTEM_UID);
 
         assertTrue(latch.await(500, TimeUnit.MILLISECONDS));
         assertEquals(AUTOMATIC_RULE_STATUS_DEACTIVATED, actualStatus[1]);
@@ -3296,7 +3309,7 @@
                 null,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
         final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(),
-                zenRule, "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+                zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         CountDownLatch latch = new CountDownLatch(1);
         final int[] actualStatus = new int[2];
@@ -3314,11 +3327,11 @@
 
         mZenModeHelper.setAutomaticZenRuleState(createdId,
                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         mZenModeHelper.setAutomaticZenRuleState(createdId,
                 new Condition(zenRule.getConditionId(), "", STATE_FALSE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         assertTrue(latch.await(500, TimeUnit.MILLISECONDS));
         assertEquals(AUTOMATIC_RULE_STATUS_DEACTIVATED, actualStatus[1]);
@@ -3336,21 +3349,21 @@
                 null,
                 NotificationManager.INTERRUPTION_FILTER_PRIORITY, true);
         final String createdId = mZenModeHelper.addAutomaticZenRule(mContext.getPackageName(),
-                zenRule, "test", Process.SYSTEM_UID, FROM_SYSTEM_OR_SYSTEMUI);
+                zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, "test", Process.SYSTEM_UID);
 
         // Event 1: Mimic the rule coming on automatically by setting the Condition to STATE_TRUE
         mZenModeHelper.setAutomaticZenRuleState(createdId,
                 new Condition(zenRule.getConditionId(), "", STATE_TRUE),
-                Process.SYSTEM_UID, true);
+                UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI, Process.SYSTEM_UID);
 
         // Event 2: Snooze rule by turning off DND
-        mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, null, "",
-                Process.SYSTEM_UID, true);
+        mZenModeHelper.setManualZenMode(Global.ZEN_MODE_OFF, null, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI,
+                "", null, Process.SYSTEM_UID);
 
         // Event 3: "User" turns off the automatic rule (sets it to not enabled)
         zenRule.setEnabled(false);
-        mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, "", Process.SYSTEM_UID,
-                FROM_SYSTEM_OR_SYSTEMUI);
+        mZenModeHelper.updateAutomaticZenRule(createdId, zenRule, UPDATE_ORIGIN_SYSTEM_OR_SYSTEMUI,
+                "", Process.SYSTEM_UID);
 
         assertEquals(false, mZenModeHelper.mConfig.automaticRules.get(createdId).snoozing);
     }
@@ -3359,18 +3372,20 @@
     public void testDeviceEffects_applied() {
         mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API);
         mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier);
+        verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(UPDATE_ORIGIN_INIT));
 
         ZenDeviceEffects effects = new ZenDeviceEffects.Builder()
                 .setShouldSuppressAmbientDisplay(true)
                 .setShouldDimWallpaper(true)
                 .build();
         String ruleId = addRuleWithEffects(effects);
-        verify(mDeviceEffectsApplier, never()).apply(any());
+        verifyNoMoreInteractions(mDeviceEffectsApplier);
 
-        mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, CUSTOM_PKG_UID, false);
+        mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP,
+                CUSTOM_PKG_UID);
         mTestableLooper.processAllMessages();
 
-        verify(mDeviceEffectsApplier).apply(eq(effects));
+        verify(mDeviceEffectsApplier).apply(eq(effects), eq(UPDATE_ORIGIN_APP));
     }
 
     @Test
@@ -3380,31 +3395,66 @@
 
         ZenDeviceEffects zde = new ZenDeviceEffects.Builder().setShouldUseNightMode(true).build();
         String ruleId = addRuleWithEffects(zde);
-        mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, CUSTOM_PKG_UID, false);
+        mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP,
+                CUSTOM_PKG_UID);
         mTestableLooper.processAllMessages();
-        verify(mDeviceEffectsApplier).apply(eq(zde));
+        verify(mDeviceEffectsApplier).apply(eq(zde), eq(UPDATE_ORIGIN_APP));
 
-        mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_FALSE, CUSTOM_PKG_UID, false);
+        mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_FALSE, UPDATE_ORIGIN_APP,
+                CUSTOM_PKG_UID);
         mTestableLooper.processAllMessages();
 
-        verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS));
+        verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(UPDATE_ORIGIN_APP));
     }
 
     @Test
+    public void testDeviceEffects_changeToConsolidatedEffects_applied() {
+        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API);
+        mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier);
+        verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(UPDATE_ORIGIN_INIT));
+
+        String ruleId = addRuleWithEffects(
+                new ZenDeviceEffects.Builder().setShouldDisplayGrayscale(true).build());
+        mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP,
+                CUSTOM_PKG_UID);
+        mTestableLooper.processAllMessages();
+        verify(mDeviceEffectsApplier).apply(
+                eq(new ZenDeviceEffects.Builder()
+                        .setShouldDisplayGrayscale(true)
+                        .build()),
+                eq(UPDATE_ORIGIN_APP));
+
+        // Now create and activate a second rule that adds more effects.
+        String secondRuleId = addRuleWithEffects(
+                new ZenDeviceEffects.Builder().setShouldDimWallpaper(true).build());
+        mZenModeHelper.setAutomaticZenRuleState(secondRuleId, CONDITION_TRUE, UPDATE_ORIGIN_APP,
+                CUSTOM_PKG_UID);
+        mTestableLooper.processAllMessages();
+
+        verify(mDeviceEffectsApplier).apply(
+                eq(new ZenDeviceEffects.Builder()
+                        .setShouldDisplayGrayscale(true)
+                        .setShouldDimWallpaper(true)
+                        .build()),
+                eq(UPDATE_ORIGIN_APP));
+    }
+    @Test
     public void testDeviceEffects_noChangeToConsolidatedEffects_notApplied() {
         mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API);
         mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier);
+        verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(UPDATE_ORIGIN_INIT));
 
         ZenDeviceEffects zde = new ZenDeviceEffects.Builder().setShouldUseNightMode(true).build();
         String ruleId = addRuleWithEffects(zde);
-        mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, CUSTOM_PKG_UID, false);
+        mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP,
+                CUSTOM_PKG_UID);
         mTestableLooper.processAllMessages();
-        verify(mDeviceEffectsApplier).apply(eq(zde));
+        verify(mDeviceEffectsApplier).apply(eq(zde), eq(UPDATE_ORIGIN_APP));
 
         // Now create and activate a second rule that doesn't add any more effects.
         String secondRuleId = addRuleWithEffects(zde);
-        mZenModeHelper.setAutomaticZenRuleState(secondRuleId, CONDITION_TRUE, CUSTOM_PKG_UID,
-                false);
+        mZenModeHelper.setAutomaticZenRuleState(secondRuleId, CONDITION_TRUE, UPDATE_ORIGIN_APP,
+                CUSTOM_PKG_UID);
         mTestableLooper.processAllMessages();
 
         verifyNoMoreInteractions(mDeviceEffectsApplier);
@@ -3416,21 +3466,50 @@
 
         ZenDeviceEffects zde = new ZenDeviceEffects.Builder().setShouldUseNightMode(true).build();
         String ruleId = addRuleWithEffects(zde);
-        verify(mDeviceEffectsApplier, never()).apply(any());
+        verify(mDeviceEffectsApplier, never()).apply(any(), anyInt());
 
-        mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, CUSTOM_PKG_UID, false);
+        mZenModeHelper.setAutomaticZenRuleState(ruleId, CONDITION_TRUE, UPDATE_ORIGIN_APP,
+                CUSTOM_PKG_UID);
         mTestableLooper.processAllMessages();
-        verify(mDeviceEffectsApplier, never()).apply(any());
+        verify(mDeviceEffectsApplier, never()).apply(any(), anyInt());
 
         mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier);
-        verify(mDeviceEffectsApplier).apply(eq(zde));
+        verify(mDeviceEffectsApplier).apply(eq(zde), eq(UPDATE_ORIGIN_INIT));
+    }
+
+    @Test
+    public void testDeviceEffects_onUserSwitch_appliedImmediately() {
+        mSetFlagsRule.enableFlags(android.app.Flags.FLAG_MODES_API);
+        mZenModeHelper.setDeviceEffectsApplier(mDeviceEffectsApplier);
+        verify(mDeviceEffectsApplier).apply(eq(NO_EFFECTS), eq(UPDATE_ORIGIN_INIT));
+
+        // Initialize default configurations (default rules) for both users.
+        mZenModeHelper.onUserSwitched(1);
+        mZenModeHelper.onUserSwitched(2);
+
+        // Current user is now 2. Tweak a rule for user 1 so it's active and has effects.
+        ZenRule user1Rule = mZenModeHelper.mConfigs.get(1).automaticRules.valueAt(0);
+        user1Rule.enabled = true;
+        user1Rule.condition = new Condition(user1Rule.conditionId, "on", STATE_TRUE);
+        user1Rule.zenDeviceEffects = new ZenDeviceEffects.Builder()
+                .setShouldDimWallpaper(true)
+                .setShouldUseNightMode(true)
+                .build();
+        verifyNoMoreInteractions(mDeviceEffectsApplier);
+
+        mZenModeHelper.onUserSwitched(1);
+        mTestableLooper.processAllMessages();
+
+        verify(mDeviceEffectsApplier).apply(eq(user1Rule.zenDeviceEffects),
+                eq(UPDATE_ORIGIN_INIT_USER));
     }
 
     private String addRuleWithEffects(ZenDeviceEffects effects) {
         AutomaticZenRule rule = new AutomaticZenRule.Builder("Test", CONDITION_ID)
                 .setDeviceEffects(effects)
                 .build();
-        return mZenModeHelper.addAutomaticZenRule("pkg", rule, "", CUSTOM_PKG_UID, FROM_APP);
+        return mZenModeHelper.addAutomaticZenRule("pkg", rule, UPDATE_ORIGIN_APP, "",
+                CUSTOM_PKG_UID);
     }
 
     @Test
@@ -3455,7 +3534,7 @@
 
         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID,
                 ZEN_MODE_IMPORTANT_INTERRUPTIONS);
-        mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, "test", "test", 0, true);
+        mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, UPDATE_ORIGIN_APP, "test", "test", 0);
         assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(1);
 
         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID,
@@ -3505,7 +3584,7 @@
         assertThat(mZenModeHelper.mConfig.automaticRules).hasSize(1);
         assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).snoozing).isFalse();
 
-        mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, "test", "test", 0, true);
+        mZenModeHelper.setManualZenMode(ZEN_MODE_OFF, null, UPDATE_ORIGIN_APP, "test", "test", 0);
         assertThat(mZenModeHelper.mConfig.automaticRules.valueAt(0).snoozing).isTrue();
 
         mZenModeHelper.applyGlobalZenModeAsImplicitZenRule(CUSTOM_PKG_NAME, CUSTOM_PKG_UID,