/**
 * 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.usage;

import android.app.usage.ConfigurationStats;
import android.app.usage.EventList;
import android.app.usage.EventStats;
import android.app.usage.UsageEvents;
import android.app.usage.UsageStats;
import android.app.usage.UsageStatsManager;
import android.content.res.Configuration;
import android.os.SystemClock;
import android.content.Context;
import android.text.format.DateUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Slog;

import com.android.internal.util.IndentingPrintWriter;
import com.android.server.usage.UsageStatsDatabase.StatCombiner;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * A per-user UsageStatsService. All methods are meant to be called with the main lock held
 * in UsageStatsService.
 */
class UserUsageStatsService {
    private static final String TAG = "UsageStatsService";
    private static final boolean DEBUG = UsageStatsService.DEBUG;
    private static final SimpleDateFormat sDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    private static final int sDateFormatFlags =
            DateUtils.FORMAT_SHOW_DATE
            | DateUtils.FORMAT_SHOW_TIME
            | DateUtils.FORMAT_SHOW_YEAR
            | DateUtils.FORMAT_NUMERIC_DATE;

    private final Context mContext;
    private final UsageStatsDatabase mDatabase;
    private final IntervalStats[] mCurrentStats;
    private boolean mStatsChanged = false;
    private final UnixCalendar mDailyExpiryDate;
    private final StatsUpdatedListener mListener;
    private final String mLogPrefix;
    private String mLastBackgroundedPackage;
    private final int mUserId;

    private static final long[] INTERVAL_LENGTH = new long[] {
            UnixCalendar.DAY_IN_MILLIS, UnixCalendar.WEEK_IN_MILLIS,
            UnixCalendar.MONTH_IN_MILLIS, UnixCalendar.YEAR_IN_MILLIS
    };

    interface StatsUpdatedListener {
        void onStatsUpdated();
        void onStatsReloaded();
        /**
         * Callback that a system update was detected
         * @param mUserId user that needs to be initialized
         */
        void onNewUpdate(int mUserId);
    }

    UserUsageStatsService(Context context, int userId, File usageStatsDir,
            StatsUpdatedListener listener) {
        mContext = context;
        mDailyExpiryDate = new UnixCalendar(0);
        mDatabase = new UsageStatsDatabase(usageStatsDir);
        mCurrentStats = new IntervalStats[UsageStatsManager.INTERVAL_COUNT];
        mListener = listener;
        mLogPrefix = "User[" + Integer.toString(userId) + "] ";
        mUserId = userId;
    }

    void init(final long currentTimeMillis) {
        mDatabase.init(currentTimeMillis);

        int nullCount = 0;
        for (int i = 0; i < mCurrentStats.length; i++) {
            mCurrentStats[i] = mDatabase.getLatestUsageStats(i);
            if (mCurrentStats[i] == null) {
                // Find out how many intervals we don't have data for.
                // Ideally it should be all or none.
                nullCount++;
            }
        }

        if (nullCount > 0) {
            if (nullCount != mCurrentStats.length) {
                // This is weird, but we shouldn't fail if something like this
                // happens.
                Slog.w(TAG, mLogPrefix + "Some stats have no latest available");
            } else {
                // This must be first boot.
            }

            // By calling loadActiveStats, we will
            // generate new stats for each bucket.
            loadActiveStats(currentTimeMillis);
        } else {
            // Set up the expiry date to be one day from the latest daily stat.
            // This may actually be today and we will rollover on the first event
            // that is reported.
            updateRolloverDeadline();
        }

        // Now close off any events that were open at the time this was saved.
        for (IntervalStats stat : mCurrentStats) {
            final int pkgCount = stat.packageStats.size();
            for (int i = 0; i < pkgCount; i++) {
                UsageStats pkgStats = stat.packageStats.valueAt(i);
                if (pkgStats.mLastEvent == UsageEvents.Event.MOVE_TO_FOREGROUND ||
                        pkgStats.mLastEvent == UsageEvents.Event.CONTINUE_PREVIOUS_DAY) {
                    stat.update(pkgStats.mPackageName, stat.lastTimeSaved,
                            UsageEvents.Event.END_OF_DAY);
                    notifyStatsChanged();
                }
            }

            stat.updateConfigurationStats(null, stat.lastTimeSaved);
        }

        if (mDatabase.isNewUpdate()) {
            notifyNewUpdate();
        }
    }

