| /* |
| * Copyright (C) 2018 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.frameworks.perftests.usage.tests; |
| |
| import static junit.framework.Assert.assertEquals; |
| |
| import android.app.usage.UsageEvents; |
| import android.app.usage.UsageStatsManager; |
| import android.content.Context; |
| import android.os.SystemClock; |
| import android.perftests.utils.ManualBenchmarkState; |
| import android.perftests.utils.PerfManualStatusReporter; |
| import android.support.test.InstrumentationRegistry; |
| import android.support.test.filters.LargeTest; |
| import android.support.test.runner.AndroidJUnit4; |
| |
| import com.android.server.usage.IntervalStats; |
| import com.android.server.usage.UsageStatsDatabase; |
| import com.android.server.usage.UsageStatsDatabase.StatCombiner; |
| |
| import org.junit.BeforeClass; |
| import org.junit.Rule; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.util.List; |
| |
| @RunWith(AndroidJUnit4.class) |
| @LargeTest |
| public class UsageStatsDatabasePerfTest { |
| protected static Context sContext; |
| private static UsageStatsDatabase sUsageStatsDatabase; |
| private static File mTestDir; |
| |
| // Represents how many apps might have used in a day by a user with a few apps |
| final static int FEW_PKGS = 10; |
| // Represent how many apps might have used in a day by a user with many apps |
| final static int MANY_PKGS = 50; |
| // Represents how many usage events per app a device might have with light usage |
| final static int LIGHT_USE = 10; |
| // Represents how many usage events per app a device might have with heavy usage |
| final static int HEAVY_USE = 50; |
| |
| private static final StatCombiner<UsageEvents.Event> sUsageStatsCombiner = |
| new StatCombiner<UsageEvents.Event>() { |
| @Override |
| public void combine(IntervalStats stats, boolean mutable, |
| List<UsageEvents.Event> accResult) { |
| final int size = stats.events.size(); |
| for (int i = 0; i < size; i++) { |
| accResult.add(stats.events.get(i)); |
| } |
| } |
| }; |
| |
| |
| @Rule |
| public PerfManualStatusReporter mPerfManualStatusReporter = new PerfManualStatusReporter(); |
| |
| @BeforeClass |
| public static void setUpOnce() { |
| sContext = InstrumentationRegistry.getTargetContext(); |
| mTestDir = new File(sContext.getFilesDir(), "UsageStatsDatabasePerfTest"); |
| sUsageStatsDatabase = new UsageStatsDatabase(mTestDir); |
| sUsageStatsDatabase.init(1); |
| } |
| |
| private static void populateIntervalStats(IntervalStats intervalStats, int packageCount, |
| int eventsPerPackage) { |
| for (int pkg = 0; pkg < packageCount; pkg++) { |
| UsageEvents.Event event = new UsageEvents.Event(); |
| event.mPackage = "fake.package.name" + pkg; |
| event.mClass = event.mPackage + ".class1"; |
| event.mTimeStamp = 1; |
| event.mEventType = UsageEvents.Event.ACTIVITY_RESUMED; |
| for (int evt = 0; evt < eventsPerPackage; evt++) { |
| intervalStats.events.insert(event); |
| intervalStats.update(event.mPackage, event.mClass, event.mTimeStamp, |
| event.mEventType, 1); |
| } |
| } |
| } |
| |
| private static void clearUsageStatsFiles() { |
| File[] intervalDirs = mTestDir.listFiles(); |
| for (File intervalDir : intervalDirs) { |
| if (intervalDir.isDirectory()) { |
| File[] usageFiles = intervalDir.listFiles(); |
| for (File f : usageFiles) { |
| f.delete(); |
| } |
| } |
| } |
| } |
| |
| private void runQueryUsageStatsTest(int packageCount, int eventsPerPackage) throws IOException { |
| final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState(); |
| IntervalStats intervalStats = new IntervalStats(); |
| populateIntervalStats(intervalStats, packageCount, eventsPerPackage); |
| sUsageStatsDatabase.putUsageStats(0, intervalStats); |
| long elapsedTimeNs = 0; |
| while (benchmarkState.keepRunning(elapsedTimeNs)) { |
| final long startTime = SystemClock.elapsedRealtimeNanos(); |
| List<UsageEvents.Event> temp = sUsageStatsDatabase.queryUsageStats( |
| UsageStatsManager.INTERVAL_DAILY, 0, 2, sUsageStatsCombiner); |
| final long endTime = SystemClock.elapsedRealtimeNanos(); |
| elapsedTimeNs = endTime - startTime; |
| assertEquals(packageCount * eventsPerPackage, temp.size()); |
| } |
| } |
| |
| private void runPutUsageStatsTest(int packageCount, int eventsPerPackage) throws IOException { |
| final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState(); |
| IntervalStats intervalStats = new IntervalStats(); |
| populateIntervalStats(intervalStats, packageCount, eventsPerPackage); |
| long elapsedTimeNs = 0; |
| while (benchmarkState.keepRunning(elapsedTimeNs)) { |
| final long startTime = SystemClock.elapsedRealtimeNanos(); |
| sUsageStatsDatabase.putUsageStats(0, intervalStats); |
| final long endTime = SystemClock.elapsedRealtimeNanos(); |
| elapsedTimeNs = endTime - startTime; |
| clearUsageStatsFiles(); |
| } |
| } |
| |
| @Test |
| public void testQueryUsageStats_FewPkgsLightUse() throws IOException { |
| runQueryUsageStatsTest(FEW_PKGS, LIGHT_USE); |
| } |
| |
| @Test |
| public void testPutUsageStats_FewPkgsLightUse() throws IOException { |
| runPutUsageStatsTest(FEW_PKGS, LIGHT_USE); |
| } |
| |
| @Test |
| public void testQueryUsageStats_FewPkgsHeavyUse() throws IOException { |
| runQueryUsageStatsTest(FEW_PKGS, HEAVY_USE); |
| } |
| |
| @Test |
| public void testPutUsageStats_FewPkgsHeavyUse() throws IOException { |
| runPutUsageStatsTest(FEW_PKGS, HEAVY_USE); |
| } |
| |
| @Test |
| public void testQueryUsageStats_ManyPkgsLightUse() throws IOException { |
| runQueryUsageStatsTest(MANY_PKGS, LIGHT_USE); |
| } |
| |
| @Test |
| public void testPutUsageStats_ManyPkgsLightUse() throws IOException { |
| runPutUsageStatsTest(MANY_PKGS, LIGHT_USE); |
| } |
| |
| @Test |
| public void testQueryUsageStats_ManyPkgsHeavyUse() throws IOException { |
| runQueryUsageStatsTest(MANY_PKGS, HEAVY_USE); |
| } |
| |
| @Test |
| public void testPutUsageStats_ManyPkgsHeavyUse() throws IOException { |
| runPutUsageStatsTest(MANY_PKGS, HEAVY_USE); |
| } |
| } |