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

Commit ff9a0421 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Automerger Merge Worker
Browse files

Merge "Add tests to verify UsageStats persistence." into rvc-dev am: 564efe22 am: fedabb1b

Change-Id: Idf936c9a474b4f7f678a7f4fe851f69d279e817b
parents e05e6dd2 fedabb1b
Loading
Loading
Loading
Loading
+106 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2020 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 android.app.usage;

import static junit.framework.Assert.fail;

import android.test.suitebuilder.annotation.SmallTest;

import androidx.test.runner.AndroidJUnit4;

import com.android.internal.util.ArrayUtils;

import org.junit.Test;
import org.junit.runner.RunWith;

import java.lang.reflect.Field;

/**
 * These tests verify that all fields defined in {@link UsageStats} and {@link UsageEvents.Event}
 * are all known fields. This ensures that newly added fields or refactorings are accounted for in
 * the usagestatsservice.proto and usagestatsservice_v2.proto files.
 *
 * Note: verification for {@link com.android.server.usage.IntervalStats} fields is located in
 * {@link com.android.server.usage.IntervalStatsTests}.
 */
@RunWith(AndroidJUnit4.class)
@SmallTest
public class UsageStatsPersistenceTest {

    // All fields in this list are defined in UsageStats and persisted - please ensure they're
    // defined correctly in both usagestatsservice.proto and usagestatsservice_v2.proto
    private static final String[] USAGESTATS_PERSISTED_FIELDS = {"mBeginTimeStamp", "mEndTimeStamp",
            "mPackageName", "mPackageToken", "mLastEvent", "mAppLaunchCount", "mChooserCounts",
            "mLastTimeUsed", "mTotalTimeInForeground", "mLastTimeForegroundServiceUsed",
            "mTotalTimeForegroundServiceUsed", "mLastTimeVisible", "mTotalTimeVisible"};
    // All fields in this list are defined in UsageStats but not persisted
    private static final String[] USAGESTATS_IGNORED_FIELDS = {"CREATOR", "mActivities",
            "mForegroundServices", "mLaunchCount", "mChooserCountsObfuscated"};

    @Test
    public void testUsageStatsFields() {
        final UsageStats stats = new UsageStats();
        final Field[] fields = stats.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (!(ArrayUtils.contains(USAGESTATS_PERSISTED_FIELDS, field.getName())
                    || ArrayUtils.contains(USAGESTATS_IGNORED_FIELDS, field.getName()))) {
                fail("Found an unknown field: " + field.getName() + ". Please correctly update "
                        + "either USAGESTATS_PERSISTED_FIELDS or USAGESTATS_IGNORED_FIELDS.");
            }
        }
    }

    // All fields in this list are defined in UsageEvents.Event and persisted - please ensure
    // they're defined correctly in both usagestatsservice.proto and usagestatsservice_v2.proto
    private static final String[] USAGEEVENTS_PERSISTED_FIELDS = {"mPackage", "mPackageToken",
            "mClass", "mClassToken", "mTimeStamp", "mFlags", "mEventType", "mConfiguration",
            "mShortcutId", "mShortcutIdToken", "mBucketAndReason", "mInstanceId",
            "mNotificationChannelId", "mNotificationChannelIdToken", "mTaskRootPackage",
            "mTaskRootPackageToken", "mTaskRootClass", "mTaskRootClassToken", "mLocusId",
            "mLocusIdToken"};
    // All fields in this list are defined in UsageEvents.Event but not persisted
    private static final String[] USAGEEVENTS_IGNORED_FIELDS = {"mAction", "mContentAnnotations",
            "mContentType", "DEVICE_EVENT_PACKAGE_NAME", "FLAG_IS_PACKAGE_INSTANT_APP",
            "VALID_FLAG_BITS", "UNASSIGNED_TOKEN", "MAX_EVENT_TYPE"};
    // All fields in this list are final constants defining event types and not persisted
    private static final String[] EVENT_TYPES = {"NONE", "ACTIVITY_DESTROYED", "ACTIVITY_PAUSED",
            "ACTIVITY_RESUMED", "ACTIVITY_STOPPED", "CHOOSER_ACTION", "CONFIGURATION_CHANGE",
            "CONTINUE_PREVIOUS_DAY", "CONTINUING_FOREGROUND_SERVICE", "DEVICE_SHUTDOWN",
            "DEVICE_STARTUP", "END_OF_DAY", "FLUSH_TO_DISK", "FOREGROUND_SERVICE_START",
            "FOREGROUND_SERVICE_STOP", "KEYGUARD_HIDDEN", "KEYGUARD_SHOWN", "LOCUS_ID_SET",
            "MOVE_TO_BACKGROUND", "MOVE_TO_FOREGROUND", "NOTIFICATION_INTERRUPTION",
            "NOTIFICATION_SEEN", "ROLLOVER_FOREGROUND_SERVICE", "SCREEN_INTERACTIVE",
            "SCREEN_NON_INTERACTIVE", "SHORTCUT_INVOCATION", "SLICE_PINNED", "SLICE_PINNED_PRIV",
            "STANDBY_BUCKET_CHANGED", "SYSTEM_INTERACTION", "USER_INTERACTION", "USER_STOPPED",
            "USER_UNLOCKED"};

    @Test
    public void testUsageEventsFields() {
        final UsageEvents.Event event = new UsageEvents.Event();
        final Field[] fields = event.getClass().getDeclaredFields();
        for (Field field : fields) {
            final String name = field.getName();
            if (!(ArrayUtils.contains(USAGEEVENTS_PERSISTED_FIELDS, name)
                    || ArrayUtils.contains(USAGEEVENTS_IGNORED_FIELDS, name)
                    || ArrayUtils.contains(EVENT_TYPES, name))) {
                fail("Found an unknown field: " + name + ". Please correctly update either "
                        + "USAGEEVENTS_PERSISTED_FIELDS or USAGEEVENTS_IGNORED_FIELDS. If this "
                        + "field is a new event type, please update EVENT_TYPES instead.");
            }
        }
    }
}
+27 −0
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ import static android.app.usage.UsageEvents.Event.MAX_EVENT_TYPE;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertTrue;
import static junit.framework.Assert.fail;