    void onTimeChanged(long oldTime, long newTime) {
        persistActiveStats();
        mDatabase.onTimeChanged(newTime - oldTime);
        loadActiveStats(newTime);
    }

    void reportEvent(UsageEvents.Event event) {
        if (DEBUG) {
            Slog.d(TAG, mLogPrefix + "Got usage event for " + event.mPackage
                    + "[" + event.mTimeStamp + "]: "
                    + eventToString(event.mEventType));
        }

        if (event.mTimeStamp >= mDailyExpiryDate.getTimeInMillis()) {
            // Need to rollover
            rolloverStats(event.mTimeStamp);
        }

        final IntervalStats currentDailyStats = mCurrentStats[UsageStatsManager.INTERVAL_DAILY];

        final Configuration newFullConfig = event.mConfiguration;
        if (event.mEventType == UsageEvents.Event.CONFIGURATION_CHANGE &&
                currentDailyStats.activeConfiguration != null) {
            // Make the event configuration a delta.
            event.mConfiguration = Configuration.generateDelta(
                    currentDailyStats.activeConfiguration, newFullConfig);
        }

        // Add the event to the daily list.
        if (currentDailyStats.events == null) {
            currentDailyStats.events = new EventList();
        }
        if (event.mEventType != UsageEvents.Event.SYSTEM_INTERACTION) {
            currentDailyStats.events.insert(event);
        }

        boolean incrementAppLaunch = false;
        if (event.mEventType == UsageEvents.Event.MOVE_TO_FOREGROUND) {
            if (event.mPackage != null && !event.mPackage.equals(mLastBackgroundedPackage)) {
                incrementAppLaunch = true;
            }
        } else if (event.mEventType == UsageEvents.Event.MOVE_TO_BACKGROUND) {
            if (event.mPackage != null) {
                mLastBackgroundedPackage = event.mPackage;
            }
        }

        for (IntervalStats stats : mCurrentStats) {
            switch (event.mEventType) {
                case UsageEvents.Event.CONFIGURATION_CHANGE: {
                    stats.updateConfigurationStats(newFullConfig, event.mTimeStamp);
                } break;
                case UsageEvents.Event.CHOOSER_ACTION: {
                    stats.updateChooserCounts(event.mPackage, event.mContentType, event.mAction);
                    String[] annotations = event.mContentAnnotations;
                    if (annotations != null) {
                        for (String annotation : annotations) {
                            stats.updateChooserCounts(event.mPackage, annotation, event.mAction);
                        }
                    }
                } break;
                case UsageEvents.Event.SCREEN_INTERACTIVE: {
                    stats.updateScreenInteractive(event.mTimeStamp);
                } break;
                case UsageEvents.Event.SCREEN_NON_INTERACTIVE: {
                    stats.updateScreenNonInteractive(event.mTimeStamp);
                } break;
                case UsageEvents.Event.KEYGUARD_SHOWN: {
                    stats.updateKeyguardShown(event.mTimeStamp);
                } break;
                case UsageEvents.Event.KEYGUARD_HIDDEN: {
                    stats.updateKeyguardHidden(event.mTimeStamp);
                } break;
                default: {
                    stats.update(event.mPackage, event.mTimeStamp, event.mEventType);
                    if (incrementAppLaunch) {
                        stats.incrementAppLaunchCount(event.mPackage);
                    }
                } break;
            }
        }

        notifyStatsChanged();
    }

