diff options
author | Xin Li <delphij@google.com> | 2020-08-31 21:21:38 -0700 |
---|---|---|
committer | Xin Li <delphij@google.com> | 2020-08-31 21:21:38 -0700 |
commit | 628590d7ec80e10a3fc24b1c18a1afb55cca10a8 (patch) | |
tree | 4b1c3f52d86d7fb53afbe9e9438468588fa489f8 /startop/apps/test/src/SystemServerBenchmarks.java | |
parent | b11b8ec3aec8bb42f2c07e1c5ac7942da293baa8 (diff) | |
parent | d2d3a20624d968199353ccf6ddbae6f3ac39c9af (diff) |
Merge Android R (rvc-dev-plus-aosp-without-vendor@6692709)
Bug: 166295507
Merged-In: I3d92a6de21a938f6b352ec26dc23420c0fe02b27
Change-Id: Ifdb80563ef042738778ebb8a7581a97c4e3d96e2
Diffstat (limited to 'startop/apps/test/src/SystemServerBenchmarks.java')
-rw-r--r-- | startop/apps/test/src/SystemServerBenchmarks.java | 242 |
1 files changed, 242 insertions, 0 deletions
diff --git a/startop/apps/test/src/SystemServerBenchmarks.java b/startop/apps/test/src/SystemServerBenchmarks.java new file mode 100644 index 000000000000..8114bc225c23 --- /dev/null +++ b/startop/apps/test/src/SystemServerBenchmarks.java @@ -0,0 +1,242 @@ +/* + * Copyright (C) 2019 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.startop.test; + +import android.app.Activity; +import android.app.ActivityManager; +import android.app.AppOpsManager; +import android.app.PendingIntent; +import android.content.ComponentName; +import android.content.Context; +import android.content.Intent; +import android.content.pm.ApplicationInfo; +import android.content.pm.PackageManager; +import android.content.pm.PackageManager.NameNotFoundException; +import android.net.ConnectivityManager; +import android.os.AsyncTask; +import android.os.PowerManager; +import android.os.Process; +import android.os.UserManager; + +/** + * An interface for running benchmarks and collecting results. Used so we can have both an + * interactive runner and a non-interactive runner. + */ +interface BenchmarkRunner { + void addBenchmark(CharSequence name, Runnable thunk); +} + +interface ResultListener { + /** + * Called when a benchmark result is ready + * + * @param mean The average iteration time in nanoseconds + * @param stdev The standard deviation of iteration times in nanoseconds + */ + void onResult(double mean, double stdev); +} + +class SystemServerBenchmarks { + // Time limit to run benchmarks in seconds + public static final int TIME_LIMIT = 5; + + static void initializeBenchmarks(Activity parent, BenchmarkRunner benchmarks) { + final String packageName = parent.getPackageName(); + + PackageManager pm = parent.getPackageManager(); + benchmarks.addBenchmark("getInstalledApplications", () -> { + pm.getInstalledApplications(PackageManager.MATCH_SYSTEM_ONLY); + }); + + benchmarks.addBenchmark("getInstalledPackages", () -> { + pm.getInstalledPackages(PackageManager.GET_ACTIVITIES); + }); + + benchmarks.addBenchmark("getPackageInfo", () -> { + try { + pm.getPackageInfo(packageName, 0); + } catch (NameNotFoundException e) { + throw new RuntimeException(e); + } + }); + + benchmarks.addBenchmark("getApplicationInfo", () -> { + try { + pm.getApplicationInfo(packageName, 0); + } catch (NameNotFoundException e) { + throw new RuntimeException(e); + } + }); + + try { + ApplicationInfo app = pm.getApplicationInfo(packageName, 0); + benchmarks.addBenchmark("getResourcesForApplication", () -> { + try { + pm.getResourcesForApplication(app); + } catch (NameNotFoundException e) { + throw new RuntimeException(e); + } + }); + + benchmarks.addBenchmark("getPackagesForUid", () -> { + pm.getPackagesForUid(app.uid); + }); + } catch (NameNotFoundException e) { + throw new RuntimeException(e); + } + + ComponentName component = new ComponentName(parent, parent.getClass()); + benchmarks.addBenchmark("getActivityInfo", () -> { + try { + pm.getActivityInfo(component, PackageManager.GET_META_DATA); + } catch (NameNotFoundException e) { + throw new RuntimeException(e); + } + }); + + benchmarks.addBenchmark("getLaunchIntentForPackage", () -> { + pm.getLaunchIntentForPackage(packageName); + }); + + benchmarks.addBenchmark("getPackageUid", () -> { + try { + pm.getPackageUid(packageName, 0); + } catch (NameNotFoundException e) { + throw new RuntimeException(e); + } + }); + + benchmarks.addBenchmark("checkPermission", () -> { + // Check for the first permission I could find. + pm.checkPermission("android.permission.SEND_SMS", packageName); + }); + + benchmarks.addBenchmark("checkSignatures", () -> { + // Compare with settings, since settings is on both AOSP and Master builds + pm.checkSignatures("com.android.settings", packageName); + }); + + Intent intent = new Intent(Intent.ACTION_BOOT_COMPLETED); + benchmarks.addBenchmark("queryBroadcastReceivers", () -> { + pm.queryBroadcastReceivers(intent, 0); + }); + + benchmarks.addBenchmark("hasSystemFeature", () -> { + pm.hasSystemFeature(PackageManager.FEATURE_CAMERA); + }); + + benchmarks.addBenchmark("resolveService", () -> { + pm.resolveService(intent, 0); + }); + + ActivityManager am = (ActivityManager) parent.getSystemService(Context.ACTIVITY_SERVICE); + benchmarks.addBenchmark("getRunningAppProcesses", () -> { + am.getRunningAppProcesses(); + }); + + // We use PendingIntent.getCreatorPackage, since + // getPackageIntentForSender is not public to us, but getCreatorPackage + // is just a thin wrapper around it. + PendingIntent pi = PendingIntent.getActivity(parent, 0, new Intent(), 0); + benchmarks.addBenchmark("getPackageIntentForSender", () -> { + pi.getCreatorPackage(); + }); + + PowerManager pwr = (PowerManager) parent.getSystemService(Context.POWER_SERVICE); + PowerManager.WakeLock wl = pwr.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "benchmark tag"); + benchmarks.addBenchmark("WakeLock Acquire/Release", () -> { + wl.acquire(); + wl.release(); + }); + + AppOpsManager appOps = (AppOpsManager) parent.getSystemService(Context.APP_OPS_SERVICE); + int uid = Process.myUid(); + benchmarks.addBenchmark("AppOpsService.checkOperation", () -> { + appOps.checkOp(AppOpsManager.OPSTR_READ_EXTERNAL_STORAGE, uid, packageName); + }); + + benchmarks.addBenchmark("AppOpsService.checkPackage", () -> { + appOps.checkPackage(uid, packageName); + }); + + benchmarks.addBenchmark("AppOpsService.noteOperation", () -> { + appOps.noteOp(AppOpsManager.OPSTR_READ_EXTERNAL_STORAGE, uid, packageName); + }); + + benchmarks.addBenchmark("AppOpsService.noteProxyOperation", () -> { + appOps.noteProxyOp(AppOpsManager.OPSTR_READ_EXTERNAL_STORAGE, packageName); + }); + + UserManager userManager = (UserManager) parent.getSystemService(Context.USER_SERVICE); + benchmarks.addBenchmark("isUserUnlocked", () -> { + userManager.isUserUnlocked(); + }); + + benchmarks.addBenchmark("getIntentSender", () -> { + pi.getIntentSender(); + }); + + ConnectivityManager cm = (ConnectivityManager) parent + .getSystemService(Context.CONNECTIVITY_SERVICE); + benchmarks.addBenchmark("getActiveNetworkInfo", () -> { + cm.getActiveNetworkInfo(); + }); + } + + /** + * A helper method for benchark runners to actually run the benchmark and gather stats + * + * @param thunk The code whose performance we want to measure + * @param reporter What to do with the results + */ + static void runBenchmarkInBackground(Runnable thunk, ResultListener reporter) { + new AsyncTask() { + double resultMean = 0; + double resultStdev = 0; + + @Override + protected Object doInBackground(Object... _args) { + long startTime = System.nanoTime(); + int count = 0; + + // Run benchmark + while (true) { + long elapsed = -System.nanoTime(); + thunk.run(); + elapsed += System.nanoTime(); + + count++; + double elapsedVariance = (double) elapsed - resultMean; + resultMean += elapsedVariance / count; + resultStdev += elapsedVariance * ((double) elapsed - resultMean); + + if (System.nanoTime() - startTime > TIME_LIMIT * 1e9) { + break; + } + } + resultStdev = Math.sqrt(resultStdev / (count - 1)); + + return null; + } + + @Override + protected void onPostExecute(Object _result) { + reporter.onResult(resultMean, resultStdev); + } + }.execute(new Object()); + } +} |