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.PackagesTokenData; 34 import com.android.server.usage.UsageStatsDatabase; 35 import com.android.server.usage.UsageStatsDatabase.StatCombiner; 36 37 import org.junit.BeforeClass; 38 import org.junit.Rule; 39 import org.junit.Test; 40 import org.junit.runner.RunWith; 41 42 import java.io.File; 43 import java.io.IOException; 44 import java.util.List; 45 46 @RunWith(AndroidJUnit4.class) 47 @LargeTest 48 public class UsageStatsDatabasePerfTest { 49 protected static Context sContext; 50 private static UsageStatsDatabase sUsageStatsDatabase; 51 private static File mTestDir; 52 53 // Represents how many apps might have used in a day by a user with a few apps 54 final static int FEW_PKGS = 10; 55 // Represent how many apps might have used in a day by a user with many apps 56 final static int MANY_PKGS = 50; 57 // Represents how many usage events per app a device might have with light usage 58 final static int LIGHT_USE = 10; 59 // Represents how many usage events per app a device might have with heavy usage 60 final static int HEAVY_USE = 50; 61 62 private static final StatCombiner<UsageEvents.Event> sUsageStatsCombiner = 63 new StatCombiner<UsageEvents.Event>() { 64 @Override 65 public void combine(IntervalStats stats, boolean mutable, 66 List<UsageEvents.Event> accResult) { 67 final int size = stats.events.size(); 68 for (int i = 0; i < size; i++) { 69 accResult.add(stats.events.get(i)); 70 } 71 } 72 }; 73 74 75 @Rule 76 public PerfManualStatusReporter mPerfManualStatusReporter = new PerfManualStatusReporter(); 77 78 @BeforeClass setUpOnce()79 public static void setUpOnce() { 80 sContext = InstrumentationRegistry.getTargetContext(); 81 mTestDir = new File(sContext.getFilesDir(), "UsageStatsDatabasePerfTest"); 82 sUsageStatsDatabase = new UsageStatsDatabase(mTestDir); 83 sUsageStatsDatabase.readMappingsLocked(); 84 sUsageStatsDatabase.init(1); 85 } 86 populateIntervalStats(IntervalStats intervalStats, int packageCount, int eventsPerPackage)87 private static void populateIntervalStats(IntervalStats intervalStats, int packageCount, 88 int eventsPerPackage) { 89 for (int pkg = 0; pkg < packageCount; pkg++) { 90 UsageEvents.Event event = new UsageEvents.Event(); 91 event.mPackage = "fake.package.name" + pkg; 92 event.mClass = event.mPackage + ".class1"; 93 event.mTimeStamp = 1; 94 event.mEventType = UsageEvents.Event.ACTIVITY_RESUMED; 95 for (int evt = 0; evt < eventsPerPackage; evt++) { 96 intervalStats.events.insert(event); 97 intervalStats.update(event.mPackage, event.mClass, event.mTimeStamp, 98 event.mEventType, 1); 99 } 100 } 101 } 102 clearUsageStatsFiles()103 private static void clearUsageStatsFiles() { 104 File[] intervalDirs = mTestDir.listFiles(); 105 for (File intervalDir : intervalDirs) { 106 if (intervalDir.isDirectory()) { 107 File[] usageFiles = intervalDir.listFiles(); 108 for (File f : usageFiles) { 109 f.delete(); 110 } 111 } 112 } 113 } 114 runQueryUsageStatsTest(int packageCount, int eventsPerPackage)115 private void runQueryUsageStatsTest(int packageCount, int eventsPerPackage) throws IOException { 116 final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState(); 117 IntervalStats intervalStats = new IntervalStats(); 118 populateIntervalStats(intervalStats, packageCount, eventsPerPackage); 119 sUsageStatsDatabase.putUsageStats(0, intervalStats); 120 long elapsedTimeNs = 0; 121 while (benchmarkState.keepRunning(elapsedTimeNs)) { 122 final long startTime = SystemClock.elapsedRealtimeNanos(); 123 List<UsageEvents.Event> temp = sUsageStatsDatabase.queryUsageStats( 124 UsageStatsManager.INTERVAL_DAILY, 0, 2, sUsageStatsCombiner); 125 final long endTime = SystemClock.elapsedRealtimeNanos(); 126 elapsedTimeNs = endTime - startTime; 127 assertEquals(packageCount * eventsPerPackage, temp.size()); 128 } 129 } 130 runPutUsageStatsTest(int packageCount, int eventsPerPackage)131 private void runPutUsageStatsTest(int packageCount, int eventsPerPackage) throws IOException { 132 final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState(); 133 IntervalStats intervalStats = new IntervalStats(); 134 populateIntervalStats(intervalStats, packageCount, eventsPerPackage); 135 long elapsedTimeNs = 0; 136 while (benchmarkState.keepRunning(elapsedTimeNs)) { 137 final long startTime = SystemClock.elapsedRealtimeNanos(); 138 sUsageStatsDatabase.putUsageStats(0, intervalStats); 139 final long endTime = SystemClock.elapsedRealtimeNanos(); 140 elapsedTimeNs = endTime - startTime; 141 clearUsageStatsFiles(); 142 } 143 } 144 runObfuscateStatsTest(int packageCount, int eventsPerPackage)145 private void runObfuscateStatsTest(int packageCount, int eventsPerPackage) { 146 final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState(); 147 IntervalStats intervalStats = new IntervalStats(); 148 populateIntervalStats(intervalStats, packageCount, eventsPerPackage); 149 long elapsedTimeNs = 0; 150 while (benchmarkState.keepRunning(elapsedTimeNs)) { 151 final long startTime = SystemClock.elapsedRealtimeNanos(); 152 PackagesTokenData packagesTokenData = new PackagesTokenData(); 153 intervalStats.obfuscateData(packagesTokenData); 154 final long endTime = SystemClock.elapsedRealtimeNanos(); 155 elapsedTimeNs = endTime - startTime; 156 clearUsageStatsFiles(); 157 } 158 } 159 runDeobfuscateStatsTest(int packageCount, int eventsPerPackage)160 private void runDeobfuscateStatsTest(int packageCount, int eventsPerPackage) { 161 final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState(); 162 IntervalStats intervalStats = new IntervalStats(); 163 populateIntervalStats(intervalStats, packageCount, eventsPerPackage); 164 long elapsedTimeNs = 0; 165 while (benchmarkState.keepRunning(elapsedTimeNs)) { 166 PackagesTokenData packagesTokenData = new PackagesTokenData(); 167 intervalStats.obfuscateData(packagesTokenData); 168 final long startTime = SystemClock.elapsedRealtimeNanos(); 169 intervalStats.deobfuscateData(packagesTokenData); 170 final long endTime = SystemClock.elapsedRealtimeNanos(); 171 elapsedTimeNs = endTime - startTime; 172 clearUsageStatsFiles(); 173 } 174 } 175 176 @Test testQueryUsageStats_FewPkgsLightUse()177 public void testQueryUsageStats_FewPkgsLightUse() throws IOException { 178 runQueryUsageStatsTest(FEW_PKGS, LIGHT_USE); 179 } 180 181 @Test testPutUsageStats_FewPkgsLightUse()182 public void testPutUsageStats_FewPkgsLightUse() throws IOException { 183 runPutUsageStatsTest(FEW_PKGS, LIGHT_USE); 184 } 185 186 @Test testObfuscateStats_FewPkgsLightUse()187 public void testObfuscateStats_FewPkgsLightUse() { 188 runObfuscateStatsTest(FEW_PKGS, LIGHT_USE); 189 } 190 191 @Test testDeobfuscateStats_FewPkgsLightUse()192 public void testDeobfuscateStats_FewPkgsLightUse() { 193 runDeobfuscateStatsTest(FEW_PKGS, LIGHT_USE); 194 } 195 196 @Test testQueryUsageStats_FewPkgsHeavyUse()197 public void testQueryUsageStats_FewPkgsHeavyUse() throws IOException { 198 runQueryUsageStatsTest(FEW_PKGS, HEAVY_USE); 199 } 200 201 @Test testPutUsageStats_FewPkgsHeavyUse()202 public void testPutUsageStats_FewPkgsHeavyUse() throws IOException { 203 runPutUsageStatsTest(FEW_PKGS, HEAVY_USE); 204 } 205 206 @Test testObfuscateStats_FewPkgsHeavyUse()207 public void testObfuscateStats_FewPkgsHeavyUse() { 208 runObfuscateStatsTest(FEW_PKGS, HEAVY_USE); 209 } 210 211 @Test testDeobfuscateStats_FewPkgsHeavyUse()212 public void testDeobfuscateStats_FewPkgsHeavyUse() { 213 runDeobfuscateStatsTest(FEW_PKGS, HEAVY_USE); 214 } 215 216 @Test testQueryUsageStats_ManyPkgsLightUse()217 public void testQueryUsageStats_ManyPkgsLightUse() throws IOException { 218 runQueryUsageStatsTest(MANY_PKGS, LIGHT_USE); 219 } 220 221 @Test testPutUsageStats_ManyPkgsLightUse()222 public void testPutUsageStats_ManyPkgsLightUse() throws IOException { 223 runPutUsageStatsTest(MANY_PKGS, LIGHT_USE); 224 } 225 226 @Test testObfuscateStats_ManyPkgsLightUse()227 public void testObfuscateStats_ManyPkgsLightUse() { 228 runObfuscateStatsTest(MANY_PKGS, LIGHT_USE); 229 } 230 231 @Test testDeobfuscateStats_ManyPkgsLightUse()232 public void testDeobfuscateStats_ManyPkgsLightUse() { 233 runDeobfuscateStatsTest(MANY_PKGS, LIGHT_USE); 234 } 235 236 @Test testQueryUsageStats_ManyPkgsHeavyUse()237 public void testQueryUsageStats_ManyPkgsHeavyUse() throws IOException { 238 runQueryUsageStatsTest(MANY_PKGS, HEAVY_USE); 239 } 240 241 @Test testPutUsageStats_ManyPkgsHeavyUse()242 public void testPutUsageStats_ManyPkgsHeavyUse() throws IOException { 243 runPutUsageStatsTest(MANY_PKGS, HEAVY_USE); 244 } 245 246 @Test testObfuscateStats_ManyPkgsHeavyUse()247 public void testObfuscateStats_ManyPkgsHeavyUse() { 248 runObfuscateStatsTest(MANY_PKGS, HEAVY_USE); 249 } 250 251 @Test testDeobfuscateStats_ManyPkgsHeavyUse()252 public void testDeobfuscateStats_ManyPkgsHeavyUse() { 253 runDeobfuscateStatsTest(MANY_PKGS, HEAVY_USE); 254 } 255 } 256