    private static final StatCombiner<UsageStats> sUsageStatsCombiner =
            new StatCombiner<UsageStats>() {
                @Override
                public void combine(IntervalStats stats, boolean mutable,
                                    List<UsageStats> accResult) {
                    if (!mutable) {
                        accResult.addAll(stats.packageStats.values());
                        return;
                    }

                    final int statCount = stats.packageStats.size();
                    for (int i = 0; i < statCount; i++) {
                        accResult.add(new UsageStats(stats.packageStats.valueAt(i)));
                    }
                }
            };

    private static final StatCombiner<ConfigurationStats> sConfigStatsCombiner =
            new StatCombiner<ConfigurationStats>() {
                @Override
                public void combine(IntervalStats stats, boolean mutable,
                                    List<ConfigurationStats> accResult) {
                    if (!mutable) {
                        accResult.addAll(stats.configurations.values());
                        return;
                    }

                    final int configCount = stats.configurations.size();
                    for (int i = 0; i < configCount; i++) {
                        accResult.add(new ConfigurationStats(stats.configurations.valueAt(i)));
                    }
                }
            };

    private static final StatCombiner<EventStats> sEventStatsCombiner =
            new StatCombiner<EventStats>() {
                @Override
                public void combine(IntervalStats stats, boolean mutable,
                        List<EventStats> accResult) {
                    stats.addEventStatsTo(accResult);
                }
            };

    /**
     * Generic query method that selects the appropriate IntervalStats for the specified time range
     * and bucket, then calls the {@link com.android.server.usage.UsageStatsDatabase.StatCombiner}
     * provided to select the stats to use from the IntervalStats object.
     */
    private <T> List<T> queryStats(int intervalType, final long beginTime, final long endTime,
            StatCombiner<T> combiner) {
        if (intervalType == UsageStatsManager.INTERVAL_BEST) {
            intervalType = mDatabase.findBestFitBucket(beginTime, endTime);
            if (intervalType < 0) {
                // Nothing saved to disk yet, so every stat is just as equal (no rollover has
                // occurred.
                intervalType = UsageStatsManager.INTERVAL_DAILY;
            }
        }

        if (intervalType < 0 || intervalType >= mCurrentStats.length) {
            if (DEBUG) {
                Slog.d(TAG, mLogPrefix + "Bad intervalType used " + intervalType);
            }
            return null;
        }

        final IntervalStats currentStats = mCurrentStats[intervalType];

        if (DEBUG) {
            Slog.d(TAG, mLogPrefix + "SELECT * FROM " + intervalType + " WHERE beginTime >= "
                    + beginTime + " AND endTime < " + endTime);
        }

        if (beginTime >= currentStats.endTime) {
            if (DEBUG) {
                Slog.d(TAG, mLogPrefix + "Requesting stats after " + beginTime + " but latest is "
                        + currentStats.endTime);
            }
            // Nothing newer available.
            return null;
        }

        // Truncate the endTime to just before the in-memory stats. Then, we'll append the
        // in-memory stats to the results (if necessary) so as to avoid writing to disk too
        // often.
        final long truncatedEndTime = Math.min(currentStats.beginTime, endTime);

        // Get the stats from disk.
        List<T> results = mDatabase.queryUsageStats(intervalType, beginTime,
                truncatedEndTime, combiner);
        if (DEBUG) {
            Slog.d(TAG, "Got " + (results != null ? results.size() : 0) + " results from disk");
            Slog.d(TAG, "Current stats beginTime=" + currentStats.beginTime +
                    " endTime=" + currentStats.endTime);
        }

        // Now check if the in-memory stats match the range and add them if they do.
        if (beginTime < currentStats.endTime && endTime > currentStats.beginTime) {
            if (DEBUG) {
                Slog.d(TAG, mLogPrefix + "Returning in-memory stats");
            }

            if (results == null) {
                results = new ArrayList<>();
            }
            combiner.combine(currentStats, true, results);
        }

        if (DEBUG) {
            Slog.d(TAG, mLogPrefix + "Results: " + (results != null ? results.size() : 0));
        }
        return results;
    }