import android.app.usage.UsageEvents;
import android.content.res.Configuration;
@@ -26,9 +27,12 @@ import android.test.suitebuilder.annotation.SmallTest;

import androidx.test.runner.AndroidJUnit4;

import com.android.internal.util.ArrayUtils;

import org.junit.Test;
import org.junit.runner.RunWith;

import java.lang.reflect.Field;
import java.util.Locale;

@RunWith(AndroidJUnit4.class)
@@ -191,4 +195,27 @@ public class IntervalStatsTests {
        assertTrue(intervalStats.events.size() > NUMBER_OF_EVENTS - NUMBER_OF_EVENTS_PER_PACKAGE);
        assertEquals(intervalStats.packageStats.size(), NUMBER_OF_PACKAGES);
    }

    // All fields in this list are defined in IntervalStats and persisted - please ensure they're
    // defined correctly in both usagestatsservice.proto and usagestatsservice_v2.proto
    private static final String[] INTERVALSTATS_PERSISTED_FIELDS = {"beginTime", "endTime",
            "mStringCache", "majorVersion", "minorVersion", "interactiveTracker",
            "nonInteractiveTracker", "keyguardShownTracker", "keyguardHiddenTracker",
            "packageStats", "configurations", "activeConfiguration", "events"};
    // All fields in this list are defined in IntervalStats but not persisted
    private static final String[] INTERVALSTATS_IGNORED_FIELDS = {"lastTimeSaved",
            "packageStatsObfuscated", "CURRENT_MAJOR_VERSION", "CURRENT_MINOR_VERSION", "TAG"};

    @Test
    public void testIntervalStatsFieldsAreKnown() {
        final IntervalStats stats = new IntervalStats();
        final Field[] fields = stats.getClass().getDeclaredFields();
        for (Field field : fields) {
            if (!(ArrayUtils.contains(INTERVALSTATS_PERSISTED_FIELDS, field.getName())
                    || ArrayUtils.contains(INTERVALSTATS_IGNORED_FIELDS, field.getName()))) {
                fail("Found an unknown field: " + field.getName() + ". Please correctly update "
                        + "either INTERVALSTATS_PERSISTED_FIELDS or INTERVALSTATS_IGNORED_FIELDS.");
            }
        }
    }
}