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

Commit a6ae2f2f authored by Varun Shah's avatar Varun Shah Committed by Automerger Merge Worker
Browse files

Merge "Update how UsageStats timestamps are written to disk." into rvc-dev am: abe10376

Change-Id: I18363924643ea69eb4f2243b8da28286be73d604
parents 6516d8e0 abe10376
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -126,7 +126,7 @@ public class UsageStatsDatabaseTest {

        mIntervalStats.majorVersion = 7;
        mIntervalStats.minorVersion = 8;
        mIntervalStats.beginTime = time;
        mIntervalStats.beginTime = time - 1;
        mIntervalStats.interactiveTracker.count = 2;
        mIntervalStats.interactiveTracker.duration = 111111;
        mIntervalStats.nonInteractiveTracker.count = 3;
+0 −4
Original line number Diff line number Diff line
@@ -253,10 +253,6 @@ public class IntervalStats {
                            }
                            break;
                    }
                    if (event.mTimeStamp == 0) {
                        //mTimestamp not set, assume default value 0 plus beginTime
                        event.mTimeStamp = beginTime;
                    }
                    return event;
            }
        }
+16 −25
Original line number Diff line number Diff line
@@ -149,10 +149,6 @@ final class UsageStatsProto {
                    break;
            }
        }
        if (stats.mLastTimeUsed == 0) {
            // mLastTimeUsed was not assigned, assume default value of 0 plus beginTime;
            stats.mLastTimeUsed = statsOut.beginTime;
        }
        proto.end(token);
    }