    List<UsageStats> queryUsageStats(int bucketType, long beginTime, long endTime) {
        return queryStats(bucketType, beginTime, endTime, sUsageStatsCombiner);
    }

    List<ConfigurationStats> queryConfigurationStats(int bucketType, long beginTime, long endTime) {
        return queryStats(bucketType, beginTime, endTime, sConfigStatsCombiner);
    }

    List<EventStats> queryEventStats(int bucketType, long beginTime, long endTime) {
        return queryStats(bucketType, beginTime, endTime, sEventStatsCombiner);
    }

    UsageEvents queryEvents(final long beginTime, final long endTime,
            boolean obfuscateInstantApps) {
        final ArraySet<String> names = new ArraySet<>();
        List<UsageEvents.Event> results = queryStats(UsageStatsManager.INTERVAL_DAILY,
                beginTime, endTime, new StatCombiner<UsageEvents.Event>() {
                    @Override
                    public void combine(IntervalStats stats, boolean mutable,
                            List<UsageEvents.Event> accumulatedResult) {
                        if (stats.events == null) {
                            return;
                        }

                        final int startIndex = stats.events.firstIndexOnOrAfter(beginTime);
                        final int size = stats.events.size();
                        for (int i = startIndex; i < size; i++) {
                            if (stats.events.get(i).mTimeStamp >= endTime) {
                                return;
                            }

                            UsageEvents.Event event = stats.events.get(i);
                            if (obfuscateInstantApps) {
                                event = event.getObfuscatedIfInstantApp();
                            }
                            names.add(event.mPackage);
                            if (event.mClass != null) {
                                names.add(event.mClass);
                            }
                            accumulatedResult.add(event);
                        }
                    }
                });

        if (results == null || results.isEmpty()) {
            return null;
        }

        String[] table = names.toArray(new String[names.size()]);
        Arrays.sort(table);
        return new UsageEvents(results, table);
    }

    UsageEvents queryEventsForPackage(final long beginTime, final long endTime,
            final String packageName) {
        final ArraySet<String> names = new ArraySet<>();
        names.add(packageName);
        final List<UsageEvents.Event> results = queryStats(UsageStatsManager.INTERVAL_DAILY,
                beginTime, endTime, (stats, mutable, accumulatedResult) -> {
                    if (stats.events == null) {
                        return;
                    }

                    final int startIndex = stats.events.firstIndexOnOrAfter(beginTime);
                    final int size = stats.events.size();
                    for (int i = startIndex; i < size; i++) {
                        if (stats.events.get(i).mTimeStamp >= endTime) {
                            return;
                        }

                        final UsageEvents.Event event = stats.events.get(i);
                        if (!packageName.equals(event.mPackage)) {
                            continue;
                        }
                        if (event.mClass != null) {
                            names.add(event.mClass);
                        }
                        accumulatedResult.add(event);
                    }
                });

        if (results == null || results.isEmpty()) {
            return null;
        }

        final String[] table = names.toArray(new String[names.size()]);
        Arrays.sort(table);
        return new UsageEvents(results, table);
    }

    void persistActiveStats() {
        if (mStatsChanged) {
            Slog.i(TAG, mLogPrefix + "Flushing usage stats to disk");
            try {
                for (int i = 0; i < mCurrentStats.length; i++) {
                    mDatabase.putUsageStats(i, mCurrentStats[i]);
                }
                mStatsChanged = false;
            } catch (IOException e) {
                Slog.e(TAG, mLogPrefix + "Failed to persist active stats", e);
            }
        }
    }

