/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License
 */

package com.android.server.notification;

import static android.service.notification.NotificationListenerService.Ranking.IMPORTANCE_HIGH;

import android.app.Notification;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.os.SystemClock;
import android.text.TextUtils;
import android.util.ArraySet;
import android.util.Log;

import com.android.internal.logging.MetricsLogger;
import com.android.server.notification.NotificationManagerService.DumpFilter;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import java.io.PrintWriter;
import java.util.ArrayDeque;
import java.util.Calendar;
import java.util.GregorianCalendar;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;

/**
 * Keeps track of notification activity, display, and user interaction.
 *
 * <p>This class receives signals from NoMan and keeps running stats of
 * notification usage. Some metrics are updated as events occur. Others, namely
 * those involving durations, are updated as the notification is canceled.</p>
 *
 * <p>This class is thread-safe.</p>
 *
 * {@hide}
 */
public class NotificationUsageStats {
    private static final String TAG = "NotificationUsageStats";

    private static final boolean ENABLE_AGGREGATED_IN_MEMORY_STATS = true;
    private static final boolean ENABLE_SQLITE_LOG = true;
    private static final AggregatedStats[] EMPTY_AGGREGATED_STATS = new AggregatedStats[0];
    private static final String DEVICE_GLOBAL_STATS = "__global"; // packages start with letters
    private static final int MSG_EMIT = 1;

    private static final boolean DEBUG = false;
    public static final int TEN_SECONDS = 1000 * 10;
    public static final int FOUR_HOURS = 1000 * 60 * 60 * 4;
    private static final long EMIT_PERIOD = DEBUG ? TEN_SECONDS : FOUR_HOURS;

    // Guarded by synchronized(this).
    private final Map<String, AggregatedStats> mStats = new HashMap<>();
    private final ArrayDeque<AggregatedStats[]> mStatsArrays = new ArrayDeque<>();
    private ArraySet<String> mStatExpiredkeys = new ArraySet<>();
    private final SQLiteLog mSQLiteLog;
    private final Context mContext;
    private final Handler mHandler;
    private long mLastEmitTime;

    public NotificationUsageStats(Context context) {
        mContext = context;
        mLastEmitTime = SystemClock.elapsedRealtime();
        mSQLiteLog = ENABLE_SQLITE_LOG ? new SQLiteLog(context) : null;
        mHandler = new Handler(mContext.getMainLooper()) {
            @Override
            public void handleMessage(Message msg) {
                switch (msg.what) {
                    case MSG_EMIT:
                        emit();
                        break;
                    default:
                        Log.wtf(TAG, "Unknown message type: " + msg.what);
                        break;
                }
            }
        };
        mHandler.sendEmptyMessageDelayed(MSG_EMIT, EMIT_PERIOD);
    }

    /**
     * Called when a notification has been posted.
     */
    public synchronized float getAppEnqueueRate(String packageName) {
        AggregatedStats stats = getOrCreateAggregatedStatsLocked(packageName);
        if (stats != null) {
            return stats.getEnqueueRate(SystemClock.elapsedRealtime());
        } else {
            return 0f;
        }
    }

    /**
     * Called when a notification is tentatively enqueued by an app, before rate checking.
     */
    public synchronized void registerEnqueuedByApp(String packageName) {
        AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(packageName);
        for (AggregatedStats stats : aggregatedStatsArray) {
            stats.numEnqueuedByApp++;
        }
        releaseAggregatedStatsLocked(aggregatedStatsArray);
    }

