1 /* 2 * Copyright (C) 2018 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 * use this file except in compliance with the License. You may obtain a copy of 6 * the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 * License for the specific language governing permissions and limitations under 14 * the License. 15 */ 16 17 package com.android.frameworks.perftests.usage.tests; 18 19 import static junit.framework.Assert.assertEquals; 20 21 import android.app.usage.UsageEvents; 22 import android.app.usage.UsageStatsManager; 23 import android.content.Context; 24 import android.os.SystemClock; 25 import android.perftests.utils.ManualBenchmarkState; 26 import android.perftests.utils.PerfManualStatusReporter; 27 28 import androidx.test.InstrumentationRegistry; 29 import androidx.test.filters.LargeTest; 30 import androidx.test.runner.AndroidJUnit4; 31 32 import com.android.server.usage.IntervalStats; 33 import com.android.server.usage.UsageStatsDatabase; 34 import com.android.server.usage.UsageStatsDatabase.StatCombiner; 35 36 import org.junit.BeforeClass; 37 import org.junit.Rule; 38 import org.junit.Test; 39 import org.junit.runner.RunWith; 40 41 import java.io.File; 42 import java.io.IOException; 43 import java.util.List; 44 45 @RunWith(AndroidJUnit4.class) 46 @LargeTest 47 public class UsageStatsDatabasePerfTest { 48 protected static Context sContext; 49 private static UsageStatsDatabase sUsageStatsDatabase; 50 private static File mTestDir; 51 52 // Represents how many apps might have used in a day by a user with a few apps 53 final static int FEW_PKGS = 10; 54 // Represent how many apps might have used in a day by a user with many apps 55 final static int MANY_PKGS = 50; 56 // Represents how many usage events per app a device might have with light usage 57 final static int LIGHT_USE = 10; 58 // Represents how many usage events per app a device might have with heavy usage 59 final static int HEAVY_USE = 50; 60 61 private static final StatCombiner<UsageEvents.Event> sUsageStatsCombiner = 62 new StatCombiner<UsageEvents.Event>() { 63 @Override 64 public void combine(IntervalStats stats, boolean mutable, 65 List<UsageEvents.Event> accResult) { 66 final int size = stats.events.size(); 67 for (int i = 0; i < size; i++) { 68 accResult.add(stats.events.get(i)); 69 } 70 } 71 }; 72 73 74 @Rule 75 public PerfManualStatusReporter mPerfManualStatusReporter = new PerfManualStatusReporter(); 76 77 @BeforeClass setUpOnce()78 public static void setUpOnce() { 79 sContext = InstrumentationRegistry.getTargetContext(); 80 mTestDir = new File(sContext.getFilesDir(), "UsageStatsDatabasePerfTest"); 81 sUsageStatsDatabase = new UsageStatsDatabase(mTestDir); 82 sUsageStatsDatabase.init(1); 83 } 84 populateIntervalStats(IntervalStats intervalStats, int packageCount, int eventsPerPackage)85 private static void populateIntervalStats(IntervalStats intervalStats, int packageCount, 86 int eventsPerPackage) { 87 for (int pkg = 0; pkg < packageCount; pkg++) { 88 UsageEvents.Event event = new UsageEvents.Event(); 89 event.mPackage = "fake.package.name" + pkg; 90 event.mClass = event.mPackage + ".class1"; 91 event.mTimeStamp = 1; 92 event.mEventType = UsageEvents.Event.ACTIVITY_RESUMED; 93 for (int evt = 0; evt < eventsPerPackage; evt++) { 94 intervalStats.events.insert(event); 95 intervalStats.update(event.mPackage, event.mClass, event.mTimeStamp, 96 event.mEventType, 1); 97 } 98 } 99 } 100 clearUsageStatsFiles()101 private static void clearUsageStatsFiles() { 102 File[] intervalDirs = mTestDir.listFiles(); 103 for (File intervalDir : intervalDirs) { 104 if (intervalDir.isDirectory()) { 105 File[] usageFiles = intervalDir.listFiles(); 106 for (File f : usageFiles) { 107 f.delete(); 108 } 109 } 110 } 111 } 112 runQueryUsageStatsTest(int packageCount, int eventsPerPackage)113 private void runQueryUsageStatsTest(int packageCount, int eventsPerPackage) throws IOException { 114 final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState(); 115 IntervalStats intervalStats = new IntervalStats(); 116 populateIntervalStats(intervalStats, packageCount, eventsPerPackage); 117 sUsageStatsDatabase.putUsageStats(0, intervalStats); 118 long elapsedTimeNs = 0; 119 while (benchmarkState.keepRunning(elapsedTimeNs)) { 120 final long startTime = SystemClock.elapsedRealtimeNanos(); 121 List<UsageEvents.Event> temp = sUsageStatsDatabase.queryUsageStats( 122 UsageStatsManager.INTERVAL_DAILY, 0, 2, sUsageStatsCombiner); 123 final long endTime = SystemClock.elapsedRealtimeNanos(); 124 elapsedTimeNs = endTime - startTime; 125 assertEquals(packageCount * eventsPerPackage, temp.size()); 126 } 127 } 128 runPutUsageStatsTest(int packageCount, int eventsPerPackage)129 private void runPutUsageStatsTest(int packageCount, int eventsPerPackage) throws IOException { 130 final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState(); 131 IntervalStats intervalStats = new IntervalStats(); 132 populateIntervalStats(intervalStats, packageCount, eventsPerPackage); 133 long elapsedTimeNs = 0; 134 while (benchmarkState.keepRunning(elapsedTimeNs)) { 135 final long startTime = SystemClock.elapsedRealtimeNanos(); 136 sUsageStatsDatabase.putUsageStats(0, intervalStats); 137 final long endTime = SystemClock.elapsedRealtimeNanos(); 138 elapsedTimeNs = endTime - startTime; 139 clearUsageStatsFiles(); 140 } 141 } 142 143 @Test testQueryUsageStats_FewPkgsLightUse()144 public void testQueryUsageStats_FewPkgsLightUse() throws IOException { 145 runQueryUsageStatsTest(FEW_PKGS, LIGHT_USE); 146 } 147 148 @Test testPutUsageStats_FewPkgsLightUse()149 public void testPutUsageStats_FewPkgsLightUse() throws IOException { 150 runPutUsageStatsTest(FEW_PKGS, LIGHT_USE); 151 } 152 153 @Test testQueryUsageStats_FewPkgsHeavyUse()154 public void testQueryUsageStats_FewPkgsHeavyUse() throws IOException { 155 runQueryUsageStatsTest(FEW_PKGS, HEAVY_USE); 156 } 157 158 @Test testPutUsageStats_FewPkgsHeavyUse()159 public void testPutUsageStats_FewPkgsHeavyUse() throws IOException { 160 runPutUsageStatsTest(FEW_PKGS, HEAVY_USE); 161 } 162 163 @Test testQueryUsageStats_ManyPkgsLightUse()164 public void testQueryUsageStats_ManyPkgsLightUse() throws IOException { 165 runQueryUsageStatsTest(MANY_PKGS, LIGHT_USE); 166 } 167 168 @Test testPutUsageStats_ManyPkgsLightUse()169 public void testPutUsageStats_ManyPkgsLightUse() throws IOException { 170 runPutUsageStatsTest(MANY_PKGS, LIGHT_USE); 171 } 172 173 @Test testQueryUsageStats_ManyPkgsHeavyUse()174 public void testQueryUsageStats_ManyPkgsHeavyUse() throws IOException { 175 runQueryUsageStatsTest(MANY_PKGS, HEAVY_USE); 176 } 177 178 @Test testPutUsageStats_ManyPkgsHeavyUse()179 public void testPutUsageStats_ManyPkgsHeavyUse() throws IOException { 180 runPutUsageStatsTest(MANY_PKGS, HEAVY_USE); 181 } 182 } 183