    private void rolloverStats(final long currentTimeMillis) {
        final long startTime = SystemClock.elapsedRealtime();
        Slog.i(TAG, mLogPrefix + "Rolling over usage stats");

        // Finish any ongoing events with an END_OF_DAY event. Make a note of which components
        // need a new CONTINUE_PREVIOUS_DAY entry.
        final Configuration previousConfig =
                mCurrentStats[UsageStatsManager.INTERVAL_DAILY].activeConfiguration;
        ArraySet<String> continuePreviousDay = new ArraySet<>();
        for (IntervalStats stat : mCurrentStats) {
            final int pkgCount = stat.packageStats.size();
            for (int i = 0; i < pkgCount; i++) {
                UsageStats pkgStats = stat.packageStats.valueAt(i);
                if (pkgStats.mLastEvent == UsageEvents.Event.MOVE_TO_FOREGROUND ||
                        pkgStats.mLastEvent == UsageEvents.Event.CONTINUE_PREVIOUS_DAY) {
                    continuePreviousDay.add(pkgStats.mPackageName);
                    stat.update(pkgStats.mPackageName, mDailyExpiryDate.getTimeInMillis() - 1,
                            UsageEvents.Event.END_OF_DAY);
                    notifyStatsChanged();
                }
            }

            stat.updateConfigurationStats(null, mDailyExpiryDate.getTimeInMillis() - 1);
            stat.commitTime(mDailyExpiryDate.getTimeInMillis() - 1);
        }

        persistActiveStats();
        mDatabase.prune(currentTimeMillis);
        loadActiveStats(currentTimeMillis);

        final int continueCount = continuePreviousDay.size();
        for (int i = 0; i < continueCount; i++) {
            String name = continuePreviousDay.valueAt(i);
            final long beginTime = mCurrentStats[UsageStatsManager.INTERVAL_DAILY].beginTime;
            for (IntervalStats stat : mCurrentStats) {
                stat.update(name, beginTime, UsageEvents.Event.CONTINUE_PREVIOUS_DAY);
                stat.updateConfigurationStats(previousConfig, beginTime);
                notifyStatsChanged();
            }
        }
        persistActiveStats();

        final long totalTime = SystemClock.elapsedRealtime() - startTime;
        Slog.i(TAG, mLogPrefix + "Rolling over usage stats complete. Took " + totalTime
                + " milliseconds");
    }

    private void notifyStatsChanged() {
        if (!mStatsChanged) {
            mStatsChanged = true;
            mListener.onStatsUpdated();
        }
    }

    private void notifyNewUpdate() {
        mListener.onNewUpdate(mUserId);
    }

    private void loadActiveStats(final long currentTimeMillis) {
        for (int intervalType = 0; intervalType < mCurrentStats.length; intervalType++) {
            final IntervalStats stats = mDatabase.getLatestUsageStats(intervalType);
            if (stats != null && currentTimeMillis - 500 >= stats.endTime &&
                    currentTimeMillis < stats.beginTime + INTERVAL_LENGTH[intervalType]) {
                if (DEBUG) {
                    Slog.d(TAG, mLogPrefix + "Loading existing stats @ " +
                            sDateFormat.format(stats.beginTime) + "(" + stats.beginTime +
                            ") for interval " + intervalType);
                }
                mCurrentStats[intervalType] = stats;
            } else {
                // No good fit remains.
                if (DEBUG) {
                    Slog.d(TAG, "Creating new stats @ " +
                            sDateFormat.format(currentTimeMillis) + "(" +
                            currentTimeMillis + ") for interval " + intervalType);
                }

                mCurrentStats[intervalType] = new IntervalStats();
                mCurrentStats[intervalType].beginTime = currentTimeMillis;
                mCurrentStats[intervalType].endTime = currentTimeMillis + 1;
            }
        }

        mStatsChanged = false;
        updateRolloverDeadline();

        // Tell the listener that the stats reloaded, which may have changed idle states.
        mListener.onStatsReloaded();
    }

    private void updateRolloverDeadline() {
        mDailyExpiryDate.setTimeInMillis(
                mCurrentStats[UsageStatsManager.INTERVAL_DAILY].beginTime);
        mDailyExpiryDate.addDays(1);
        Slog.i(TAG, mLogPrefix + "Rollover scheduled @ " +
                sDateFormat.format(mDailyExpiryDate.getTimeInMillis()) + "(" +
                mDailyExpiryDate.getTimeInMillis() + ")");
    }

