Loading core/java/android/provider/Settings.java +13 −0 Original line number Diff line number Diff line Loading @@ -14591,6 +14591,19 @@ public final class Settings { */ public static final String MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH = "maximum_obscuring_opacity_for_touch"; /** * LatencyTracker settings. * * The following strings are supported as keys: * <pre> * enabled (boolean) * sampling_interval (int) * </pre> * * @hide */ public static final String LATENCY_TRACKER = "latency_tracker"; } /** core/java/com/android/internal/util/LatencyTracker.java +93 −11 Original line number Diff line number Diff line Loading @@ -15,14 +15,22 @@ package com.android.internal.util; import android.content.Context; import android.database.ContentObserver; import android.net.Uri; import android.os.Build; import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; import android.provider.Settings; import android.util.EventLog; import android.util.KeyValueListParser; import android.util.Log; import android.util.SparseLongArray; import com.android.internal.logging.EventLogTags; import com.android.internal.os.BackgroundThread; import java.util.concurrent.ThreadLocalRandom; /** * Class to track various latencies in SystemUI. It then writes the latency to statsd and also Loading @@ -34,6 +42,12 @@ import com.android.internal.logging.EventLogTags; */ public class LatencyTracker { private static final String TAG = "LatencyTracker"; private static final String SETTINGS_ENABLED_KEY = "enabled"; private static final String SETTINGS_SAMPLING_INTERVAL_KEY = "sampling_interval"; /** Default to being enabled on debug builds. */ private static final boolean DEFAULT_ENABLED = Build.IS_DEBUGGABLE; /** Default to collecting data for 1/5 of all actions (randomly sampled). */ private static final int DEFAULT_SAMPLING_INTERVAL = 5; /** * Time it takes until the first frame of the notification panel to be displayed while expanding Loading Loading @@ -100,20 +114,59 @@ public class LatencyTracker { private static LatencyTracker sLatencyTracker; private final SparseLongArray mStartRtc = new SparseLongArray(); private final Context mContext; private volatile int mSamplingInterval; private volatile boolean mEnabled; public static LatencyTracker getInstance(Context context) { if (sLatencyTracker == null) { sLatencyTracker = new LatencyTracker(); synchronized (LatencyTracker.class) { if (sLatencyTracker == null) { sLatencyTracker = new LatencyTracker(context); } } } return sLatencyTracker; } public LatencyTracker(Context context) { mContext = context; mEnabled = DEFAULT_ENABLED; mSamplingInterval = DEFAULT_SAMPLING_INTERVAL; // Post initialization to the background in case we're running on the main thread. BackgroundThread.getHandler().post(this::registerSettingsObserver); BackgroundThread.getHandler().post(this::readSettings); } private void registerSettingsObserver() { Uri settingsUri = Settings.Global.getUriFor(Settings.Global.LATENCY_TRACKER); mContext.getContentResolver().registerContentObserver( settingsUri, false, new SettingsObserver(this), UserHandle.myUserId()); } private void readSettings() { KeyValueListParser parser = new KeyValueListParser(','); String settingsValue = Settings.Global.getString(mContext.getContentResolver(), Settings.Global.LATENCY_TRACKER); try { parser.setString(settingsValue); mSamplingInterval = parser.getInt(SETTINGS_SAMPLING_INTERVAL_KEY, DEFAULT_SAMPLING_INTERVAL); mEnabled = parser.getBoolean(SETTINGS_ENABLED_KEY, DEFAULT_ENABLED); } catch (IllegalArgumentException e) { Log.e(TAG, "Incorrect settings format", e); mEnabled = false; } } public static boolean isEnabled(Context ctx) { return getInstance(ctx).isEnabled(); } public boolean isEnabled() { return Build.IS_DEBUGGABLE; return mEnabled; } /** Loading Loading @@ -154,10 +207,39 @@ public class LatencyTracker { * @param action The action to end. One of the ACTION_* values. * @param duration The duration of the action in ms. */ public static void logAction(int action, int duration) { public void logAction(int action, int duration) { boolean shouldSample = ThreadLocalRandom.current().nextInt() % mSamplingInterval == 0; logActionDeprecated(action, duration, shouldSample); } /** * Logs an action that has started and ended. This needs to be called from the main thread. * * @param action The action to end. One of the ACTION_* values. * @param duration The duration of the action in ms. * @param writeToStatsLog Whether to write the measured latency to FrameworkStatsLog. */ public static void logActionDeprecated(int action, int duration, boolean writeToStatsLog) { Log.i(TAG, "action=" + action + " latency=" + duration); EventLog.writeEvent(EventLogTags.SYSUI_LATENCY, action, duration); if (writeToStatsLog) { FrameworkStatsLog.write( FrameworkStatsLog.UI_ACTION_LATENCY_REPORTED, STATSD_ACTION[action], duration); } } private static class SettingsObserver extends ContentObserver { private final LatencyTracker mThisTracker; SettingsObserver(LatencyTracker thisTracker) { super(BackgroundThread.getHandler()); mThisTracker = thisTracker; } @Override public void onChange(boolean selfChange, Uri uri, int userId) { mThisTracker.readSettings(); } } } packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,7 @@ public class SettingsBackupTest { Settings.Global.KERNEL_CPU_THREAD_READER, Settings.Global.LANG_ID_UPDATE_CONTENT_URL, Settings.Global.LANG_ID_UPDATE_METADATA_URL, Settings.Global.LATENCY_TRACKER, Settings.Global.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS, Settings.Global.LOCATION_BACKGROUND_THROTTLE_PROXIMITY_ALERT_INTERVAL_MS, Settings.Global.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST, Loading packages/SystemUI/shared/src/com/android/systemui/shared/system/LatencyTrackerCompat.java +12 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,18 @@ public class LatencyTrackerCompat { return LatencyTracker.isEnabled(context); } /** * @see LatencyTracker * @deprecated Please use {@link LatencyTrackerCompat#logToggleRecents(Context, int)} instead. */ @Deprecated public static void logToggleRecents(int duration) { LatencyTracker.logAction(LatencyTracker.ACTION_TOGGLE_RECENTS, duration); LatencyTracker.logActionDeprecated(LatencyTracker.ACTION_TOGGLE_RECENTS, duration, false); } /** @see LatencyTracker */ public static void logToggleRecents(Context context, int duration) { LatencyTracker.getInstance(context).logAction(LatencyTracker.ACTION_TOGGLE_RECENTS, duration); } } No newline at end of file Loading
core/java/android/provider/Settings.java +13 −0 Original line number Diff line number Diff line Loading @@ -14591,6 +14591,19 @@ public final class Settings { */ public static final String MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH = "maximum_obscuring_opacity_for_touch"; /** * LatencyTracker settings. * * The following strings are supported as keys: * <pre> * enabled (boolean) * sampling_interval (int) * </pre> * * @hide */ public static final String LATENCY_TRACKER = "latency_tracker"; } /**
core/java/com/android/internal/util/LatencyTracker.java +93 −11 Original line number Diff line number Diff line Loading @@ -15,14 +15,22 @@ package com.android.internal.util; import android.content.Context; import android.database.ContentObserver; import android.net.Uri; import android.os.Build; import android.os.SystemClock; import android.os.Trace; import android.os.UserHandle; import android.provider.Settings; import android.util.EventLog; import android.util.KeyValueListParser; import android.util.Log; import android.util.SparseLongArray; import com.android.internal.logging.EventLogTags; import com.android.internal.os.BackgroundThread; import java.util.concurrent.ThreadLocalRandom; /** * Class to track various latencies in SystemUI. It then writes the latency to statsd and also Loading @@ -34,6 +42,12 @@ import com.android.internal.logging.EventLogTags; */ public class LatencyTracker { private static final String TAG = "LatencyTracker"; private static final String SETTINGS_ENABLED_KEY = "enabled"; private static final String SETTINGS_SAMPLING_INTERVAL_KEY = "sampling_interval"; /** Default to being enabled on debug builds. */ private static final boolean DEFAULT_ENABLED = Build.IS_DEBUGGABLE; /** Default to collecting data for 1/5 of all actions (randomly sampled). */ private static final int DEFAULT_SAMPLING_INTERVAL = 5; /** * Time it takes until the first frame of the notification panel to be displayed while expanding Loading Loading @@ -100,20 +114,59 @@ public class LatencyTracker { private static LatencyTracker sLatencyTracker; private final SparseLongArray mStartRtc = new SparseLongArray(); private final Context mContext; private volatile int mSamplingInterval; private volatile boolean mEnabled; public static LatencyTracker getInstance(Context context) { if (sLatencyTracker == null) { sLatencyTracker = new LatencyTracker(); synchronized (LatencyTracker.class) { if (sLatencyTracker == null) { sLatencyTracker = new LatencyTracker(context); } } } return sLatencyTracker; } public LatencyTracker(Context context) { mContext = context; mEnabled = DEFAULT_ENABLED; mSamplingInterval = DEFAULT_SAMPLING_INTERVAL; // Post initialization to the background in case we're running on the main thread. BackgroundThread.getHandler().post(this::registerSettingsObserver); BackgroundThread.getHandler().post(this::readSettings); } private void registerSettingsObserver() { Uri settingsUri = Settings.Global.getUriFor(Settings.Global.LATENCY_TRACKER); mContext.getContentResolver().registerContentObserver( settingsUri, false, new SettingsObserver(this), UserHandle.myUserId()); } private void readSettings() { KeyValueListParser parser = new KeyValueListParser(','); String settingsValue = Settings.Global.getString(mContext.getContentResolver(), Settings.Global.LATENCY_TRACKER); try { parser.setString(settingsValue); mSamplingInterval = parser.getInt(SETTINGS_SAMPLING_INTERVAL_KEY, DEFAULT_SAMPLING_INTERVAL); mEnabled = parser.getBoolean(SETTINGS_ENABLED_KEY, DEFAULT_ENABLED); } catch (IllegalArgumentException e) { Log.e(TAG, "Incorrect settings format", e); mEnabled = false; } } public static boolean isEnabled(Context ctx) { return getInstance(ctx).isEnabled(); } public boolean isEnabled() { return Build.IS_DEBUGGABLE; return mEnabled; } /** Loading Loading @@ -154,10 +207,39 @@ public class LatencyTracker { * @param action The action to end. One of the ACTION_* values. * @param duration The duration of the action in ms. */ public static void logAction(int action, int duration) { public void logAction(int action, int duration) { boolean shouldSample = ThreadLocalRandom.current().nextInt() % mSamplingInterval == 0; logActionDeprecated(action, duration, shouldSample); } /** * Logs an action that has started and ended. This needs to be called from the main thread. * * @param action The action to end. One of the ACTION_* values. * @param duration The duration of the action in ms. * @param writeToStatsLog Whether to write the measured latency to FrameworkStatsLog. */ public static void logActionDeprecated(int action, int duration, boolean writeToStatsLog) { Log.i(TAG, "action=" + action + " latency=" + duration); EventLog.writeEvent(EventLogTags.SYSUI_LATENCY, action, duration); if (writeToStatsLog) { FrameworkStatsLog.write( FrameworkStatsLog.UI_ACTION_LATENCY_REPORTED, STATSD_ACTION[action], duration); } } private static class SettingsObserver extends ContentObserver { private final LatencyTracker mThisTracker; SettingsObserver(LatencyTracker thisTracker) { super(BackgroundThread.getHandler()); mThisTracker = thisTracker; } @Override public void onChange(boolean selfChange, Uri uri, int userId) { mThisTracker.readSettings(); } } }
packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +1 −0 Original line number Diff line number Diff line Loading @@ -314,6 +314,7 @@ public class SettingsBackupTest { Settings.Global.KERNEL_CPU_THREAD_READER, Settings.Global.LANG_ID_UPDATE_CONTENT_URL, Settings.Global.LANG_ID_UPDATE_METADATA_URL, Settings.Global.LATENCY_TRACKER, Settings.Global.LOCATION_BACKGROUND_THROTTLE_INTERVAL_MS, Settings.Global.LOCATION_BACKGROUND_THROTTLE_PROXIMITY_ALERT_INTERVAL_MS, Settings.Global.LOCATION_BACKGROUND_THROTTLE_PACKAGE_WHITELIST, Loading
packages/SystemUI/shared/src/com/android/systemui/shared/system/LatencyTrackerCompat.java +12 −1 Original line number Diff line number Diff line Loading @@ -28,7 +28,18 @@ public class LatencyTrackerCompat { return LatencyTracker.isEnabled(context); } /** * @see LatencyTracker * @deprecated Please use {@link LatencyTrackerCompat#logToggleRecents(Context, int)} instead. */ @Deprecated public static void logToggleRecents(int duration) { LatencyTracker.logAction(LatencyTracker.ACTION_TOGGLE_RECENTS, duration); LatencyTracker.logActionDeprecated(LatencyTracker.ACTION_TOGGLE_RECENTS, duration, false); } /** @see LatencyTracker */ public static void logToggleRecents(Context context, int duration) { LatencyTracker.getInstance(context).logAction(LatencyTracker.ACTION_TOGGLE_RECENTS, duration); } } No newline at end of file