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

Commit f79f9588 authored by Xiang Wang's avatar Xiang Wang Committed by Android (Google) Code Review
Browse files

Merge "Add logging for V thermal API metrics" into main

parents a9537e18 6a062f4f
Loading
Loading
Loading
Loading
+11 −0
Original line number Diff line number Diff line
@@ -45,6 +45,17 @@
        {"include-filter": "com.android.server.power"},
        {"exclude-annotation": "org.junit.Ignore"}
      ]
    },
    {
      "name": "CtsStatsdAtomHostTestCases",
      "options": [
        {"exclude-annotation": "androidx.test.filters.FlakyTest"},
        {"exclude-annotation": "org.junit.Ignore"},
        {"include-filter": "android.cts.statsdatom.powermanager"}
      ],
      "file_patterns": [
        "(/|^)ThermalManagerService.java"
      ]
    }
  ]
}
+105 −1
Original line number Diff line number Diff line
@@ -16,8 +16,17 @@

package com.android.server.power;

import static com.android.internal.util.ConcurrentUtils.DIRECT_EXECUTOR;
import static com.android.internal.util.FrameworkStatsLog.THERMAL_HEADROOM_CALLED__API_STATUS__NO_TEMPERATURE_THRESHOLD;
import static com.android.internal.util.FrameworkStatsLog.THERMAL_HEADROOM_THRESHOLDS_CALLED__API_STATUS__FEATURE_NOT_SUPPORTED;
import static com.android.internal.util.FrameworkStatsLog.THERMAL_HEADROOM_THRESHOLDS_CALLED__API_STATUS__HAL_NOT_READY;
import static com.android.internal.util.FrameworkStatsLog.THERMAL_HEADROOM_THRESHOLDS_CALLED__API_STATUS__SUCCESS;
import static com.android.internal.util.FrameworkStatsLog.THERMAL_STATUS_CALLED__API_STATUS__HAL_NOT_READY;
import static com.android.internal.util.FrameworkStatsLog.THERMAL_STATUS_CALLED__API_STATUS__SUCCESS;

import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.StatsManager;
import android.content.Context;
import android.hardware.thermal.IThermal;
import android.hardware.thermal.IThermalChangedCallback;
@@ -48,11 +57,13 @@ import android.os.Temperature;
import android.util.ArrayMap;
import android.util.EventLog;
import android.util.Slog;
import android.util.StatsEvent;