    //
    // -- DUMP related methods --
    //

    void checkin(final IndentingPrintWriter pw) {
        mDatabase.checkinDailyFiles(new UsageStatsDatabase.CheckinAction() {
            @Override
            public boolean checkin(IntervalStats stats) {
                printIntervalStats(pw, stats, false, false, null);
                return true;
            }
        });
    }

    void dump(IndentingPrintWriter pw, String pkg) {
        dump(pw, pkg, false);
    }
    void dump(IndentingPrintWriter pw, String pkg, boolean compact) {
        printLast24HrEvents(pw, !compact, pkg);
        for (int interval = 0; interval < mCurrentStats.length; interval++) {
            pw.print("In-memory ");
            pw.print(intervalToString(interval));
            pw.println(" stats");
            printIntervalStats(pw, mCurrentStats[interval], !compact, true, pkg);
        }
    }

    private String formatDateTime(long dateTime, boolean pretty) {
        if (pretty) {
            return "\"" + sDateFormat.format(dateTime)+ "\"";
        }
        return Long.toString(dateTime);
    }

    private String formatElapsedTime(long elapsedTime, boolean pretty) {
        if (pretty) {
            return "\"" + DateUtils.formatElapsedTime(elapsedTime / 1000) + "\"";
        }
        return Long.toString(elapsedTime);
    }


    void printEvent(IndentingPrintWriter pw, UsageEvents.Event event, boolean prettyDates) {
        pw.printPair("time", formatDateTime(event.mTimeStamp, prettyDates));
        pw.printPair("type", eventToString(event.mEventType));
        pw.printPair("package", event.mPackage);
        if (event.mClass != null) {
            pw.printPair("class", event.mClass);
        }
        if (event.mConfiguration != null) {
            pw.printPair("config", Configuration.resourceQualifierString(event.mConfiguration));
        }
        if (event.mShortcutId != null) {
            pw.printPair("shortcutId", event.mShortcutId);
        }
        if (event.mEventType == UsageEvents.Event.STANDBY_BUCKET_CHANGED) {
            pw.printPair("standbyBucket", event.getStandbyBucket());
            pw.printPair("reason", UsageStatsManager.reasonToString(event.getStandbyReason()));
        }
        pw.printHexPair("flags", event.mFlags);
        pw.println();
    }

    void printLast24HrEvents(IndentingPrintWriter pw, boolean prettyDates, final String pkg) {
        final long endTime = System.currentTimeMillis();
        UnixCalendar yesterday = new UnixCalendar(endTime);
        yesterday.addDays(-1);

        final long beginTime = yesterday.getTimeInMillis();

        List<UsageEvents.Event> events = queryStats(UsageStatsManager.INTERVAL_DAILY,
                beginTime, endTime, new StatCombiner<UsageEvents.Event>() {
                    @Override
                    public void combine(IntervalStats stats, boolean mutable,
                            List<UsageEvents.Event> accumulatedResult) {
                        if (stats.events == null) {
                            return;
                        }

                        final int startIndex = stats.events.firstIndexOnOrAfter(beginTime);
                        final int size = stats.events.size();
                        for (int i = startIndex; i < size; i++) {
                            if (stats.events.get(i).mTimeStamp >= endTime) {
                                return;
                            }

                            UsageEvents.Event event = stats.events.get(i);
                            if (pkg != null && !pkg.equals(event.mPackage)) {
                                continue;
                            }
                            accumulatedResult.add(event);
                        }
                    }
                });

        pw.print("Last 24 hour events (");
        if (prettyDates) {
            pw.printPair("timeRange", "\"" + DateUtils.formatDateRange(mContext,
                    beginTime, endTime, sDateFormatFlags) + "\"");
        } else {
            pw.printPair("beginTime", beginTime);
            pw.printPair("endTime", endTime);
        }
        pw.println(")");
        if (events != null) {
            pw.increaseIndent();
            for (UsageEvents.Event event : events) {
                printEvent(pw, event, prettyDates);
            }
            pw.decreaseIndent();
        }
    }

