summaryrefslogtreecommitdiff
path: root/startop/apps/test/src/SystemServerBenchmarks.java
diff options
context:
space:
mode:
Diffstat (limited to 'startop/apps/test/src/SystemServerBenchmarks.java')
-rw-r--r--startop/apps/test/src/SystemServerBenchmarks.java245
1 files changed, 245 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..25b43f4d53f6
--- /dev/null
+++ b/startop/apps/test/src/SystemServerBenchmarks.java
@@ -0,0 +1,245 @@
+/*
+ * 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();
+
+ benchmarks.addBenchmark("Empty", () -> {
+ });
+
+ 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());
+ }
+}