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

Commit 9758cff8 authored by Beverly's avatar Beverly
Browse files

QS DND tile secondary text added

Bug: 63077372
Test: manual (set automatic rules, toggle dnd manually in settings)
Change-Id: Ibe598423e4c1d668bc7c828ff66c9b572cc21192
parent 7999ba90
Loading
Loading
Loading
Loading
+101 −0
Original line number Diff line number Diff line
@@ -19,6 +19,8 @@ package com.android.systemui.qs.tiles;
import static android.provider.Settings.Global.ZEN_MODE_ALARMS;
import static android.provider.Settings.Global.ZEN_MODE_OFF;

import android.app.AlarmManager;
import android.app.AlarmManager.AlarmClockInfo;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -27,9 +29,11 @@ import android.content.SharedPreferences;
import android.content.SharedPreferences.OnSharedPreferenceChangeListener;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.net.Uri;
import android.os.UserManager;
import android.provider.Settings;
import android.provider.Settings.Global;
import android.service.notification.ScheduleCalendar;
import android.service.notification.ZenModeConfig;
import android.service.notification.ZenModeConfig.ZenRule;
import android.service.quicksettings.Tile;
@@ -178,6 +182,7 @@ public class DndTile extends QSTileImpl<BooleanState> {
        state.state = state.value ? Tile.STATE_ACTIVE : Tile.STATE_INACTIVE;
        state.slash.isSlashed = !state.value;
        state.label = getTileLabel();
        state.secondaryLabel = getSecondaryLabel(zen != Global.ZEN_MODE_OFF);
        checkIfRestrictionEnforcedByAdminOnly(state, UserManager.DISALLOW_ADJUST_VOLUME);
        switch (zen) {
            case Global.ZEN_MODE_IMPORTANT_INTERRUPTIONS:
@@ -209,6 +214,102 @@ public class DndTile extends QSTileImpl<BooleanState> {
        state.expandedAccessibilityClassName = Switch.class.getName();
    }

    /**
     * Returns the secondary label to use for the given instance of do not disturb.
     * - If turned on manually and end time is known, returns end time.
     * - If turned on by an automatic rule, returns the automatic rule name.
     * - If on due to an app, returns the app name.
     * - If there's a combination of rules/apps that trigger, then shows the one that will
     *  last the longest if applicable.
     * @return null if do not disturb is off.
     */
    private String getSecondaryLabel(boolean zenOn) {
        if (!zenOn) {
            return null;
        }

        ZenModeConfig config = mController.getConfig();
        String secondaryText = "";
        long latestEndTime = -1;

        // DND turned on by manual rule
        if (config.manualRule != null) {
            final Uri id = config.manualRule.conditionId;
            if (config.manualRule.enabler != null) {
                // app triggered manual rule
                String appName = ZenModeConfig.getOwnerCaption(mContext, config.manualRule.enabler);
                if (!appName.isEmpty()) {
                    secondaryText = appName;
                }
            } else {
                if (id == null) {
                    // Do not disturb manually triggered to remain on forever until turned off
                    // No subtext
                    return null;
                } else {
                    latestEndTime = ZenModeConfig.tryParseCountdownConditionId(id);
                    if (latestEndTime > 0) {
                        final CharSequence formattedTime = ZenModeConfig.getFormattedTime(mContext,
                                latestEndTime, ZenModeConfig.isToday(latestEndTime),
                                mContext.getUserId());
                        secondaryText = mContext.getString(R.string.qs_dnd_until, formattedTime);
                    }
                }
            }
        }

        // DND turned on by an automatic rule
        for (ZenModeConfig.ZenRule automaticRule : config.automaticRules.values()) {
            if (automaticRule.isAutomaticActive()) {
                if (ZenModeConfig.isValidEventConditionId(automaticRule.conditionId) ||
                        ZenModeConfig.isValidScheduleConditionId(automaticRule.conditionId)) {
                    // set text if automatic rule end time is the latest active rule end time
                    long endTime = parseAutomaticRuleEndTime(automaticRule.conditionId);
                    if (endTime > latestEndTime) {
                        latestEndTime = endTime;
                        secondaryText = automaticRule.name;
                    }
                } else {
                    // set text if 3rd party rule
                    return automaticRule.name;
                }
            }
        }

        return !secondaryText.equals("") ? secondaryText : null;
    }

    private long parseAutomaticRuleEndTime(Uri id) {
        if (ZenModeConfig.isValidEventConditionId(id)) {
            // cannot look up end times for events
            return Long.MAX_VALUE;
        }

        if (ZenModeConfig.isValidScheduleConditionId(id)) {
            ScheduleCalendar schedule = ZenModeConfig.toScheduleCalendar(id);
            long endTimeMs = schedule.getNextChangeTime(System.currentTimeMillis());

            // check if automatic rule will end on next alarm
            if (schedule.exitAtAlarm()) {
                long nextAlarm = getNextAlarm(mContext);
                schedule.maybeSetNextAlarm(System.currentTimeMillis(), nextAlarm);
                if (schedule.shouldExitForAlarm(endTimeMs)) {
                    return nextAlarm;
                }
            }

            return endTimeMs;
        }

        return -1;
    }

    private long getNextAlarm(Context context) {
        final AlarmManager alarms = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE);
        final AlarmClockInfo info = alarms.getNextAlarmClock(mContext.getUserId());
        return info != null ? info.getTriggerTime() : 0;
    }

    @Override
    public int getMetricsCategory() {
        return MetricsEvent.QS_DND;