    void printEventAggregation(IndentingPrintWriter pw, String label,
            IntervalStats.EventTracker tracker, boolean prettyDates) {
        if (tracker.count != 0 || tracker.duration != 0) {
            pw.print(label);
            pw.print(": ");
            pw.print(tracker.count);
            pw.print("x for ");
            pw.print(formatElapsedTime(tracker.duration, prettyDates));
            if (tracker.curStartTime != 0) {
                pw.print(" (now running, started at ");
                formatDateTime(tracker.curStartTime, prettyDates);
                pw.print(")");
            }
            pw.println();
        }
    }

    void printIntervalStats(IndentingPrintWriter pw, IntervalStats stats,
            boolean prettyDates, boolean skipEvents, String pkg) {
        if (prettyDates) {
            pw.printPair("timeRange", "\"" + DateUtils.formatDateRange(mContext,
                    stats.beginTime, stats.endTime, sDateFormatFlags) + "\"");
        } else {
            pw.printPair("beginTime", stats.beginTime);
            pw.printPair("endTime", stats.endTime);
        }
        pw.println();
        pw.increaseIndent();
        pw.println("packages");
        pw.increaseIndent();
        final ArrayMap<String, UsageStats> pkgStats = stats.packageStats;
        final int pkgCount = pkgStats.size();
        for (int i = 0; i < pkgCount; i++) {
            final UsageStats usageStats = pkgStats.valueAt(i);
            if (pkg != null && !pkg.equals(usageStats.mPackageName)) {
                continue;
            }
            pw.printPair("package", usageStats.mPackageName);
            pw.printPair("totalTime",
                    formatElapsedTime(usageStats.mTotalTimeInForeground, prettyDates));
            pw.printPair("lastTime", formatDateTime(usageStats.mLastTimeUsed, prettyDates));
            pw.printPair("appLaunchCount", usageStats.mAppLaunchCount);
            pw.println();
        }
        pw.decreaseIndent();

        pw.println();
        pw.println("ChooserCounts");
        pw.increaseIndent();
        for (UsageStats usageStats : pkgStats.values()) {
            if (pkg != null && !pkg.equals(usageStats.mPackageName)) {
                continue;
            }
            pw.printPair("package", usageStats.mPackageName);
            if (usageStats.mChooserCounts != null) {
                final int chooserCountSize = usageStats.mChooserCounts.size();
                for (int i = 0; i < chooserCountSize; i++) {
                    final String action = usageStats.mChooserCounts.keyAt(i);
                    final ArrayMap<String, Integer> counts = usageStats.mChooserCounts.valueAt(i);
                    final int annotationSize = counts.size();
                    for (int j = 0; j < annotationSize; j++) {
                        final String key = counts.keyAt(j);
                        final int count = counts.valueAt(j);
                        if (count != 0) {
                            pw.printPair("ChooserCounts", action + ":" + key + " is " +
                                    Integer.toString(count));
                            pw.println();
                        }
                    }
                }
            }
            pw.println();
        }
        pw.decreaseIndent();

        if (pkg == null) {
            pw.println("configurations");
            pw.increaseIndent();
            final ArrayMap<Configuration, ConfigurationStats> configStats = stats.configurations;
            final int configCount = configStats.size();
            for (int i = 0; i < configCount; i++) {
                final ConfigurationStats config = configStats.valueAt(i);
                pw.printPair("config", Configuration.resourceQualifierString(
                        config.mConfiguration));
                pw.printPair("totalTime", formatElapsedTime(config.mTotalTimeActive, prettyDates));
                pw.printPair("lastTime", formatDateTime(config.mLastTimeActive, prettyDates));
                pw.printPair("count", config.mActivationCount);
                pw.println();
            }
            pw.decreaseIndent();
            pw.println("event aggregations");
            pw.increaseIndent();
            printEventAggregation(pw, "screen-interactive", stats.interactiveTracker,
                    prettyDates);
            printEventAggregation(pw, "screen-non-interactive", stats.nonInteractiveTracker,
                    prettyDates);
            printEventAggregation(pw, "keyguard-shown", stats.keyguardShownTracker,
                    prettyDates);
            printEventAggregation(pw, "keyguard-hidden", stats.keyguardHiddenTracker,
                    prettyDates);
            pw.decreaseIndent();
        }

        // The last 24 hours of events is already printed in the non checkin dump
        // No need to repeat here.
        if (!skipEvents) {
            pw.println("events");
            pw.increaseIndent();
            final EventList events = stats.events;
            final int eventCount = events != null ? events.size() : 0;
            for (int i = 0; i < eventCount; i++) {
                final UsageEvents.Event event = events.get(i);
                if (pkg != null && !pkg.equals(event.mPackage)) {
                    continue;
                }
                printEvent(pw, event, prettyDates);
            }
            pw.decreaseIndent();
        }
        pw.decreaseIndent();
    }

