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 boolean 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 return true; 72 } 73 }; 74 75 76 @Rule 77 public PerfManualStatusReporter mPerfManualStatusReporter = new PerfManualStatusReporter(); 78 79 @BeforeClass setUpOnce()80 public static void setUpOnce() { 81 sContext = InstrumentationRegistry.getTargetContext(); 82 mTestDir = new File(sContext.getFilesDir(), "UsageStatsDatabasePerfTest"); 83 sUsageStatsDatabase = new UsageStatsDatabase(mTestDir); 84 sUsageStatsDatabase.readMappingsLocked(); 85 sUsageStatsDatabase.init(1); 86 } 87 populateIntervalStats(IntervalStats intervalStats, int packageCount, int eventsPerPackage)88 private static void populateIntervalStats(IntervalStats intervalStats, int packageCount, 89 int eventsPerPackage) { 90 for (int pkg = 0; pkg < packageCount; pkg++) { 91 UsageEvents.Event event = new UsageEvents.Event(); 92 event.mPackage = "fake.package.name" + pkg; 93 event.mClass = event.mPackage + ".class1"; 94 event.mTimeStamp = 1; 95 event.mEventType = UsageEvents.Event.ACTIVITY_RESUMED; 96 for (int evt = 0; evt < eventsPerPackage; evt++) { 97 intervalStats.events.insert(event); 98 intervalStats.update(event.mPackage, event.mClass, event.mTimeStamp, 99 event.mEventType, 1); 100 } 101 } 102 } 103 clearUsageStatsFiles()104 private static void clearUsageStatsFiles() { 105 File[] intervalDirs = mTestDir.listFiles(); 106 for (File intervalDir : intervalDirs) { 107 if (intervalDir.isDirectory()) { 108 File[] usageFiles = intervalDir.listFiles(); 109 for (File f : usageFiles) { 110 f.delete(); 111 } 112 } 113 } 114 } 115 runQueryUsageStatsTest(int packageCount, int eventsPerPackage)116 private void runQueryUsageStatsTest(int packageCount, int eventsPerPackage) throws IOException { 117 final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState(); 118 IntervalStats intervalStats = new IntervalStats(); 119 populateIntervalStats(intervalStats, packageCount, eventsPerPackage); 120 sUsageStatsDatabase.putUsageStats(0, intervalStats); 121 long elapsedTimeNs = 0; 122 while (benchmarkState.keepRunning(elapsedTimeNs)) { 123 final long startTime = SystemClock.elapsedRealtimeNanos(); 124 List<UsageEvents.Event> temp = sUsageStatsDatabase.queryUsageStats( 125 UsageStatsManager.INTERVAL_DAILY, 0, 2, sUsageStatsCombiner); 126 final long endTime = SystemClock.elapsedRealtimeNanos(); 127 elapsedTimeNs = endTime - startTime; 128 assertEquals(packageCount * eventsPerPackage, temp.size()); 129 } 130 } 131 runPutUsageStatsTest(int packageCount, int eventsPerPackage)132 private void runPutUsageStatsTest(int packageCount, int eventsPerPackage) throws IOException { 133 final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState(); 134 IntervalStats intervalStats = new IntervalStats(); 135 populateIntervalStats(intervalStats, packageCount, eventsPerPackage); 136 long elapsedTimeNs = 0; 137 while (benchmarkState.keepRunning(elapsedTimeNs)) { 138 final long startTime = SystemClock.elapsedRealtimeNanos(); 139 sUsageStatsDatabase.putUsageStats(0, intervalStats); 140 final long endTime = SystemClock.elapsedRealtimeNanos(); 141 elapsedTimeNs = endTime - startTime; 142 clearUsageStatsFiles(); 143 } 144 } 145 runObfuscateStatsTest(int packageCount, int eventsPerPackage)146 private void runObfuscateStatsTest(int packageCount, int eventsPerPackage) { 147 final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState(); 148 IntervalStats intervalStats = new IntervalStats(); 149 populateIntervalStats(intervalStats, packageCount, eventsPerPackage); 150 long elapsedTimeNs = 0; 151 while (benchmarkState.keepRunning(elapsedTimeNs)) { 152 final long startTime = SystemClock.elapsedRealtimeNanos(); 153 PackagesTokenData packagesTokenData = new PackagesTokenData(); 154 intervalStats.obfuscateData(packagesTokenData); 155 final long endTime = SystemClock.elapsedRealtimeNanos(); 156 elapsedTimeNs = endTime - startTime; 157 clearUsageStatsFiles(); 158 } 159 } 160 runDeobfuscateStatsTest(int packageCount, int eventsPerPackage)161 private void runDeobfuscateStatsTest(int packageCount, int eventsPerPackage) { 162 final ManualBenchmarkState benchmarkState = mPerfManualStatusReporter.getBenchmarkState(); 163 IntervalStats intervalStats = new IntervalStats(); 164 populateIntervalStats(intervalStats, packageCount, eventsPerPackage); 165 long elapsedTimeNs = 0; 166 while (benchmarkState.keepRunning(elapsedTimeNs)) { 167 PackagesTokenData packagesTokenData = new PackagesTokenData(); 168 intervalStats.obfuscateData(packagesTokenData); 169 final long startTime = SystemClock.elapsedRealtimeNanos(); 170 intervalStats.deobfuscateData(packagesTokenData); 171 final long endTime = SystemClock.elapsedRealtimeNanos(); 172 elapsedTimeNs = endTime - startTime; 173 clearUsageStatsFiles(); 174 } 175 } 176 177 @Test testQueryUsageStats_FewPkgsLightUse()178 public void testQueryUsageStats_FewPkgsLightUse() throws IOException { 179 runQueryUsageStatsTest(FEW_PKGS, LIGHT_USE); 180 } 181 182 @Test testPutUsageStats_FewPkgsLightUse()183 public void testPutUsageStats_FewPkgsLightUse() throws IOException { 184 runPutUsageStatsTest(FEW_PKGS, LIGHT_USE); 185 } 186 187 @Test testObfuscateStats_FewPkgsLightUse()188 public void testObfuscateStats_FewPkgsLightUse() { 189 runObfuscateStatsTest(FEW_PKGS, LIGHT_USE); 190 } 191 192 @Test testDeobfuscateStats_FewPkgsLightUse()193 public void testDeobfuscateStats_FewPkgsLightUse() { 194 runDeobfuscateStatsTest(FEW_PKGS, LIGHT_USE); 195 } 196 197 @Test testQueryUsageStats_FewPkgsHeavyUse()198 public void testQueryUsageStats_FewPkgsHeavyUse() throws IOException { 199 runQueryUsageStatsTest(FEW_PKGS, HEAVY_USE); 200 } 201 202 @Test testPutUsageStats_FewPkgsHeavyUse()203 public void testPutUsageStats_FewPkgsHeavyUse() throws IOException { 204 runPutUsageStatsTest(FEW_PKGS, HEAVY_USE); 205 } 206 207 @Test testObfuscateStats_FewPkgsHeavyUse()208 public void testObfuscateStats_FewPkgsHeavyUse() { 209 runObfuscateStatsTest(FEW_PKGS, HEAVY_USE); 210 } 211 212 @Test testDeobfuscateStats_FewPkgsHeavyUse()213 public void testDeobfuscateStats_FewPkgsHeavyUse() { 214 runDeobfuscateStatsTest(FEW_PKGS, HEAVY_USE); 215 } 216 217 @Test testQueryUsageStats_ManyPkgsLightUse()218 public void testQueryUsageStats_ManyPkgsLightUse() throws IOException { 219 runQueryUsageStatsTest(MANY_PKGS, LIGHT_USE); 220 } 221 222 @Test testPutUsageStats_ManyPkgsLightUse()223 public void testPutUsageStats_ManyPkgsLightUse() throws IOException { 224 runPutUsageStatsTest(MANY_PKGS, LIGHT_USE); 225 } 226 227 @Test testObfuscateStats_ManyPkgsLightUse()228 public void testObfuscateStats_ManyPkgsLightUse() { 229 runObfuscateStatsTest(MANY_PKGS, LIGHT_USE); 230 } 231 232 @Test testDeobfuscateStats_ManyPkgsLightUse()233 public void testDeobfuscateStats_ManyPkgsLightUse() { 234 runDeobfuscateStatsTest(MANY_PKGS, LIGHT_USE); 235 } 236 237 @Test testQueryUsageStats_ManyPkgsHeavyUse()238 public void testQueryUsageStats_ManyPkgsHeavyUse() throws IOException { 239 runQueryUsageStatsTest(MANY_PKGS, HEAVY_USE); 240 } 241 242 @Test testPutUsageStats_ManyPkgsHeavyUse()243 public void testPutUsageStats_ManyPkgsHeavyUse() throws IOException { 244 runPutUsageStatsTest(MANY_PKGS, HEAVY_USE); 245 } 246 247 @Test testObfuscateStats_ManyPkgsHeavyUse()248 public void testObfuscateStats_ManyPkgsHeavyUse() { 249 runObfuscateStatsTest(MANY_PKGS, HEAVY_USE); 250 } 251 252 @Test testDeobfuscateStats_ManyPkgsHeavyUse()253 public void testDeobfuscateStats_ManyPkgsHeavyUse() { 254 runDeobfuscateStatsTest(MANY_PKGS, HEAVY_USE); 255 } 256 } 257