Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 0def8a37 authored by Siim Sammul's avatar Siim Sammul Committed by Automerger Merge Worker
Browse files

Merge "Add a version of SettingsObserver to BinderCallsStats and make it...

Merge "Add a version of SettingsObserver to BinderCallsStats and make it public so it could be used to collect binder latency data from bluetooth and telephony." am: e9005875

Original change: https://android-review.googlesource.com/c/platform/frameworks/base/+/1717631

Change-Id: I86be5b0682e148b3b2af1f5635667c77d8b7c86d
parents 9de3a37a e9005875
Loading
Loading
Loading
Loading
+127 −3
Original line number Diff line number Diff line
@@ -16,17 +16,24 @@

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.KeyValueListParser;
import android.util.Pair;
import android.util.Slog;
import android.util.SparseArray;
@@ -139,15 +146,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) {
@@ -883,4 +895,116 @@ 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";
        // 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.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));
        }
    }
}
+6 −6
Original line number Diff line number Diff line
@@ -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();
    }

+3 −2
Original line number Diff line number Diff line
@@ -875,8 +875,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);
+16 −10
Original line number Diff line number Diff line
@@ -245,8 +245,13 @@ public class BinderLatencyObserverTest {
        private ArrayList<String> mWrittenAtoms;

        TestBinderLatencyObserver() {
            this(SYSTEM_SERVER);
        }

        TestBinderLatencyObserver(int processSource) {
            // Make random generator not random.
            super(new Injector() {
            super(
                    new Injector() {
                        public Random getRandomGenerator() {
                            return new Random() {
                                int mCallCount = 0;
@@ -256,7 +261,8 @@ public class BinderLatencyObserverTest {
                                }
                            };
                        }
            });
                    },
                    processSource);
            setSamplingInterval(1);
            mWrittenAtoms = new ArrayList<>();
        }
+11 −39
Original line number Diff line number Diff line
@@ -19,6 +19,14 @@ 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_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;
@@ -41,7 +49,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;

@@ -122,27 +129,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";
        // 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;
@@ -199,23 +185,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);