    private static String intervalToString(int interval) {
        switch (interval) {
            case UsageStatsManager.INTERVAL_DAILY:
                return "daily";
            case UsageStatsManager.INTERVAL_WEEKLY:
                return "weekly";
            case UsageStatsManager.INTERVAL_MONTHLY:
                return "monthly";
            case UsageStatsManager.INTERVAL_YEARLY:
                return "yearly";
            default:
                return "?";
        }
    }

    private static String eventToString(int eventType) {
        switch (eventType) {
            case UsageEvents.Event.NONE:
                return "NONE";
            case UsageEvents.Event.MOVE_TO_BACKGROUND:
                return "MOVE_TO_BACKGROUND";
            case UsageEvents.Event.MOVE_TO_FOREGROUND:
                return "MOVE_TO_FOREGROUND";
            case UsageEvents.Event.END_OF_DAY:
                return "END_OF_DAY";
            case UsageEvents.Event.CONTINUE_PREVIOUS_DAY:
                return "CONTINUE_PREVIOUS_DAY";
            case UsageEvents.Event.CONFIGURATION_CHANGE:
                return "CONFIGURATION_CHANGE";
            case UsageEvents.Event.SYSTEM_INTERACTION:
                return "SYSTEM_INTERACTION";
            case UsageEvents.Event.USER_INTERACTION:
                return "USER_INTERACTION";
            case UsageEvents.Event.SHORTCUT_INVOCATION:
                return "SHORTCUT_INVOCATION";
            case UsageEvents.Event.CHOOSER_ACTION:
                return "CHOOSER_ACTION";
            case UsageEvents.Event.NOTIFICATION_SEEN:
                return "NOTIFICATION_SEEN";
            case UsageEvents.Event.STANDBY_BUCKET_CHANGED:
                return "STANDBY_BUCKET_CHANGED";
            case UsageEvents.Event.NOTIFICATION_INTERRUPTION:
                return "NOTIFICATION_INTERRUPTION";
            case UsageEvents.Event.SLICE_PINNED:
                return "SLICE_PINNED";
            case UsageEvents.Event.SLICE_PINNED_PRIV:
                return "SLICE_PINNED_PRIV";
            case UsageEvents.Event.SCREEN_INTERACTIVE:
                return "SCREEN_INTERACTIVE";
            case UsageEvents.Event.SCREEN_NON_INTERACTIVE:
                return "SCREEN_NON_INTERACTIVE";
            default:
                return "UNKNOWN";
        }
    }

    byte[] getBackupPayload(String key){
        return mDatabase.getBackupPayload(key);
    }

    void applyRestoredPayload(String key, byte[] payload){
        mDatabase.applyRestoredPayload(key, payload);
    }
}