@@ -289,10 +285,6 @@ final class UsageStatsProto {
                    configActive = proto.readBoolean(IntervalStatsProto.Configuration.ACTIVE);
                    break;
                case ProtoInputStream.NO_MORE_FIELDS:
                    if (configStats.mLastTimeActive == 0) {
                        //mLastTimeActive was not assigned, assume default value of 0 plus beginTime
                        configStats.mLastTimeActive = statsOut.beginTime;
                    }
                    if (configActive) {
                        statsOut.activeConfiguration = configStats.mConfiguration;
                    }
@@ -336,21 +328,21 @@ final class UsageStatsProto {
            // Package not in Stringpool for some reason, write full string instead
            proto.write(IntervalStatsProto.UsageStats.PACKAGE, usageStats.mPackageName);
        }
        // Time attributes stored as an offset of the beginTime.
        proto.write(IntervalStatsProto.UsageStats.LAST_TIME_ACTIVE_MS,
                usageStats.mLastTimeUsed - stats.beginTime);
        UsageStatsProtoV2.writeOffsetTimestamp(proto,
                IntervalStatsProto.UsageStats.LAST_TIME_ACTIVE_MS,
                usageStats.mLastTimeUsed, stats.beginTime);
        proto.write(IntervalStatsProto.UsageStats.TOTAL_TIME_ACTIVE_MS,
                usageStats.mTotalTimeInForeground);
        proto.write(IntervalStatsProto.UsageStats.LAST_EVENT,
                usageStats.mLastEvent);
        // Time attributes stored as an offset of the beginTime.
        proto.write(IntervalStatsProto.UsageStats.LAST_TIME_SERVICE_USED_MS,
                usageStats.mLastTimeForegroundServiceUsed - stats.beginTime);
        UsageStatsProtoV2.writeOffsetTimestamp(proto,
                IntervalStatsProto.UsageStats.LAST_TIME_SERVICE_USED_MS,
                usageStats.mLastTimeForegroundServiceUsed, stats.beginTime);
        proto.write(IntervalStatsProto.UsageStats.TOTAL_TIME_SERVICE_USED_MS,
                usageStats.mTotalTimeForegroundServiceUsed);
        // Time attributes stored as an offset of the beginTime.
        proto.write(IntervalStatsProto.UsageStats.LAST_TIME_VISIBLE_MS,
                usageStats.mLastTimeVisible - stats.beginTime);
        UsageStatsProtoV2.writeOffsetTimestamp(proto,
                IntervalStatsProto.UsageStats.LAST_TIME_VISIBLE_MS,
                usageStats.mLastTimeVisible, stats.beginTime);
        proto.write(IntervalStatsProto.UsageStats.TOTAL_TIME_VISIBLE_MS,
                usageStats.mTotalTimeVisible);
        proto.write(IntervalStatsProto.UsageStats.APP_LAUNCH_COUNT, usageStats.mAppLaunchCount);
@@ -411,8 +403,9 @@ final class UsageStatsProto {
            throws IllegalArgumentException {
        final long token = proto.start(fieldId);
        configStats.mConfiguration.dumpDebug(proto, IntervalStatsProto.Configuration.CONFIG);
        proto.write(IntervalStatsProto.Configuration.LAST_TIME_ACTIVE_MS,
                configStats.mLastTimeActive - stats.beginTime);
        UsageStatsProtoV2.writeOffsetTimestamp(proto,
                IntervalStatsProto.Configuration.LAST_TIME_ACTIVE_MS,
                configStats.mLastTimeActive, stats.beginTime);
        proto.write(IntervalStatsProto.Configuration.TOTAL_TIME_ACTIVE_MS,
                configStats.mTotalTimeActive);
        proto.write(IntervalStatsProto.Configuration.COUNT, configStats.mActivationCount);
@@ -439,7 +432,8 @@ final class UsageStatsProto {
                proto.write(IntervalStatsProto.Event.CLASS, event.mClass);
            }
        }
        proto.write(IntervalStatsProto.Event.TIME_MS, event.mTimeStamp - stats.beginTime);
        UsageStatsProtoV2.writeOffsetTimestamp(proto, IntervalStatsProto.Event.TIME_MS,
                event.mTimeStamp, stats.beginTime);
        proto.write(IntervalStatsProto.Event.FLAGS, event.mFlags);
        proto.write(IntervalStatsProto.Event.TYPE, event.mEventType);
        proto.write(IntervalStatsProto.Event.INSTANCE_ID, event.mInstanceId);
@@ -566,10 +560,6 @@ final class UsageStatsProto {
                    }
                    break;
                case ProtoInputStream.NO_MORE_FIELDS:
                    if (statsOut.endTime == 0) {
                        // endTime not assigned, assume default value of 0 plus beginTime
                        statsOut.endTime = statsOut.beginTime;
                    }
                    statsOut.upgradeIfNeeded();
                    return;
            }
@@ -585,7 +575,8 @@ final class UsageStatsProto {
    public static void write(OutputStream out, IntervalStats stats)
            throws IOException, IllegalArgumentException {
        final ProtoOutputStream proto = new ProtoOutputStream(out);
        proto.write(IntervalStatsProto.END_TIME_MS, stats.endTime - stats.beginTime);
        proto.write(IntervalStatsProto.END_TIME_MS,
                UsageStatsProtoV2.getOffsetTimestamp(stats.endTime, stats.beginTime));
        proto.write(IntervalStatsProto.MAJOR_VERSION, stats.majorVersion);
        proto.write(IntervalStatsProto.MINOR_VERSION, stats.minorVersion);
        // String pool should be written before the rest of the usage stats
+31 −26
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@ import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.concurrent.TimeUnit;

/**
 * UsageStats reader/writer V2 for Protocol Buffer format.
@@ -37,6 +38,8 @@ import java.util.LinkedList;
final class UsageStatsProtoV2 {
    private static final String TAG = "UsageStatsProtoV2";

    private static final long ONE_HOUR_MS = TimeUnit.HOURS.toMillis(1);

    // Static-only utility class.
    private UsageStatsProtoV2() {}

@@ -88,10 +91,6 @@ final class UsageStatsProtoV2 {
                            UsageStatsObfuscatedProto.TOTAL_TIME_VISIBLE_MS);
                    break;
                case ProtoInputStream.NO_MORE_FIELDS:
                    // mLastTimeUsed was not read, assume default value of 0 plus beginTime
                    if (stats.mLastTimeUsed == 0) {
                        stats.mLastTimeUsed = beginTime;
                    }
                    return stats;
            }
        }
@@ -219,10 +218,6 @@ final class UsageStatsProtoV2 {
                            IntervalStatsObfuscatedProto.Configuration.ACTIVE);
                    break;
                case ProtoInputStream.NO_MORE_FIELDS:
                    // mLastTimeActive was not assigned, assume default value of 0 plus beginTime
                    if (configStats.mLastTimeActive == 0) {
                        configStats.mLastTimeActive = stats.beginTime;
                    }
                    if (configActive) {
                        stats.activeConfiguration = configStats.mConfiguration;
                    }
@@ -282,27 +277,40 @@ final class UsageStatsProtoV2 {
                            EventObfuscatedProto.LOCUS_ID_TOKEN) - 1;
                    break;
                case ProtoInputStream.NO_MORE_FIELDS:
                    // timeStamp was not read, assume default value 0 plus beginTime
                    if (event.mTimeStamp == 0) {
                        event.mTimeStamp = beginTime;
                    }
                    return event.mPackageToken == PackagesTokenData.UNASSIGNED_TOKEN ? null : event;
            }
        }
    }

    static void writeOffsetTimestamp(ProtoOutputStream proto, long fieldId,
            long timestamp, long beginTime) {
        // timestamps will only be written if they're after the begin time
        // a grace period of one hour before the begin time is allowed because of rollover logic
        final long rolloverGracePeriod = beginTime - ONE_HOUR_MS;
        if (timestamp > rolloverGracePeriod) {
            // time attributes are stored as an offset of the begin time (given offset)
            proto.write(fieldId, getOffsetTimestamp(timestamp, beginTime));
        }
    }

    static long getOffsetTimestamp(long timestamp, long offset) {
        final long offsetTimestamp = timestamp - offset;
        // add one ms to timestamp if 0 to ensure it's written to proto (default values are ignored)
        return offsetTimestamp == 0 ? offsetTimestamp + 1 : offsetTimestamp;
    }

    private static void writeUsageStats(ProtoOutputStream proto, final long beginTime,
            final UsageStats stats) throws IllegalArgumentException {
        // Time attributes stored as an offset of the beginTime.
        proto.write(UsageStatsObfuscatedProto.PACKAGE_TOKEN, stats.mPackageToken + 1);
        proto.write(UsageStatsObfuscatedProto.LAST_TIME_ACTIVE_MS, stats.mLastTimeUsed - beginTime);
        writeOffsetTimestamp(proto, UsageStatsObfuscatedProto.LAST_TIME_ACTIVE_MS,
                stats.mLastTimeUsed, beginTime);
        proto.write(UsageStatsObfuscatedProto.TOTAL_TIME_ACTIVE_MS, stats.mTotalTimeInForeground);
        proto.write(UsageStatsObfuscatedProto.LAST_TIME_SERVICE_USED_MS,
                stats.mLastTimeForegroundServiceUsed - beginTime);
        writeOffsetTimestamp(proto, UsageStatsObfuscatedProto.LAST_TIME_SERVICE_USED_MS,
                stats.mLastTimeForegroundServiceUsed, beginTime);
        proto.write(UsageStatsObfuscatedProto.TOTAL_TIME_SERVICE_USED_MS,
                stats.mTotalTimeForegroundServiceUsed);
        proto.write(UsageStatsObfuscatedProto.LAST_TIME_VISIBLE_MS,
                stats.mLastTimeVisible - beginTime);
        writeOffsetTimestamp(proto, UsageStatsObfuscatedProto.LAST_TIME_VISIBLE_MS,
                stats.mLastTimeVisible, beginTime);
        proto.write(UsageStatsObfuscatedProto.TOTAL_TIME_VISIBLE_MS, stats.mTotalTimeVisible);
        proto.write(UsageStatsObfuscatedProto.APP_LAUNCH_COUNT, stats.mAppLaunchCount);
        try {
@@ -361,8 +369,8 @@ final class UsageStatsProtoV2 {
            throws IllegalArgumentException {
        configStats.mConfiguration.dumpDebug(proto,
                IntervalStatsObfuscatedProto.Configuration.CONFIG);
        proto.write(IntervalStatsObfuscatedProto.Configuration.LAST_TIME_ACTIVE_MS,
                configStats.mLastTimeActive - statsBeginTime);
        writeOffsetTimestamp(proto, IntervalStatsObfuscatedProto.Configuration.LAST_TIME_ACTIVE_MS,
                configStats.mLastTimeActive, statsBeginTime);
        proto.write(IntervalStatsObfuscatedProto.Configuration.TOTAL_TIME_ACTIVE_MS,
                configStats.mTotalTimeActive);
        proto.write(IntervalStatsObfuscatedProto.Configuration.COUNT, configStats.mActivationCount);
@@ -375,7 +383,7 @@ final class UsageStatsProtoV2 {
        if (event.mClassToken != PackagesTokenData.UNASSIGNED_TOKEN) {
            proto.write(EventObfuscatedProto.CLASS_TOKEN, event.mClassToken + 1);
        }
        proto.write(EventObfuscatedProto.TIME_MS, event.mTimeStamp - statsBeginTime);
        writeOffsetTimestamp(proto, EventObfuscatedProto.TIME_MS, event.mTimeStamp, statsBeginTime);
        proto.write(EventObfuscatedProto.FLAGS, event.mFlags);
        proto.write(EventObfuscatedProto.TYPE, event.mEventType);
        proto.write(EventObfuscatedProto.INSTANCE_ID, event.mInstanceId);
@@ -489,10 +497,6 @@ final class UsageStatsProtoV2 {
                    }
                    break;
                case ProtoInputStream.NO_MORE_FIELDS:
                    // endTime not assigned, assume default value of 0 plus beginTime
                    if (stats.endTime == 0) {
                        stats.endTime = stats.beginTime;
                    }
                    // update the begin and end time stamps for all usage stats
                    final int usageStatsSize = stats.packageStatsObfuscated.size();
                    for (int i = 0; i < usageStatsSize; i++) {
@@ -514,7 +518,8 @@ final class UsageStatsProtoV2 {
    public static void write(OutputStream out, IntervalStats stats)
            throws IOException, IllegalArgumentException {
        final ProtoOutputStream proto = new ProtoOutputStream(out);
        proto.write(IntervalStatsObfuscatedProto.END_TIME_MS, stats.endTime - stats.beginTime);
        proto.write(IntervalStatsObfuscatedProto.END_TIME_MS,
                getOffsetTimestamp(stats.endTime, stats.beginTime));
        proto.write(IntervalStatsObfuscatedProto.MAJOR_VERSION, stats.majorVersion);
        proto.write(IntervalStatsObfuscatedProto.MINOR_VERSION, stats.minorVersion);