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

Commit 5a43aaa6 authored by Julia Reynolds's avatar Julia Reynolds
Browse files

Clean up orphaned zen rules, synchronize better.

(If a rule was restored to the device but the user didn't restore
the matching app).

Bug: 25472361
Change-Id: Icaefd0d1fca78ff351937fbe553ae72922a5457f
parent b6212537
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -109,7 +109,6 @@ public class ZenModeConditions implements ConditionProviders.Callback {
        if (DEBUG) Log.d(TAG, "onConditionChanged " + id + " " + condition);
        ZenModeConfig config = mHelper.getConfig();
        if (config == null) return;
        config = config.copy();
        boolean updated = updateCondition(id, condition, config.manualRule);
        for (ZenRule automaticRule : config.automaticRules.values()) {
            updated |= updateCondition(id, condition, automaticRule);
+113 −72
Original line number Diff line number Diff line
@@ -77,6 +77,9 @@ public class ZenModeHelper {
    static final String TAG = "ZenModeHelper";
    static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);

    // The amount of time rules instances can exist without their owning app being installed.
    private static final int RULE_INSTANCE_GRACE_PERIOD = 1000 * 60 * 60 * 72;

    private final Context mContext;
    private final H mHandler;
    private final SettingsObserver mSettingsObserver;
@@ -93,6 +96,7 @@ public class ZenModeHelper {
    private int mUser = UserHandle.USER_SYSTEM;
    private ZenModeConfig mConfig;
    private AudioManagerInternal mAudioManager;
    private PackageManager mPm;
    private boolean mEffectsSuppressed;

    public ZenModeHelper(Context context, Looper looper, ConditionProviders conditionProviders) {
@@ -170,7 +174,9 @@ public class ZenModeHelper {
        if (mAudioManager != null) {
            mAudioManager.setRingerModeDelegate(mRingerModeDelegate);
        }
        mPm = mContext.getPackageManager();
        mHandler.postMetricsTimer();
        cleanUpZenRules();
        evaluateZenMode("onSystemReady", true);
    }

@@ -184,8 +190,11 @@ public class ZenModeHelper {
            config = mDefaultConfig.copy();
            config.user = user;
        }
        synchronized (mConfig) {
            setConfig(config, "onUserSwitched");
        }
        cleanUpZenRules();
    }

    public void onUserRemoved(int user) {
        if (user < UserHandle.USER_SYSTEM) return;
@@ -253,7 +262,7 @@ public class ZenModeHelper {
                throw new IllegalArgumentException("Rule already exists");
            }
            newConfig = mConfig.copy();
        }

            ZenRule rule = new ZenRule();
            populateZenRule(automaticZenRule, rule, true);
            newConfig.automaticRules.put(rule.id, rule);
@@ -263,6 +272,7 @@ public class ZenModeHelper {
                return null;
            }
        }
    }

    public boolean updateAutomaticZenRule(AutomaticZenRule automaticZenRule, String reason) {
        ZenModeConfig newConfig;
@@ -273,7 +283,6 @@ public class ZenModeHelper {
                        + " reason=" + reason);
            }
            newConfig = mConfig.copy();
        }
            final String ruleId = automaticZenRule.getId();
            ZenModeConfig.ZenRule rule;
            if (ruleId == null) {
@@ -289,13 +298,13 @@ public class ZenModeHelper {
            newConfig.automaticRules.put(ruleId, rule);
            return setConfig(newConfig, reason, true);
        }
    }

    public boolean removeAutomaticZenRule(String id, String reason) {
        ZenModeConfig newConfig;
        synchronized (mConfig) {
            if (mConfig == null) return false;
            newConfig = mConfig.copy();
        }
            ZenRule rule = newConfig.automaticRules.get(id);
            if (rule == null) return false;
            if (canManageAutomaticZenRule(rule)) {
@@ -307,13 +316,13 @@ public class ZenModeHelper {
            }
            return setConfig(newConfig, reason, true);
        }
    }

    public boolean removeAutomaticZenRules(String packageName, String reason) {
        ZenModeConfig newConfig;
        synchronized (mConfig) {
            if (mConfig == null) return false;
            newConfig = mConfig.copy();
        }
            for (int i = newConfig.automaticRules.size() - 1; i >= 0; i--) {
                ZenRule rule = newConfig.automaticRules.get(newConfig.automaticRules.keyAt(i));
                if (rule.component.getPackageName().equals(packageName)
@@ -323,6 +332,7 @@ public class ZenModeHelper {
            }
            return setConfig(newConfig, reason, true);
        }
    }

    public boolean canManageAutomaticZenRule(ZenRule rule) {
        final int callingUid = Binder.getCallingUid();
@@ -332,8 +342,7 @@ public class ZenModeHelper {
                == PackageManager.PERMISSION_GRANTED) {
            return true;
        } else {
            String[] packages =
                    mContext.getPackageManager().getPackagesForUid(Binder.getCallingUid());
            String[] packages = mPm.getPackagesForUid(Binder.getCallingUid());
            if (packages != null) {
                final int packageCount = packages.length;
                for (int i = 0; i < packageCount; i++) {
@@ -384,7 +393,6 @@ public class ZenModeHelper {
                    + " conditionId=" + conditionId + " reason=" + reason
                    + " setRingerMode=" + setRingerMode);
            newConfig = mConfig.copy();
        }
            if (zenMode == Global.ZEN_MODE_OFF) {
                newConfig.manualRule = null;
                for (ZenRule automaticRule : newConfig.automaticRules.values()) {
@@ -401,6 +409,7 @@ public class ZenModeHelper {
            }
            setConfig(newConfig, reason, setRingerMode);
        }
    }

    public void dump(PrintWriter pw, String prefix) {
        pw.print(prefix); pw.print("mZenMode=");
@@ -450,18 +459,22 @@ public class ZenModeHelper {
                    return;
                }
                config.manualRule = null;  // don't restore the manual rule
                long time = System.currentTimeMillis();
                if (config.automaticRules != null) {
                    for (ZenRule automaticRule : config.automaticRules.values()) {
                        // don't restore transient state from restored automatic rules
                        automaticRule.snoozing = false;
                        automaticRule.condition = null;
                        automaticRule.creationTime = time;
                    }
                }
            }
            if (DEBUG) Log.d(TAG, "readXml");
            synchronized (mConfig) {
                setConfig(config, "readXml");
            }
        }
    }

    public void writeXml(XmlSerializer out, boolean forBackup) throws IOException {
        final int N = mConfigs.size();
@@ -484,11 +497,39 @@ public class ZenModeHelper {

    public void setNotificationPolicy(Policy policy) {
        if (policy == null || mConfig == null) return;
        synchronized (mConfig) {
            final ZenModeConfig newConfig = mConfig.copy();
            newConfig.applyNotificationPolicy(policy);
            setConfig(newConfig, "setNotificationPolicy");
        }
    }

    /**
     * Removes old rule instances whose owner is not installed.
     */
    private void cleanUpZenRules() {
        long currentTime = System.currentTimeMillis();
        synchronized (mConfig) {
            final ZenModeConfig newConfig = mConfig.copy();
            if (newConfig.automaticRules != null) {
                for (int i = newConfig.automaticRules.size() - 1; i >= 0; i--) {
                    ZenRule rule = newConfig.automaticRules.get(newConfig.automaticRules.keyAt(i));
                    if (RULE_INSTANCE_GRACE_PERIOD < (currentTime - rule.creationTime)) {
                        try {
                            mPm.getPackageInfo(rule.component.getPackageName(), 0);
                        } catch (PackageManager.NameNotFoundException e) {
                            newConfig.automaticRules.removeAt(i);
                        }
                    }
                }
            }
            setConfig(newConfig, "cleanUpZenRules");
        }
    }

    /**
     * @return a copy of the zen mode configuration
     */
    public ZenModeConfig getConfig() {
        synchronized (mConfig) {
            return mConfig.copy();
@@ -517,7 +558,6 @@ public class ZenModeHelper {
                return true;
            }
            mConditions.evaluateConfig(config, false /*processSubscriptions*/);  // may modify config
            synchronized (mConfig) {
            mConfigs.put(config.user, config);
            if (DEBUG) Log.d(TAG, "setConfig reason=" + reason, new Throwable());
            ZenLog.traceConfig(reason, mConfig, config);
@@ -530,7 +570,6 @@ public class ZenModeHelper {
            if (policyChanged) {
                dispatchOnPolicyChanged();
            }
            }
            final String val = Integer.toString(config.hashCode());
            Global.putString(mContext.getContentResolver(), Global.ZEN_MODE_CONFIG_ETAG, val);
            if (!evaluateZenMode(reason, setRingerMode)) {
@@ -994,7 +1033,9 @@ public class ZenModeHelper {
                    break;
                case MSG_SET_CONFIG:
                    ConfigMessageData configData = (ConfigMessageData)msg.obj;
                    synchronized (mConfig) {
                        setConfig(configData.config, configData.reason);
                    }
                    break;
            }
        }