import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.BackgroundThread;
import com.android.internal.util.DumpUtils;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.EventLogTags;
import com.android.server.FgThread;
import com.android.server.SystemService;
@@ -122,6 +133,8 @@ public class ThermalManagerService extends SystemService {
    @VisibleForTesting
    final TemperatureWatcher mTemperatureWatcher = new TemperatureWatcher();

    private final Context mContext;

    public ThermalManagerService(Context context) {
        this(context, null);
    }
@@ -129,6 +142,7 @@ public class ThermalManagerService extends SystemService {
    @VisibleForTesting
    ThermalManagerService(Context context, @Nullable ThermalHalWrapper halWrapper) {
        super(context);
        mContext = context;
        mHalWrapper = halWrapper;
        if (halWrapper != null) {
            halWrapper.setCallback(this::onTemperatureChangedCallback);
@@ -146,6 +160,9 @@ public class ThermalManagerService extends SystemService {
        if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
            onActivityManagerReady();
        }
        if (phase == SystemService.PHASE_BOOT_COMPLETED) {
            registerStatsCallbacks();
        }
    }

    private void onActivityManagerReady() {
@@ -326,6 +343,31 @@ public class ThermalManagerService extends SystemService {
        }
    }

    private void registerStatsCallbacks() {
        final StatsManager statsManager = mContext.getSystemService(StatsManager.class);
        if (statsManager != null) {
            statsManager.setPullAtomCallback(
                    FrameworkStatsLog.THERMAL_HEADROOM_THRESHOLDS,
                    null, // use default PullAtomMetadata values
                    DIRECT_EXECUTOR,
                    this::onPullAtom);
        }
    }

    private int onPullAtom(int atomTag, @NonNull List<StatsEvent> data) {
        if (atomTag == FrameworkStatsLog.THERMAL_HEADROOM_THRESHOLDS) {
            final float[] thresholds;
            synchronized (mTemperatureWatcher.mSamples) {
                thresholds = Arrays.copyOf(mTemperatureWatcher.mHeadroomThresholds,
                        mTemperatureWatcher.mHeadroomThresholds.length);
            }
            data.add(
                    FrameworkStatsLog.buildStatsEvent(FrameworkStatsLog.THERMAL_HEADROOM_THRESHOLDS,
                            thresholds));
        }
        return android.app.StatsManager.PULL_SUCCESS;
    }

    @VisibleForTesting
    final IThermalService.Stub mService = new IThermalService.Stub() {
        @Override
@@ -449,6 +491,12 @@ public class ThermalManagerService extends SystemService {
            synchronized (mLock) {
                final long token = Binder.clearCallingIdentity();
                try {
                    FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_STATUS_CALLED,
                            Binder.getCallingUid(),
                            mHalReady.get()
                                    ? THERMAL_STATUS_CALLED__API_STATUS__SUCCESS
                                    : THERMAL_STATUS_CALLED__API_STATUS__HAL_NOT_READY,
                            thermalSeverityToStatsdStatus(mStatus));
                    return mStatus;
                } finally {
                    Binder.restoreCallingIdentity(token);
@@ -493,6 +541,9 @@ public class ThermalManagerService extends SystemService {
        @Override
        public float getThermalHeadroom(int forecastSeconds) {
            if (!mHalReady.get()) {
                FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_HEADROOM_CALLED, getCallingUid(),
                            FrameworkStatsLog.THERMAL_HEADROOM_CALLED__API_STATUS__HAL_NOT_READY,
                            Float.NaN);
                return Float.NaN;
            }

@@ -500,6 +551,9 @@ public class ThermalManagerService extends SystemService {
                if (DEBUG) {
                    Slog.d(TAG, "Invalid forecastSeconds: " + forecastSeconds);
                }
                FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_HEADROOM_CALLED, getCallingUid(),
                            FrameworkStatsLog.THERMAL_HEADROOM_CALLED__API_STATUS__INVALID_ARGUMENT,
                            Float.NaN);
                return Float.NaN;
            }

@@ -509,12 +563,21 @@ public class ThermalManagerService extends SystemService {
        @Override
        public float[] getThermalHeadroomThresholds() {
            if (!mHalReady.get()) {
                FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_HEADROOM_THRESHOLDS_CALLED,
                        Binder.getCallingUid(),
                        THERMAL_HEADROOM_THRESHOLDS_CALLED__API_STATUS__HAL_NOT_READY);
                throw new IllegalStateException("Thermal HAL connection is not initialized");
            }
            if (!Flags.allowThermalHeadroomThresholds()) {
                FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_HEADROOM_THRESHOLDS_CALLED,
                        Binder.getCallingUid(),
                        THERMAL_HEADROOM_THRESHOLDS_CALLED__API_STATUS__FEATURE_NOT_SUPPORTED);
                throw new UnsupportedOperationException("Thermal headroom thresholds not enabled");
            }
            synchronized (mTemperatureWatcher.mSamples) {
                FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_HEADROOM_THRESHOLDS_CALLED,
                        Binder.getCallingUid(),
                        THERMAL_HEADROOM_THRESHOLDS_CALLED__API_STATUS__SUCCESS);
                return Arrays.copyOf(mTemperatureWatcher.mHeadroomThresholds,
                        mTemperatureWatcher.mHeadroomThresholds.length);
            }
@@ -544,6 +607,27 @@ public class ThermalManagerService extends SystemService {

    };

    private static int thermalSeverityToStatsdStatus(int severity) {
        switch (severity) {
            case PowerManager.THERMAL_STATUS_NONE:
                return FrameworkStatsLog.THERMAL_STATUS_CALLED__STATUS__NONE;
            case PowerManager.THERMAL_STATUS_LIGHT:
                return FrameworkStatsLog.THERMAL_STATUS_CALLED__STATUS__LIGHT;
            case PowerManager.THERMAL_STATUS_MODERATE:
                return FrameworkStatsLog.THERMAL_STATUS_CALLED__STATUS__MODERATE;
            case PowerManager.THERMAL_STATUS_SEVERE:
                return FrameworkStatsLog.THERMAL_STATUS_CALLED__STATUS__SEVERE;
            case PowerManager.THERMAL_STATUS_CRITICAL:
                return FrameworkStatsLog.THERMAL_STATUS_CALLED__STATUS__CRITICAL;
            case PowerManager.THERMAL_STATUS_EMERGENCY:
                return FrameworkStatsLog.THERMAL_STATUS_CALLED__STATUS__EMERGENCY;
            case PowerManager.THERMAL_STATUS_SHUTDOWN:
                return FrameworkStatsLog.THERMAL_STATUS_CALLED__STATUS__SHUTDOWN;
            default:
                return FrameworkStatsLog.THERMAL_STATUS_CALLED__STATUS__NONE;
        }
    }

    private static void dumpItemsLocked(PrintWriter pw, String prefix,
            Collection<?> items) {
        for (Iterator iterator = items.iterator(); iterator.hasNext();) {
@@ -1626,6 +1710,10 @@ public class ThermalManagerService extends SystemService {
                // to sample, return early
                if (mSamples.isEmpty()) {
                    Slog.e(TAG, "No temperature samples found");
                    FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_HEADROOM_CALLED,
                            Binder.getCallingUid(),
                            FrameworkStatsLog.THERMAL_HEADROOM_CALLED__API_STATUS__NO_TEMPERATURE,
                            Float.NaN);
                    return Float.NaN;
                }

@@ -1633,16 +1721,22 @@ public class ThermalManagerService extends SystemService {
                // so return early
                if (mSevereThresholds.isEmpty()) {
                    Slog.e(TAG, "No temperature thresholds found");
                    FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_HEADROOM_CALLED,
                            Binder.getCallingUid(),
                            THERMAL_HEADROOM_CALLED__API_STATUS__NO_TEMPERATURE_THRESHOLD,
                            Float.NaN);
                    return Float.NaN;
                }

                float maxNormalized = Float.NaN;
                int noThresholdSampleCount = 0;
                for (Map.Entry<String, ArrayList<Sample>> entry : mSamples.entrySet()) {
                    String name = entry.getKey();
                    ArrayList<Sample> samples = entry.getValue();

                    Float threshold = mSevereThresholds.get(name);
                    if (threshold == null) {
                        noThresholdSampleCount++;
                        Slog.e(TAG, "No threshold found for " + name);
                        continue;
                    }
@@ -1665,7 +1759,17 @@ public class ThermalManagerService extends SystemService {
                        maxNormalized = normalized;
                    }
                }

                if (noThresholdSampleCount == mSamples.size()) {
                    FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_HEADROOM_CALLED,
                            Binder.getCallingUid(),
                            THERMAL_HEADROOM_CALLED__API_STATUS__NO_TEMPERATURE_THRESHOLD,
                            Float.NaN);
                } else {
                    FrameworkStatsLog.write(FrameworkStatsLog.THERMAL_HEADROOM_CALLED,
                            Binder.getCallingUid(),
                            FrameworkStatsLog.THERMAL_HEADROOM_CALLED__API_STATUS__SUCCESS,
                            maxNormalized);
                }
                return maxNormalized;
            }
        }