summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/com/android/internal/os/BinderCallsStats.java134
-rw-r--r--core/java/com/android/internal/os/BinderLatencyObserver.java12
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java5
-rw-r--r--core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java26
-rw-r--r--services/core/java/com/android/server/BinderCallsStatsService.java52
5 files changed, 168 insertions, 61 deletions
diff --git a/core/java/com/android/internal/os/BinderCallsStats.java b/core/java/com/android/internal/os/BinderCallsStats.java
index 7ecf69b0abae..1004e17e91e6 100644
--- a/core/java/com/android/internal/os/BinderCallsStats.java
+++ b/core/java/com/android/internal/os/BinderCallsStats.java
@@ -16,18 +16,25 @@
package com.android.internal.os;
+import static com.android.internal.os.BinderLatencyProto.Dims.SYSTEM_SERVER;
+
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.Context;
+import android.database.ContentObserver;
+import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
import android.os.Looper;
import android.os.Process;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.provider.Settings;
import android.text.format.DateFormat;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.IntArray;
+import android.util.KeyValueListParser;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
@@ -157,15 +164,20 @@ public class BinderCallsStats implements BinderInternal.Observer {
return new Handler(Looper.getMainLooper());
}
- public BinderLatencyObserver getLatencyObserver() {
- return new BinderLatencyObserver(new BinderLatencyObserver.Injector());
+ /** Create a latency observer for the specified process. */
+ public BinderLatencyObserver getLatencyObserver(int processSource) {
+ return new BinderLatencyObserver(new BinderLatencyObserver.Injector(), processSource);
}
}
public BinderCallsStats(Injector injector) {
+ this(injector, SYSTEM_SERVER);
+ }
+
+ public BinderCallsStats(Injector injector, int processSource) {
this.mRandom = injector.getRandomGenerator();
this.mCallStatsObserverHandler = injector.getHandler();
- this.mLatencyObserver = injector.getLatencyObserver();
+ this.mLatencyObserver = injector.getLatencyObserver(processSource);
}
public void setDeviceState(@NonNull CachedDeviceState.Readonly deviceState) {
@@ -1074,4 +1086,120 @@ public class BinderCallsStats implements BinderInternal.Observer {
? result
: Integer.compare(a.transactionCode, b.transactionCode);
}
+
+
+ /**
+ * Settings observer for other processes (not system_server).
+ *
+ * We do not want to collect cpu data from other processes so only latency collection should be
+ * possible to enable.
+ */
+ public static class SettingsObserver extends ContentObserver {
+ // Settings for BinderCallsStats.
+ public static final String SETTINGS_ENABLED_KEY = "enabled";
+ public static final String SETTINGS_DETAILED_TRACKING_KEY = "detailed_tracking";
+ public static final String SETTINGS_UPLOAD_DATA_KEY = "upload_data";
+ public static final String SETTINGS_SAMPLING_INTERVAL_KEY = "sampling_interval";
+ public static final String SETTINGS_TRACK_SCREEN_INTERACTIVE_KEY = "track_screen_state";
+ public static final String SETTINGS_TRACK_DIRECT_CALLING_UID_KEY = "track_calling_uid";
+ public static final String SETTINGS_MAX_CALL_STATS_KEY = "max_call_stats_count";
+ public static final String SETTINGS_IGNORE_BATTERY_STATUS_KEY = "ignore_battery_status";
+ // Settings for BinderLatencyObserver.
+ public static final String SETTINGS_COLLECT_LATENCY_DATA_KEY = "collect_Latency_data";
+ public static final String SETTINGS_LATENCY_OBSERVER_SAMPLING_INTERVAL_KEY =
+ "latency_observer_sampling_interval";
+ public static final String SETTINGS_LATENCY_OBSERVER_PUSH_INTERVAL_MINUTES_KEY =
+ "latency_observer_push_interval_minutes";
+ public static final String SETTINGS_LATENCY_HISTOGRAM_BUCKET_COUNT_KEY =
+ "latency_histogram_bucket_count";
+ public static final String SETTINGS_LATENCY_HISTOGRAM_FIRST_BUCKET_SIZE_KEY =
+ "latency_histogram_first_bucket_size";
+ public static final String SETTINGS_LATENCY_HISTOGRAM_BUCKET_SCALE_FACTOR_KEY =
+ "latency_histogram_bucket_scale_factor";
+
+ private boolean mEnabled;
+ private final Uri mUri = Settings.Global.getUriFor(Settings.Global.BINDER_CALLS_STATS);
+ private final Context mContext;
+ private final KeyValueListParser mParser = new KeyValueListParser(',');
+ private final BinderCallsStats mBinderCallsStats;
+ private final int mProcessSource;
+
+ public SettingsObserver(Context context, BinderCallsStats binderCallsStats,
+ int processSource, int userHandle) {
+ super(BackgroundThread.getHandler());
+ mContext = context;
+ context.getContentResolver().registerContentObserver(mUri, false, this,
+ userHandle);
+ mBinderCallsStats = binderCallsStats;
+ mProcessSource = processSource;
+ // Always kick once to ensure that we match current state
+ onChange();
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri, int userId) {
+ if (mUri.equals(uri)) {
+ onChange();
+ }
+ }
+
+ void onChange() {
+ try {
+ mParser.setString(Settings.Global.getString(mContext.getContentResolver(),
+ Settings.Global.BINDER_CALLS_STATS));
+ } catch (IllegalArgumentException e) {
+ Slog.e(TAG, "Bad binder call stats settings", e);
+ }
+
+ // Cpu data collection should always be disabled for other processes.
+ mBinderCallsStats.setDetailedTracking(false);
+ mBinderCallsStats.setTrackScreenInteractive(false);
+ mBinderCallsStats.setTrackDirectCallerUid(false);
+
+ mBinderCallsStats.setIgnoreBatteryStatus(
+ mParser.getBoolean(SETTINGS_IGNORE_BATTERY_STATUS_KEY,
+ BinderCallsStats.DEFAULT_IGNORE_BATTERY_STATUS));
+ mBinderCallsStats.setCollectLatencyData(
+ mParser.getBoolean(SETTINGS_COLLECT_LATENCY_DATA_KEY,
+ BinderCallsStats.DEFAULT_COLLECT_LATENCY_DATA));
+
+ // Binder latency observer settings.
+ configureLatencyObserver(mParser, mBinderCallsStats.getLatencyObserver());
+
+ final boolean enabled =
+ mParser.getBoolean(SETTINGS_ENABLED_KEY, BinderCallsStats.ENABLED_DEFAULT);
+ if (mEnabled != enabled) {
+ if (enabled) {
+ Binder.setObserver(mBinderCallsStats);
+ } else {
+ Binder.setObserver(null);
+ }
+ mEnabled = enabled;
+ mBinderCallsStats.reset();
+ mBinderCallsStats.setAddDebugEntries(enabled);
+ mBinderCallsStats.getLatencyObserver().reset();
+ }
+ }
+
+ /** Configures the binder latency observer related settings. */
+ public static void configureLatencyObserver(
+ KeyValueListParser mParser, BinderLatencyObserver binderLatencyObserver) {
+ binderLatencyObserver.setSamplingInterval(mParser.getInt(
+ SETTINGS_LATENCY_OBSERVER_SAMPLING_INTERVAL_KEY,
+ BinderLatencyObserver.PERIODIC_SAMPLING_INTERVAL_DEFAULT));
+ binderLatencyObserver.setHistogramBucketsParams(
+ mParser.getInt(
+ SETTINGS_LATENCY_HISTOGRAM_BUCKET_COUNT_KEY,
+ BinderLatencyObserver.BUCKET_COUNT_DEFAULT),
+ mParser.getInt(
+ SETTINGS_LATENCY_HISTOGRAM_FIRST_BUCKET_SIZE_KEY,
+ BinderLatencyObserver.FIRST_BUCKET_SIZE_DEFAULT),
+ mParser.getFloat(
+ SETTINGS_LATENCY_HISTOGRAM_BUCKET_SCALE_FACTOR_KEY,
+ BinderLatencyObserver.BUCKET_SCALE_FACTOR_DEFAULT));
+ binderLatencyObserver.setPushInterval(mParser.getInt(
+ SETTINGS_LATENCY_OBSERVER_PUSH_INTERVAL_MINUTES_KEY,
+ BinderLatencyObserver.STATSD_PUSH_INTERVAL_MINUTES_DEFAULT));
+ }
+ }
}
diff --git a/core/java/com/android/internal/os/BinderLatencyObserver.java b/core/java/com/android/internal/os/BinderLatencyObserver.java
index 007980150237..5fa96bd9a152 100644
--- a/core/java/com/android/internal/os/BinderLatencyObserver.java
+++ b/core/java/com/android/internal/os/BinderLatencyObserver.java
@@ -16,8 +16,6 @@
package com.android.internal.os;
-import static com.android.internal.os.BinderLatencyProto.Dims.SYSTEM_SERVER;
-
import android.annotation.Nullable;
import android.os.Binder;
import android.os.Handler;
@@ -68,9 +66,10 @@ public class BinderLatencyObserver {
private int mStatsdPushIntervalMinutes = STATSD_PUSH_INTERVAL_MINUTES_DEFAULT;
private final Random mRandom;
- private BinderLatencyBuckets mLatencyBuckets;
-
private final Handler mLatencyObserverHandler;
+ private final int mProcessSource;
+
+ private BinderLatencyBuckets mLatencyBuckets;
private Runnable mLatencyObserverRunnable = new Runnable() {
@Override
@@ -134,7 +133,7 @@ public class BinderLatencyObserver {
// Write the dims.
long dimsToken = proto.start(ApiStats.DIMS);
- proto.write(Dims.PROCESS_SOURCE, SYSTEM_SERVER);
+ proto.write(Dims.PROCESS_SOURCE, mProcessSource);
proto.write(Dims.SERVICE_CLASS_NAME, dims.getBinderClass().getName());
proto.write(Dims.SERVICE_METHOD_NAME, transactionName);
proto.end(dimsToken);
@@ -180,11 +179,12 @@ public class BinderLatencyObserver {
}
}
- public BinderLatencyObserver(Injector injector) {
+ public BinderLatencyObserver(Injector injector, int processSource) {
mRandom = injector.getRandomGenerator();
mLatencyObserverHandler = injector.getHandler();
mLatencyBuckets = new BinderLatencyBuckets(
mBucketCount, mFirstBucketSize, mBucketScaleFactor);
+ mProcessSource = processSource;
noteLatencyDelayed();
}
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
index 8c5e0fc8e658..e2e672ea6f68 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderCallsStatsTest.java
@@ -984,8 +984,9 @@ public class BinderCallsStatsTest {
return mHandler;
}
- public BinderLatencyObserver getLatencyObserver() {
- return new BinderLatencyObserverTest.TestBinderLatencyObserver();
+ @Override
+ public BinderLatencyObserver getLatencyObserver(int processSource) {
+ return new BinderLatencyObserverTest.TestBinderLatencyObserver(processSource);
}
});
setSamplingInterval(1);
diff --git a/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java b/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java
index bf87683593e7..4157f5e72871 100644
--- a/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java
+++ b/core/tests/coretests/src/com/android/internal/os/BinderLatencyObserverTest.java
@@ -245,18 +245,24 @@ public class BinderLatencyObserverTest {
private ArrayList<String> mWrittenAtoms;
TestBinderLatencyObserver() {
- // Make random generator not random.
- super(new Injector() {
- public Random getRandomGenerator() {
- return new Random() {
- int mCallCount = 0;
+ this(SYSTEM_SERVER);
+ }
- public int nextInt() {
- return mCallCount++;
+ TestBinderLatencyObserver(int processSource) {
+ // Make random generator not random.
+ super(
+ new Injector() {
+ public Random getRandomGenerator() {
+ return new Random() {
+ int mCallCount = 0;
+
+ public int nextInt() {
+ return mCallCount++;
+ }
+ };
}
- };
- }
- });
+ },
+ processSource);
setSamplingInterval(1);
mWrittenAtoms = new ArrayList<>();
}
diff --git a/services/core/java/com/android/server/BinderCallsStatsService.java b/services/core/java/com/android/server/BinderCallsStatsService.java
index 78610a2857bd..0bd331b737c6 100644
--- a/services/core/java/com/android/server/BinderCallsStatsService.java
+++ b/services/core/java/com/android/server/BinderCallsStatsService.java
@@ -19,6 +19,15 @@ package com.android.server;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
+import static com.android.internal.os.BinderCallsStats.SettingsObserver.SETTINGS_COLLECT_LATENCY_DATA_KEY;
+import static com.android.internal.os.BinderCallsStats.SettingsObserver.SETTINGS_DETAILED_TRACKING_KEY;
+import static com.android.internal.os.BinderCallsStats.SettingsObserver.SETTINGS_ENABLED_KEY;
+import static com.android.internal.os.BinderCallsStats.SettingsObserver.SETTINGS_IGNORE_BATTERY_STATUS_KEY;
+import static com.android.internal.os.BinderCallsStats.SettingsObserver.SETTINGS_MAX_CALL_STATS_KEY;
+import static com.android.internal.os.BinderCallsStats.SettingsObserver.SETTINGS_SAMPLING_INTERVAL_KEY;
+import static com.android.internal.os.BinderCallsStats.SettingsObserver.SETTINGS_TRACK_DIRECT_CALLING_UID_KEY;
+import static com.android.internal.os.BinderCallsStats.SettingsObserver.SETTINGS_TRACK_SCREEN_INTERACTIVE_KEY;
+
import android.app.ActivityThread;
import android.content.Context;
import android.content.pm.PackageInfo;
@@ -43,7 +52,6 @@ import com.android.internal.os.AppIdToPackageMap;
import com.android.internal.os.BackgroundThread;
import com.android.internal.os.BinderCallsStats;
import com.android.internal.os.BinderInternal;
-import com.android.internal.os.BinderLatencyObserver;
import com.android.internal.os.CachedDeviceState;
import com.android.internal.util.DumpUtils;
@@ -125,28 +133,6 @@ public class BinderCallsStatsService extends Binder {
/** Listens for flag changes. */
private static class SettingsObserver extends ContentObserver {
- // Settings for BinderCallsStats.
- private static final String SETTINGS_ENABLED_KEY = "enabled";
- private static final String SETTINGS_DETAILED_TRACKING_KEY = "detailed_tracking";
- private static final String SETTINGS_UPLOAD_DATA_KEY = "upload_data";
- private static final String SETTINGS_SAMPLING_INTERVAL_KEY = "sampling_interval";
- private static final String SETTINGS_TRACK_SCREEN_INTERACTIVE_KEY = "track_screen_state";
- private static final String SETTINGS_TRACK_DIRECT_CALLING_UID_KEY = "track_calling_uid";
- private static final String SETTINGS_MAX_CALL_STATS_KEY = "max_call_stats_count";
- private static final String SETTINGS_IGNORE_BATTERY_STATUS_KEY = "ignore_battery_status";
- // Settings for BinderLatencyObserver.
- private static final String SETTINGS_COLLECT_LATENCY_DATA_KEY = "collect_Latency_data";
- private static final String SETTINGS_LATENCY_OBSERVER_SAMPLING_INTERVAL_KEY =
- "latency_observer_sampling_interval";
- private static final String SETTINGS_LATENCY_OBSERVER_PUSH_INTERVAL_MINUTES_KEY =
- "latency_observer_push_interval_minutes";
- private static final String SETTINGS_LATENCY_HISTOGRAM_BUCKET_COUNT_KEY =
- "latency_histogram_bucket_count";
- private static final String SETTINGS_LATENCY_HISTOGRAM_FIRST_BUCKET_SIZE_KEY =
- "latency_histogram_first_bucket_size";
- private static final String SETTINGS_LATENCY_HISTOGRAM_BUCKET_SCALE_FACTOR_KEY =
- "latency_histogram_bucket_scale_factor";
-
private boolean mEnabled;
private final Uri mUri = Settings.Global.getUriFor(Settings.Global.BINDER_CALLS_STATS);
private final Context mContext;
@@ -206,23 +192,9 @@ public class BinderCallsStatsService extends Binder {
mParser.getBoolean(SETTINGS_COLLECT_LATENCY_DATA_KEY,
BinderCallsStats.DEFAULT_COLLECT_LATENCY_DATA));
// Binder latency observer settings.
- BinderLatencyObserver binderLatencyObserver = mBinderCallsStats.getLatencyObserver();
- binderLatencyObserver.setSamplingInterval(mParser.getInt(
- SETTINGS_LATENCY_OBSERVER_SAMPLING_INTERVAL_KEY,
- BinderLatencyObserver.PERIODIC_SAMPLING_INTERVAL_DEFAULT));
- binderLatencyObserver.setHistogramBucketsParams(
- mParser.getInt(
- SETTINGS_LATENCY_HISTOGRAM_BUCKET_COUNT_KEY,
- BinderLatencyObserver.BUCKET_COUNT_DEFAULT),
- mParser.getInt(
- SETTINGS_LATENCY_HISTOGRAM_FIRST_BUCKET_SIZE_KEY,
- BinderLatencyObserver.FIRST_BUCKET_SIZE_DEFAULT),
- mParser.getFloat(
- SETTINGS_LATENCY_HISTOGRAM_BUCKET_SCALE_FACTOR_KEY,
- BinderLatencyObserver.BUCKET_SCALE_FACTOR_DEFAULT));
- binderLatencyObserver.setPushInterval(mParser.getInt(
- SETTINGS_LATENCY_OBSERVER_PUSH_INTERVAL_MINUTES_KEY,
- BinderLatencyObserver.STATSD_PUSH_INTERVAL_MINUTES_DEFAULT));
+ BinderCallsStats.SettingsObserver.configureLatencyObserver(
+ mParser,
+ mBinderCallsStats.getLatencyObserver());
final boolean enabled =
mParser.getBoolean(SETTINGS_ENABLED_KEY, BinderCallsStats.ENABLED_DEFAULT);