    /**
     * Called when a notification has been posted.
     */
    public synchronized void registerPostedByApp(NotificationRecord notification) {
        final long now = SystemClock.elapsedRealtime();
        notification.stats.posttimeElapsedMs = now;

        AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification);
        for (AggregatedStats stats : aggregatedStatsArray) {
            stats.numPostedByApp++;
            stats.updateInterarrivalEstimate(now);
            stats.countApiUse(notification);
        }
        releaseAggregatedStatsLocked(aggregatedStatsArray);
        if (ENABLE_SQLITE_LOG) {
            mSQLiteLog.logPosted(notification);
        }
    }

    /**
     * Called when a notification has been updated.
     */
    public synchronized void registerUpdatedByApp(NotificationRecord notification,
            NotificationRecord old) {
        notification.stats.updateFrom(old.stats);
        AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification);
        for (AggregatedStats stats : aggregatedStatsArray) {
            stats.numUpdatedByApp++;
            stats.updateInterarrivalEstimate(SystemClock.elapsedRealtime());
            stats.countApiUse(notification);
        }
        releaseAggregatedStatsLocked(aggregatedStatsArray);
        if (ENABLE_SQLITE_LOG) {
            mSQLiteLog.logPosted(notification);
        }
    }

    /**
     * Called when the originating app removed the notification programmatically.
     */
    public synchronized void registerRemovedByApp(NotificationRecord notification) {
        notification.stats.onRemoved();
        AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification);
        for (AggregatedStats stats : aggregatedStatsArray) {
            stats.numRemovedByApp++;
        }
        releaseAggregatedStatsLocked(aggregatedStatsArray);
        if (ENABLE_SQLITE_LOG) {
            mSQLiteLog.logRemoved(notification);
        }
    }

    /**
     * Called when the user dismissed the notification via the UI.
     */
    public synchronized void registerDismissedByUser(NotificationRecord notification) {
        MetricsLogger.histogram(mContext, "note_dismiss_longevity",
                (int) (System.currentTimeMillis() - notification.getRankingTimeMs()) / (60 * 1000));
        notification.stats.onDismiss();
        if (ENABLE_SQLITE_LOG) {
            mSQLiteLog.logDismissed(notification);
        }
    }

    /**
     * Called when the user clicked the notification in the UI.
     */
    public synchronized void registerClickedByUser(NotificationRecord notification) {
        MetricsLogger.histogram(mContext, "note_click_longevity",
                (int) (System.currentTimeMillis() - notification.getRankingTimeMs()) / (60 * 1000));
        notification.stats.onClick();
        if (ENABLE_SQLITE_LOG) {
            mSQLiteLog.logClicked(notification);
        }
    }

    public synchronized void registerPeopleAffinity(NotificationRecord notification, boolean valid,
            boolean starred, boolean cached) {
        AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification);
        for (AggregatedStats stats : aggregatedStatsArray) {
            if (valid) {
                stats.numWithValidPeople++;
            }
            if (starred) {
                stats.numWithStaredPeople++;
            }
            if (cached) {
                stats.numPeopleCacheHit++;
            } else {
                stats.numPeopleCacheMiss++;
            }
        }
        releaseAggregatedStatsLocked(aggregatedStatsArray);
    }

    public synchronized void registerBlocked(NotificationRecord notification) {
        AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification);
        for (AggregatedStats stats : aggregatedStatsArray) {
            stats.numBlocked++;
        }
        releaseAggregatedStatsLocked(aggregatedStatsArray);
    }

    public synchronized void registerSuspendedByAdmin(NotificationRecord notification) {
        AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(notification);
        for (AggregatedStats stats : aggregatedStatsArray) {
            stats.numSuspendedByAdmin++;
        }
        releaseAggregatedStatsLocked(aggregatedStatsArray);
    }

    public synchronized void registerOverRateQuota(String packageName) {
        AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(packageName);
        for (AggregatedStats stats : aggregatedStatsArray) {
            stats.numRateViolations++;
        }
    }

    public synchronized void registerOverCountQuota(String packageName) {
        AggregatedStats[] aggregatedStatsArray = getAggregatedStatsLocked(packageName);
        for (AggregatedStats stats : aggregatedStatsArray) {
            stats.numQuotaViolations++;
        }
    }

    // Locked by this.
    private AggregatedStats[] getAggregatedStatsLocked(NotificationRecord record) {
        return getAggregatedStatsLocked(record.sbn.getPackageName());
    }

    // Locked by this.
    private AggregatedStats[] getAggregatedStatsLocked(String packageName) {
        if (!ENABLE_AGGREGATED_IN_MEMORY_STATS) {
            return EMPTY_AGGREGATED_STATS;
        }

        AggregatedStats[] array = mStatsArrays.poll();
        if (array == null) {
            array = new AggregatedStats[2];
        }
        array[0] = getOrCreateAggregatedStatsLocked(DEVICE_GLOBAL_STATS);
        array[1] = getOrCreateAggregatedStatsLocked(packageName);
        return array;
    }

    // Locked by this.
    private void releaseAggregatedStatsLocked(AggregatedStats[] array) {
        for(int i = 0; i < array.length; i++) {
            array[i] = null;
        }
        mStatsArrays.offer(array);
    }

    // Locked by this.
    private AggregatedStats getOrCreateAggregatedStatsLocked(String key) {
        AggregatedStats result = mStats.get(key);
        if (result == null) {
            result = new AggregatedStats(mContext, key);
            mStats.put(key, result);
        }
        result.mLastAccessTime = SystemClock.elapsedRealtime();
        return result;
    }

    public synchronized JSONObject dumpJson(DumpFilter filter) {
        JSONObject dump = new JSONObject();
        if (ENABLE_AGGREGATED_IN_MEMORY_STATS) {
            try {
                JSONArray aggregatedStats = new JSONArray();
                for (AggregatedStats as : mStats.values()) {
                    if (filter != null && !filter.matches(as.key))
                        continue;
                    aggregatedStats.put(as.dumpJson());
                }
                dump.put("current", aggregatedStats);
            } catch (JSONException e) {
                // pass
            }
        }
        if (ENABLE_SQLITE_LOG) {
            try {
                dump.put("historical", mSQLiteLog.dumpJson(filter));
            } catch (JSONException e) {
                // pass
            }
        }
        return dump;
    }

    public synchronized void dump(PrintWriter pw, String indent, DumpFilter filter) {
        if (ENABLE_AGGREGATED_IN_MEMORY_STATS) {
            for (AggregatedStats as : mStats.values()) {
                if (filter != null && !filter.matches(as.key))
                    continue;
                as.dump(pw, indent);
            }
            pw.println(indent + "mStatsArrays.size(): " + mStatsArrays.size());
            pw.println(indent + "mStats.size(): " + mStats.size());
        }
        if (ENABLE_SQLITE_LOG) {
            mSQLiteLog.dump(pw, indent, filter);
        }
    }

    public synchronized void emit() {
        AggregatedStats stats = getOrCreateAggregatedStatsLocked(DEVICE_GLOBAL_STATS);
        stats.emit();
        mHandler.removeMessages(MSG_EMIT);
        mHandler.sendEmptyMessageDelayed(MSG_EMIT, EMIT_PERIOD);
        for(String key: mStats.keySet()) {
            if (mStats.get(key).mLastAccessTime < mLastEmitTime) {
                mStatExpiredkeys.add(key);
            }
        }
        for(String key: mStatExpiredkeys) {
            mStats.remove(key);
        }
        mStatExpiredkeys.clear();
        mLastEmitTime = SystemClock.elapsedRealtime();
    }

    /**
     * Aggregated notification stats.
     */
    private static class AggregatedStats {

        private final Context mContext;
        public final String key;
        private final long mCreated;
        private AggregatedStats mPrevious;

        // ---- Updated as the respective events occur.
        public int numEnqueuedByApp;
        public int numPostedByApp;
        public int numUpdatedByApp;
        public int numRemovedByApp;
        public int numPeopleCacheHit;
        public int numPeopleCacheMiss;;
        public int numWithStaredPeople;
        public int numWithValidPeople;
        public int numBlocked;
        public int numSuspendedByAdmin;
        public int numWithActions;
        public int numPrivate;
        public int numSecret;
        public int numWithBigText;
        public int numWithBigPicture;
        public int numForegroundService;
        public int numOngoing;
        public int numAutoCancel;
        public int numWithLargeIcon;
        public int numWithInbox;
        public int numWithMediaSession;
        public int numWithTitle;
        public int numWithText;
        public int numWithSubText;
        public int numWithInfoText;
        public int numInterrupt;
        public ImportanceHistogram noisyImportance;
        public ImportanceHistogram quietImportance;
        public ImportanceHistogram finalImportance;
        public RateEstimator enqueueRate;
        public int numRateViolations;
        public int numQuotaViolations;
        public long mLastAccessTime;

        public AggregatedStats(Context context, String key) {
            this.key = key;
            mContext = context;
            mCreated = SystemClock.elapsedRealtime();
            noisyImportance = new ImportanceHistogram(context, "note_imp_noisy_");
            quietImportance = new ImportanceHistogram(context, "note_imp_quiet_");
            finalImportance = new ImportanceHistogram(context, "note_importance_");
            enqueueRate = new RateEstimator();
        }

        public AggregatedStats getPrevious() {
            if (mPrevious == null) {
                mPrevious = new AggregatedStats(mContext, key);
            }
            return mPrevious;
        }

        public void countApiUse(NotificationRecord record) {
            final Notification n = record.getNotification();
            if (n.actions != null) {
                numWithActions++;
            }

            if ((n.flags & Notification.FLAG_FOREGROUND_SERVICE) != 0) {
                numForegroundService++;
            }

            if ((n.flags & Notification.FLAG_ONGOING_EVENT) != 0) {
                numOngoing++;
            }

            if ((n.flags & Notification.FLAG_AUTO_CANCEL) != 0) {
                numAutoCancel++;
            }

            if ((n.defaults & Notification.DEFAULT_SOUND) != 0 ||
                    (n.defaults & Notification.DEFAULT_VIBRATE) != 0 ||
                    n.sound != null || n.vibrate != null) {
                numInterrupt++;
            }

            switch (n.visibility) {
                case Notification.VISIBILITY_PRIVATE:
                    numPrivate++;
                    break;
                case Notification.VISIBILITY_SECRET:
                    numSecret++;
                    break;
            }

            if (record.stats.isNoisy) {
                noisyImportance.increment(record.stats.requestedImportance);
            } else {
                quietImportance.increment(record.stats.requestedImportance);
            }
            finalImportance.increment(record.getImportance());

            final Set<String> names = n.extras.keySet();
            if (names.contains(Notification.EXTRA_BIG_TEXT)) {
                numWithBigText++;
            }
            if (names.contains(Notification.EXTRA_PICTURE)) {
                numWithBigPicture++;
            }
            if (names.contains(Notification.EXTRA_LARGE_ICON)) {
                numWithLargeIcon++;
            }
            if (names.contains(Notification.EXTRA_TEXT_LINES)) {
                numWithInbox++;
            }
            if (names.contains(Notification.EXTRA_MEDIA_SESSION)) {
                numWithMediaSession++;
            }
            if (names.contains(Notification.EXTRA_TITLE) &&
                    !TextUtils.isEmpty(n.extras.getCharSequence(Notification.EXTRA_TITLE))) {
                numWithTitle++;
            }
            if (names.contains(Notification.EXTRA_TEXT) &&
                    !TextUtils.isEmpty(n.extras.getCharSequence(Notification.EXTRA_TEXT))) {
                numWithText++;
            }
            if (names.contains(Notification.EXTRA_SUB_TEXT) &&
                    !TextUtils.isEmpty(n.extras.getCharSequence(Notification.EXTRA_SUB_TEXT))) {
                numWithSubText++;
            }
            if (names.contains(Notification.EXTRA_INFO_TEXT) &&
                    !TextUtils.isEmpty(n.extras.getCharSequence(Notification.EXTRA_INFO_TEXT))) {
                numWithInfoText++;
            }
        }

        public void emit() {
            AggregatedStats previous = getPrevious();
            maybeCount("note_enqueued", (numEnqueuedByApp - previous.numEnqueuedByApp));
            maybeCount("note_post", (numPostedByApp - previous.numPostedByApp));
            maybeCount("note_update", (numUpdatedByApp - previous.numUpdatedByApp));
            maybeCount("note_remove", (numRemovedByApp - previous.numRemovedByApp));
            maybeCount("note_with_people", (numWithValidPeople - previous.numWithValidPeople));
            maybeCount("note_with_stars", (numWithStaredPeople - previous.numWithStaredPeople));
            maybeCount("people_cache_hit", (numPeopleCacheHit - previous.numPeopleCacheHit));
            maybeCount("people_cache_miss", (numPeopleCacheMiss - previous.numPeopleCacheMiss));
            maybeCount("note_blocked", (numBlocked - previous.numBlocked));
            maybeCount("note_suspended", (numSuspendedByAdmin - previous.numSuspendedByAdmin));
            maybeCount("note_with_actions", (numWithActions - previous.numWithActions));
            maybeCount("note_private", (numPrivate - previous.numPrivate));
            maybeCount("note_secret", (numSecret - previous.numSecret));
            maybeCount("note_interupt", (numInterrupt - previous.numInterrupt));
            maybeCount("note_big_text", (numWithBigText - previous.numWithBigText));
            maybeCount("note_big_pic", (numWithBigPicture - previous.numWithBigPicture));
            maybeCount("note_fg", (numForegroundService - previous.numForegroundService));
            maybeCount("note_ongoing", (numOngoing - previous.numOngoing));
            maybeCount("note_auto", (numAutoCancel - previous.numAutoCancel));
            maybeCount("note_large_icon", (numWithLargeIcon - previous.numWithLargeIcon));
            maybeCount("note_inbox", (numWithInbox - previous.numWithInbox));
            maybeCount("note_media", (numWithMediaSession - previous.numWithMediaSession));
            maybeCount("note_title", (numWithTitle - previous.numWithTitle));
            maybeCount("note_text", (numWithText - previous.numWithText));
            maybeCount("note_sub_text", (numWithSubText - previous.numWithSubText));
            maybeCount("note_info_text", (numWithInfoText - previous.numWithInfoText));
            maybeCount("note_over_rate", (numRateViolations - previous.numRateViolations));
            maybeCount("note_over_quota", (numQuotaViolations - previous.numQuotaViolations));
            noisyImportance.maybeCount(previous.noisyImportance);
            quietImportance.maybeCount(previous.quietImportance);
            finalImportance.maybeCount(previous.finalImportance);

            previous.numEnqueuedByApp = numEnqueuedByApp;
            previous.numPostedByApp = numPostedByApp;
            previous.numUpdatedByApp = numUpdatedByApp;
            previous.numRemovedByApp = numRemovedByApp;
            previous.numPeopleCacheHit = numPeopleCacheHit;
            previous.numPeopleCacheMiss = numPeopleCacheMiss;
            previous.numWithStaredPeople = numWithStaredPeople;
            previous.numWithValidPeople = numWithValidPeople;
            previous.numBlocked = numBlocked;
            previous.numSuspendedByAdmin = numSuspendedByAdmin;
            previous.numWithActions = numWithActions;
            previous.numPrivate = numPrivate;
            previous.numSecret = numSecret;
            previous.numInterrupt = numInterrupt;
            previous.numWithBigText = numWithBigText;
            previous.numWithBigPicture = numWithBigPicture;
            previous.numForegroundService = numForegroundService;
            previous.numOngoing = numOngoing;
            previous.numAutoCancel = numAutoCancel;
            previous.numWithLargeIcon = numWithLargeIcon;
            previous.numWithInbox = numWithInbox;
            previous.numWithMediaSession = numWithMediaSession;
            previous.numWithTitle = numWithTitle;
            previous.numWithText = numWithText;
            previous.numWithSubText = numWithSubText;
            previous.numWithInfoText = numWithInfoText;
            previous.numRateViolations = numRateViolations;
            previous.numQuotaViolations = numQuotaViolations;
            noisyImportance.update(previous.noisyImportance);
            quietImportance.update(previous.quietImportance);
            finalImportance.update(previous.finalImportance);
        }

        void maybeCount(String name, int value) {
            if (value > 0) {
                MetricsLogger.count(mContext, name, value);
            }
        }

        public void dump(PrintWriter pw, String indent) {
            pw.println(toStringWithIndent(indent));
        }

        @Override
        public String toString() {
            return toStringWithIndent("");
        }

        /** @return the enqueue rate if there were a new enqueue event right now. */
        public float getEnqueueRate() {
            return getEnqueueRate(SystemClock.elapsedRealtime());
        }

        public float getEnqueueRate(long now) {
            return enqueueRate.getRate(now);
        }

        public void updateInterarrivalEstimate(long now) {
            enqueueRate.update(now);
        }

        private String toStringWithIndent(String indent) {
            StringBuilder output = new StringBuilder();
            output.append(indent).append("AggregatedStats{\n");
            String indentPlusTwo = indent + "  ";
            output.append(indentPlusTwo);
            output.append("key='").append(key).append("',\n");
            output.append(indentPlusTwo);
            output.append("numEnqueuedByApp=").append(numEnqueuedByApp).append(",\n");
            output.append(indentPlusTwo);
            output.append("numPostedByApp=").append(numPostedByApp).append(",\n");
            output.append(indentPlusTwo);
            output.append("numUpdatedByApp=").append(numUpdatedByApp).append(",\n");
            output.append(indentPlusTwo);
            output.append("numRemovedByApp=").append(numRemovedByApp).append(",\n");
            output.append(indentPlusTwo);
            output.append("numPeopleCacheHit=").append(numPeopleCacheHit).append(",\n");
            output.append(indentPlusTwo);
            output.append("numWithStaredPeople=").append(numWithStaredPeople).append(",\n");
            output.append(indentPlusTwo);
            output.append("numWithValidPeople=").append(numWithValidPeople).append(",\n");
            output.append(indentPlusTwo);
            output.append("numPeopleCacheMiss=").append(numPeopleCacheMiss).append(",\n");
            output.append(indentPlusTwo);
            output.append("numBlocked=").append(numBlocked).append(",\n");
            output.append(indentPlusTwo);
            output.append("numSuspendedByAdmin=").append(numSuspendedByAdmin).append(",\n");
            output.append(indentPlusTwo);
            output.append("numWithActions=").append(numWithActions).append(",\n");
            output.append(indentPlusTwo);
            output.append("numPrivate=").append(numPrivate).append(",\n");
            output.append(indentPlusTwo);
            output.append("numSecret=").append(numSecret).append(",\n");
            output.append(indentPlusTwo);
            output.append("numInterrupt=").append(numInterrupt).append(",\n");
            output.append(indentPlusTwo);
            output.append("numWithBigText=").append(numWithBigText).append(",\n");
            output.append(indentPlusTwo);
            output.append("numWithBigPicture=").append(numWithBigPicture).append("\n");
            output.append(indentPlusTwo);
            output.append("numForegroundService=").append(numForegroundService).append("\n");
            output.append(indentPlusTwo);
            output.append("numOngoing=").append(numOngoing).append("\n");
            output.append(indentPlusTwo);
            output.append("numAutoCancel=").append(numAutoCancel).append("\n");
            output.append(indentPlusTwo);
            output.append("numWithLargeIcon=").append(numWithLargeIcon).append("\n");
            output.append(indentPlusTwo);
            output.append("numWithInbox=").append(numWithInbox).append("\n");
            output.append(indentPlusTwo);
            output.append("numWithMediaSession=").append(numWithMediaSession).append("\n");
            output.append(indentPlusTwo);
            output.append("numWithTitle=").append(numWithTitle).append("\n");
            output.append(indentPlusTwo);
            output.append("numWithText=").append(numWithText).append("\n");
            output.append(indentPlusTwo);
            output.append("numWithSubText=").append(numWithSubText).append("\n");
            output.append(indentPlusTwo);
            output.append("numWithInfoText=").append(numWithInfoText).append("\n");
            output.append("numRateViolations=").append(numRateViolations).append("\n");
            output.append("numQuotaViolations=").append(numQuotaViolations).append("\n");
            output.append(indentPlusTwo).append(noisyImportance.toString()).append("\n");
            output.append(indentPlusTwo).append(quietImportance.toString()).append("\n");
            output.append(indentPlusTwo).append(finalImportance.toString()).append("\n");
            output.append(indent).append("}");
            return output.toString();
        }

        public JSONObject dumpJson() throws JSONException {
            AggregatedStats previous = getPrevious();
            JSONObject dump = new JSONObject();
            dump.put("key", key);
            dump.put("duration", SystemClock.elapsedRealtime() - mCreated);
            maybePut(dump, "numEnqueuedByApp", numEnqueuedByApp);
            maybePut(dump, "numPostedByApp", numPostedByApp);
            maybePut(dump, "numUpdatedByApp", numUpdatedByApp);
            maybePut(dump, "numRemovedByApp", numRemovedByApp);
            maybePut(dump, "numPeopleCacheHit", numPeopleCacheHit);
            maybePut(dump, "numPeopleCacheMiss", numPeopleCacheMiss);
            maybePut(dump, "numWithStaredPeople", numWithStaredPeople);
            maybePut(dump, "numWithValidPeople", numWithValidPeople);
            maybePut(dump, "numBlocked", numBlocked);
            maybePut(dump, "numSuspendedByAdmin", numSuspendedByAdmin);
            maybePut(dump, "numWithActions", numWithActions);
            maybePut(dump, "numPrivate", numPrivate);
            maybePut(dump, "numSecret", numSecret);
            maybePut(dump, "numInterrupt", numInterrupt);
            maybePut(dump, "numWithBigText", numWithBigText);
            maybePut(dump, "numWithBigPicture", numWithBigPicture);
            maybePut(dump, "numForegroundService", numForegroundService);
            maybePut(dump, "numOngoing", numOngoing);
            maybePut(dump, "numAutoCancel", numAutoCancel);
            maybePut(dump, "numWithLargeIcon", numWithLargeIcon);
            maybePut(dump, "numWithInbox", numWithInbox);
            maybePut(dump, "numWithMediaSession", numWithMediaSession);
            maybePut(dump, "numWithTitle", numWithTitle);
            maybePut(dump, "numWithText", numWithText);
            maybePut(dump, "numWithSubText", numWithSubText);
            maybePut(dump, "numWithInfoText", numWithInfoText);
            maybePut(dump, "numRateViolations", numRateViolations);
            maybePut(dump, "numQuotaLViolations", numQuotaViolations);
            maybePut(dump, "notificationEnqueueRate", getEnqueueRate());
            noisyImportance.maybePut(dump, previous.noisyImportance);
            quietImportance.maybePut(dump, previous.quietImportance);
            finalImportance.maybePut(dump, previous.finalImportance);

            return dump;
        }

        private void maybePut(JSONObject dump, String name, int value) throws JSONException {
            if (value > 0) {
                dump.put(name, value);
            }
        }

        private void maybePut(JSONObject dump, String name, float value) throws JSONException {
            if (value > 0.0) {
                dump.put(name, value);
            }
        }
    }

    private static class ImportanceHistogram {
        // TODO define these somewhere else
        private static final int NUM_IMPORTANCES = 6;
        private static final String[] IMPORTANCE_NAMES =
                {"none", "min", "low", "default", "high", "max"};
        private final Context mContext;
        private final String[] mCounterNames;
        private final String mPrefix;
        private int[] mCount;

        ImportanceHistogram(Context context, String prefix) {
            mContext = context;
            mCount = new int[NUM_IMPORTANCES];
            mCounterNames = new String[NUM_IMPORTANCES];
            mPrefix = prefix;
            for (int i = 0; i < NUM_IMPORTANCES; i++) {
                mCounterNames[i] = mPrefix + IMPORTANCE_NAMES[i];
            }
        }

        void increment(int imp) {
            imp = imp < 0 ? 0 : imp > NUM_IMPORTANCES ? NUM_IMPORTANCES : imp;
            mCount[imp] ++;
        }

        void maybeCount(ImportanceHistogram prev) {
            for (int i = 0; i < NUM_IMPORTANCES; i++) {
                final int value = mCount[i] - prev.mCount[i];
                if (value > 0) {
                    MetricsLogger.count(mContext, mCounterNames[i], value);
                }
            }
        }

        void update(ImportanceHistogram that) {
            for (int i = 0; i < NUM_IMPORTANCES; i++) {
                mCount[i] = that.mCount[i];
            }
        }

        public void maybePut(JSONObject dump, ImportanceHistogram prev)
                throws JSONException {
            dump.put(mPrefix, new JSONArray(mCount));
        }

        @Override
        public String toString() {
            StringBuilder output = new StringBuilder();
            output.append(mPrefix).append(": [");
            for (int i = 0; i < NUM_IMPORTANCES; i++) {
                output.append(mCount[i]);
                if (i < (NUM_IMPORTANCES-1)) {
                    output.append(", ");
                }
            }
            output.append("]");
            return output.toString();
        }
    }

    /**
     * Tracks usage of an individual notification that is currently active.
     */
    public static class SingleNotificationStats {
        private boolean isVisible = false;
        private boolean isExpanded = false;
        /** SystemClock.elapsedRealtime() when the notification was posted. */
        public long posttimeElapsedMs = -1;
        /** Elapsed time since the notification was posted until it was first clicked, or -1. */
        public long posttimeToFirstClickMs = -1;
        /** Elpased time since the notification was posted until it was dismissed by the user. */
        public long posttimeToDismissMs = -1;
        /** Number of times the notification has been made visible. */
        public long airtimeCount = 0;
        /** Time in ms between the notification was posted and first shown; -1 if never shown. */
        public long posttimeToFirstAirtimeMs = -1;
        /**
         * If currently visible, SystemClock.elapsedRealtime() when the notification was made
         * visible; -1 otherwise.
         */
        public long currentAirtimeStartElapsedMs = -1;
        /** Accumulated visible time. */
        public long airtimeMs = 0;
        /**
         * Time in ms between the notification being posted and when it first
         * became visible and expanded; -1 if it was never visibly expanded.
         */
        public long posttimeToFirstVisibleExpansionMs = -1;
        /**
         * If currently visible, SystemClock.elapsedRealtime() when the notification was made
         * visible; -1 otherwise.
         */
        public long currentAirtimeExpandedStartElapsedMs = -1;
        /** Accumulated visible expanded time. */
        public long airtimeExpandedMs = 0;
        /** Number of times the notification has been expanded by the user. */
        public long userExpansionCount = 0;
        /** Importance directly requested by the app. */
        public int requestedImportance;
        /** Did the app include sound or vibration on the notificaiton. */
        public boolean isNoisy;
        /** Importance after initial filtering for noise and other features */
        public int naturalImportance;

        public long getCurrentPosttimeMs() {
            if (posttimeElapsedMs < 0) {
                return 0;
            }
            return SystemClock.elapsedRealtime() - posttimeElapsedMs;
        }

        public long getCurrentAirtimeMs() {
            long result = airtimeMs;
            // Add incomplete airtime if currently shown.
            if (currentAirtimeStartElapsedMs >= 0) {
                result += (SystemClock.elapsedRealtime() - currentAirtimeStartElapsedMs);
            }
            return result;
        }

        public long getCurrentAirtimeExpandedMs() {
            long result = airtimeExpandedMs;
            // Add incomplete expanded airtime if currently shown.
            if (currentAirtimeExpandedStartElapsedMs >= 0) {
                result += (SystemClock.elapsedRealtime() - currentAirtimeExpandedStartElapsedMs);
            }
            return result;
        }

        /**
         * Called when the user clicked the notification.
         */
        public void onClick() {
            if (posttimeToFirstClickMs < 0) {
                posttimeToFirstClickMs = SystemClock.elapsedRealtime() - posttimeElapsedMs;
            }
        }

        /**
         * Called when the user removed the notification.
         */
        public void onDismiss() {
            if (posttimeToDismissMs < 0) {
                posttimeToDismissMs = SystemClock.elapsedRealtime() - posttimeElapsedMs;
            }
            finish();
        }

        public void onCancel() {
            finish();
        }

        public void onRemoved() {
            finish();
        }

        public void onVisibilityChanged(boolean visible) {
            long elapsedNowMs = SystemClock.elapsedRealtime();
            final boolean wasVisible = isVisible;
            isVisible = visible;
            if (visible) {
                if (currentAirtimeStartElapsedMs < 0) {
                    airtimeCount++;
                    currentAirtimeStartElapsedMs = elapsedNowMs;
                }
                if (posttimeToFirstAirtimeMs < 0) {
                    posttimeToFirstAirtimeMs = elapsedNowMs - posttimeElapsedMs;
                }
            } else {
                if (currentAirtimeStartElapsedMs >= 0) {
                    airtimeMs += (elapsedNowMs - currentAirtimeStartElapsedMs);
                    currentAirtimeStartElapsedMs = -1;
                }
            }

            if (wasVisible != isVisible) {
                updateVisiblyExpandedStats();
            }
        }

        public void onExpansionChanged(boolean userAction, boolean expanded) {
            isExpanded = expanded;
            if (isExpanded && userAction) {
                userExpansionCount++;
            }
            updateVisiblyExpandedStats();
        }

        private void updateVisiblyExpandedStats() {
            long elapsedNowMs = SystemClock.elapsedRealtime();
            if (isExpanded && isVisible) {
                // expanded and visible
                if (currentAirtimeExpandedStartElapsedMs < 0) {
                    currentAirtimeExpandedStartElapsedMs = elapsedNowMs;
                }
                if (posttimeToFirstVisibleExpansionMs < 0) {
                    posttimeToFirstVisibleExpansionMs = elapsedNowMs - posttimeElapsedMs;
                }
            } else {
                // not-expanded or not-visible
                if (currentAirtimeExpandedStartElapsedMs >= 0) {
                    airtimeExpandedMs += (elapsedNowMs - currentAirtimeExpandedStartElapsedMs);
                    currentAirtimeExpandedStartElapsedMs = -1;
                }
            }
        }

        /** The notification is leaving the system. Finalize. */
        public void finish() {
            onVisibilityChanged(false);
        }

        @Override
        public String toString() {
            StringBuilder output = new StringBuilder();
            output.append("SingleNotificationStats{");

            output.append("posttimeElapsedMs=").append(posttimeElapsedMs).append(", ");
            output.append("posttimeToFirstClickMs=").append(posttimeToFirstClickMs).append(", ");
            output.append("posttimeToDismissMs=").append(posttimeToDismissMs).append(", ");
            output.append("airtimeCount=").append(airtimeCount).append(", ");
            output.append("airtimeMs=").append(airtimeMs).append(", ");
            output.append("currentAirtimeStartElapsedMs=").append(currentAirtimeStartElapsedMs)
                    .append(", ");
            output.append("airtimeExpandedMs=").append(airtimeExpandedMs).append(", ");
            output.append("posttimeToFirstVisibleExpansionMs=")
                    .append(posttimeToFirstVisibleExpansionMs).append(", ");
            output.append("currentAirtimeExpandedStartElapsedMs=")
                    .append(currentAirtimeExpandedStartElapsedMs).append(", ");
            output.append("requestedImportance=").append(requestedImportance).append(", ");
            output.append("naturalImportance=").append(naturalImportance).append(", ");
            output.append("isNoisy=").append(isNoisy);
            output.append('}');
            return output.toString();
        }

        /** Copy useful information out of the stats from the pre-update notifications. */
        public void updateFrom(SingleNotificationStats old) {
            posttimeElapsedMs = old.posttimeElapsedMs;
            posttimeToFirstClickMs = old.posttimeToFirstClickMs;
            airtimeCount = old.airtimeCount;
            posttimeToFirstAirtimeMs = old.posttimeToFirstAirtimeMs;
            currentAirtimeStartElapsedMs = old.currentAirtimeStartElapsedMs;
            airtimeMs = old.airtimeMs;
            posttimeToFirstVisibleExpansionMs = old.posttimeToFirstVisibleExpansionMs;
            currentAirtimeExpandedStartElapsedMs = old.currentAirtimeExpandedStartElapsedMs;
            airtimeExpandedMs = old.airtimeExpandedMs;
            userExpansionCount = old.userExpansionCount;
        }
    }

    /**
     * Aggregates long samples to sum and averages.
     */
    public static class Aggregate {
        long numSamples;
        double avg;
        double sum2;
        double var;

        public void addSample(long sample) {
            // Welford's "Method for Calculating Corrected Sums of Squares"
            // http://www.jstor.org/stable/1266577?seq=2
            numSamples++;
            final double n = numSamples;
            final double delta = sample - avg;
            avg += (1.0 / n) * delta;
            sum2 += ((n - 1) / n) * delta * delta;
            final double divisor = numSamples == 1 ? 1.0 : n - 1.0;
            var = sum2 / divisor;
        }

        @Override
        public String toString() {
            return "Aggregate{" +
                    "numSamples=" + numSamples +
                    ", avg=" + avg +
                    ", var=" + var +
                    '}';
        }
    }

    private static class SQLiteLog {
        private static final String TAG = "NotificationSQLiteLog";

        // Message types passed to the background handler.
        private static final int MSG_POST = 1;
        private static final int MSG_CLICK = 2;
        private static final int MSG_REMOVE = 3;
        private static final int MSG_DISMISS = 4;

        private static final String DB_NAME = "notification_log.db";
        private static final int DB_VERSION = 5;

        /** Age in ms after which events are pruned from the DB. */
        private static final long HORIZON_MS = 7 * 24 * 60 * 60 * 1000L;  // 1 week
        /** Delay between pruning the DB. Used to throttle pruning. */
        private static final long PRUNE_MIN_DELAY_MS = 6 * 60 * 60 * 1000L;  // 6 hours
        /** Mininum number of writes between pruning the DB. Used to throttle pruning. */
        private static final long PRUNE_MIN_WRITES = 1024;

        // Table 'log'
        private static final String TAB_LOG = "log";
        private static final String COL_EVENT_USER_ID = "event_user_id";
        private static final String COL_EVENT_TYPE = "event_type";
        private static final String COL_EVENT_TIME = "event_time_ms";
        private static final String COL_KEY = "key";
        private static final String COL_PKG = "pkg";
        private static final String COL_NOTIFICATION_ID = "nid";
        private static final String COL_TAG = "tag";
        private static final String COL_WHEN_MS = "when_ms";
        private static final String COL_DEFAULTS = "defaults";
        private static final String COL_FLAGS = "flags";
        private static final String COL_IMPORTANCE_REQ = "importance_request";
        private static final String COL_IMPORTANCE_FINAL = "importance_final";
        private static final String COL_NOISY = "noisy";
        private static final String COL_MUTED = "muted";
        private static final String COL_DEMOTED = "demoted";
        private static final String COL_CATEGORY = "category";
        private static final String COL_ACTION_COUNT = "action_count";
        private static final String COL_POSTTIME_MS = "posttime_ms";
        private static final String COL_AIRTIME_MS = "airtime_ms";
        private static final String COL_FIRST_EXPANSIONTIME_MS = "first_expansion_time_ms";
        private static final String COL_AIRTIME_EXPANDED_MS = "expansion_airtime_ms";
        private static final String COL_EXPAND_COUNT = "expansion_count";


        private static final int EVENT_TYPE_POST = 1;
        private static final int EVENT_TYPE_CLICK = 2;
        private static final int EVENT_TYPE_REMOVE = 3;
        private static final int EVENT_TYPE_DISMISS = 4;
        private static long sLastPruneMs;

        private static long sNumWrites;
        private final SQLiteOpenHelper mHelper;

        private final Handler mWriteHandler;
        private static final long DAY_MS = 24 * 60 * 60 * 1000;
        private static final String STATS_QUERY = "SELECT " +
                COL_EVENT_USER_ID + ", " +
                COL_PKG + ", " +
                // Bucket by day by looking at 'floor((midnight - eventTimeMs) / dayMs)'
                "CAST(((%d - " + COL_EVENT_TIME + ") / " + DAY_MS + ") AS int) " +
                "AS day, " +
                "COUNT(*) AS cnt, " +
                "SUM(" + COL_MUTED + ") as muted, " +
                "SUM(" + COL_NOISY + ") as noisy, " +
                "SUM(" + COL_DEMOTED + ") as demoted " +
                "FROM " + TAB_LOG + " " +
                "WHERE " +
                COL_EVENT_TYPE + "=" + EVENT_TYPE_POST +
                " AND " + COL_EVENT_TIME + " > %d " +
                " GROUP BY " + COL_EVENT_USER_ID + ", day, " + COL_PKG;

        public SQLiteLog(Context context) {
            HandlerThread backgroundThread = new HandlerThread("notification-sqlite-log",
                    android.os.Process.THREAD_PRIORITY_BACKGROUND);
            backgroundThread.start();
            mWriteHandler = new Handler(backgroundThread.getLooper()) {
                @Override
                public void handleMessage(Message msg) {
                    NotificationRecord r = (NotificationRecord) msg.obj;
                    long nowMs = System.currentTimeMillis();
                    switch (msg.what) {
                        case MSG_POST:
                            writeEvent(r.sbn.getPostTime(), EVENT_TYPE_POST, r);
                            break;
                        case MSG_CLICK:
                            writeEvent(nowMs, EVENT_TYPE_CLICK, r);
                            break;
                        case MSG_REMOVE:
                            writeEvent(nowMs, EVENT_TYPE_REMOVE, r);
                            break;
                        case MSG_DISMISS:
                            writeEvent(nowMs, EVENT_TYPE_DISMISS, r);
                            break;
                        default:
                            Log.wtf(TAG, "Unknown message type: " + msg.what);
                            break;
                    }
                }
            };
            mHelper = new SQLiteOpenHelper(context, DB_NAME, null, DB_VERSION) {
                @Override
                public void onCreate(SQLiteDatabase db) {
                    db.execSQL("CREATE TABLE " + TAB_LOG + " (" +
                            "_id INTEGER PRIMARY KEY AUTOINCREMENT," +
                            COL_EVENT_USER_ID + " INT," +
                            COL_EVENT_TYPE + " INT," +
                            COL_EVENT_TIME + " INT," +
                            COL_KEY + " TEXT," +
                            COL_PKG + " TEXT," +
                            COL_NOTIFICATION_ID + " INT," +
                            COL_TAG + " TEXT," +
                            COL_WHEN_MS + " INT," +
                            COL_DEFAULTS + " INT," +
                            COL_FLAGS + " INT," +
                            COL_IMPORTANCE_REQ + " INT," +
                            COL_IMPORTANCE_FINAL + " INT," +
                            COL_NOISY + " INT," +
                            COL_MUTED + " INT," +
                            COL_DEMOTED + " INT," +
                            COL_CATEGORY + " TEXT," +
                            COL_ACTION_COUNT + " INT," +
                            COL_POSTTIME_MS + " INT," +
                            COL_AIRTIME_MS + " INT," +
                            COL_FIRST_EXPANSIONTIME_MS + " INT," +
                            COL_AIRTIME_EXPANDED_MS + " INT," +
                            COL_EXPAND_COUNT + " INT" +
                            ")");
                }

                @Override
                public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
                    if (oldVersion != newVersion) {
                        db.execSQL("DROP TABLE IF EXISTS " + TAB_LOG);
                        onCreate(db);
                    }
                }
            };
        }

        public void logPosted(NotificationRecord notification) {
            mWriteHandler.sendMessage(mWriteHandler.obtainMessage(MSG_POST, notification));
        }

        public void logClicked(NotificationRecord notification) {
            mWriteHandler.sendMessage(mWriteHandler.obtainMessage(MSG_CLICK, notification));
        }

        public void logRemoved(NotificationRecord notification) {
            mWriteHandler.sendMessage(mWriteHandler.obtainMessage(MSG_REMOVE, notification));
        }

        public void logDismissed(NotificationRecord notification) {
            mWriteHandler.sendMessage(mWriteHandler.obtainMessage(MSG_DISMISS, notification));
        }

        private JSONArray jsonPostFrequencies(DumpFilter filter) throws JSONException {
            JSONArray frequencies = new JSONArray();
            SQLiteDatabase db = mHelper.getReadableDatabase();
            long midnight = getMidnightMs();
            String q = String.format(STATS_QUERY, midnight, filter.since);
            Cursor cursor = db.rawQuery(q, null);
            try {
                for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
                    int userId = cursor.getInt(0);
                    String pkg = cursor.getString(1);
                    if (filter != null && !filter.matches(pkg)) continue;
                    int day = cursor.getInt(2);
                    int count = cursor.getInt(3);
                    int muted = cursor.getInt(4);
                    int noisy = cursor.getInt(5);
                    int demoted = cursor.getInt(6);
                    JSONObject row = new JSONObject();
                    row.put("user_id", userId);
                    row.put("package", pkg);
                    row.put("day", day);
                    row.put("count", count);
                    row.put("noisy", noisy);
                    row.put("muted", muted);
                    row.put("demoted", demoted);
                    frequencies.put(row);
                }
            } finally {
                cursor.close();
            }
            return frequencies;
        }

        public void printPostFrequencies(PrintWriter pw, String indent, DumpFilter filter) {
            SQLiteDatabase db = mHelper.getReadableDatabase();
            long midnight = getMidnightMs();
            String q = String.format(STATS_QUERY, midnight, filter.since);
            Cursor cursor = db.rawQuery(q, null);
            try {
                for (cursor.moveToFirst(); !cursor.isAfterLast(); cursor.moveToNext()) {
                    int userId = cursor.getInt(0);
                    String pkg = cursor.getString(1);
                    if (filter != null && !filter.matches(pkg)) continue;
                    int day = cursor.getInt(2);
                    int count = cursor.getInt(3);
                    int muted = cursor.getInt(4);
                    int noisy = cursor.getInt(5);
                    int demoted = cursor.getInt(6);
                    pw.println(indent + "post_frequency{user_id=" + userId + ",pkg=" + pkg +
                            ",day=" + day + ",count=" + count + ",muted=" + muted + "/" + noisy +
                            ",demoted=" + demoted + "}");
                }
            } finally {
                cursor.close();
            }
        }

        private long getMidnightMs() {
            GregorianCalendar midnight = new GregorianCalendar();
            midnight.set(midnight.get(Calendar.YEAR), midnight.get(Calendar.MONTH),
                    midnight.get(Calendar.DATE), 23, 59, 59);
            return midnight.getTimeInMillis();
        }

        private void writeEvent(long eventTimeMs, int eventType, NotificationRecord r) {
            ContentValues cv = new ContentValues();
            cv.put(COL_EVENT_USER_ID, r.sbn.getUser().getIdentifier());
            cv.put(COL_EVENT_TIME, eventTimeMs);
            cv.put(COL_EVENT_TYPE, eventType);
            putNotificationIdentifiers(r, cv);
            if (eventType == EVENT_TYPE_POST) {
                putNotificationDetails(r, cv);
            } else {
                putPosttimeVisibility(r, cv);
            }
            SQLiteDatabase db = mHelper.getWritableDatabase();
            if (db.insert(TAB_LOG, null, cv) < 0) {
                Log.wtf(TAG, "Error while trying to insert values: " + cv);
            }
            sNumWrites++;
            pruneIfNecessary(db);
        }

        private void pruneIfNecessary(SQLiteDatabase db) {
            // Prune if we haven't in a while.
            long nowMs = System.currentTimeMillis();
            if (sNumWrites > PRUNE_MIN_WRITES ||
                    nowMs - sLastPruneMs > PRUNE_MIN_DELAY_MS) {
                sNumWrites = 0;
                sLastPruneMs = nowMs;
                long horizonStartMs = nowMs - HORIZON_MS;
                int deletedRows = db.delete(TAB_LOG, COL_EVENT_TIME + " < ?",
                        new String[] { String.valueOf(horizonStartMs) });
                Log.d(TAG, "Pruned event entries: " + deletedRows);
            }
        }

        private static void putNotificationIdentifiers(NotificationRecord r, ContentValues outCv) {
            outCv.put(COL_KEY, r.sbn.getKey());
            outCv.put(COL_PKG, r.sbn.getPackageName());
        }

        private static void putNotificationDetails(NotificationRecord r, ContentValues outCv) {
            outCv.put(COL_NOTIFICATION_ID, r.sbn.getId());
            if (r.sbn.getTag() != null) {
                outCv.put(COL_TAG, r.sbn.getTag());
            }
            outCv.put(COL_WHEN_MS, r.sbn.getPostTime());
            outCv.put(COL_FLAGS, r.getNotification().flags);
            final int before = r.stats.requestedImportance;
            final int after = r.getImportance();
            final boolean noisy = r.stats.isNoisy;
            outCv.put(COL_IMPORTANCE_REQ, before);
            outCv.put(COL_IMPORTANCE_FINAL, after);
            outCv.put(COL_DEMOTED, after < before ? 1 : 0);
            outCv.put(COL_NOISY, noisy);
            if (noisy && after < IMPORTANCE_HIGH) {
                outCv.put(COL_MUTED, 1);
            } else {
                outCv.put(COL_MUTED, 0);
            }
            if (r.getNotification().category != null) {
                outCv.put(COL_CATEGORY, r.getNotification().category);
            }
            outCv.put(COL_ACTION_COUNT, r.getNotification().actions != null ?
                    r.getNotification().actions.length : 0);
        }

        private static void putPosttimeVisibility(NotificationRecord r, ContentValues outCv) {
            outCv.put(COL_POSTTIME_MS, r.stats.getCurrentPosttimeMs());
            outCv.put(COL_AIRTIME_MS, r.stats.getCurrentAirtimeMs());
            outCv.put(COL_EXPAND_COUNT, r.stats.userExpansionCount);
            outCv.put(COL_AIRTIME_EXPANDED_MS, r.stats.getCurrentAirtimeExpandedMs());
            outCv.put(COL_FIRST_EXPANSIONTIME_MS, r.stats.posttimeToFirstVisibleExpansionMs);
        }

        public void dump(PrintWriter pw, String indent, DumpFilter filter) {
            printPostFrequencies(pw, indent, filter);
        }

        public JSONObject dumpJson(DumpFilter filter) {
            JSONObject dump = new JSONObject();
            try {
                dump.put("post_frequency", jsonPostFrequencies(filter));
                dump.put("since", filter.since);
                dump.put("now", System.currentTimeMillis());
            } catch (JSONException e) {
                // pass
            }
            return dump;
        }
    }
}
