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

Commit 9801ae61 authored by Xiang Wang's avatar Xiang Wang
Browse files

Address API review feedback

* Sync the headroom explanation between NDK and SDK
* Make the calculation window min max values public
* Change params to be immutable and add builder
* Add comment on how to use the APIs and the binder call warning
* Add new API getMaxCpuHeadroomTidsSize to query max TID count

Bug: 384056153
Bug: 346604998
Flag: android.os.cpu_gpu_headrooms
Test: atest HintManagerServiceTest
Change-Id: I8aff28a0b281e2948462924875017f9273440022
parent 98ab6d9d
Loading
Loading
Loading
Loading
+26 −9
Original line number Diff line number Diff line
@@ -33623,16 +33623,23 @@ package android.os {
  }
  @FlaggedApi("android.os.cpu_gpu_headrooms") public final class CpuHeadroomParams {
    ctor public CpuHeadroomParams();
    method public int getCalculationType();
    method @IntRange(from=0x32, to=0x2710) public long getCalculationWindowMillis();
    method public void setCalculationType(int);
    method public void setCalculationWindowMillis(@IntRange(from=0x32, to=0x2710) int);
    method public void setTids(@NonNull int...);
    method public long getCalculationWindowMillis();
    method @NonNull public int[] getTids();
    method @NonNull public android.os.CpuHeadroomParams.Builder toBuilder();
    field public static final int CPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1; // 0x1
    field public static final int CPU_HEADROOM_CALCULATION_TYPE_MIN = 0; // 0x0
  }
  public static final class CpuHeadroomParams.Builder {
    ctor public CpuHeadroomParams.Builder();
    ctor public CpuHeadroomParams.Builder(@NonNull android.os.CpuHeadroomParams);
    method @NonNull public android.os.CpuHeadroomParams build();
    method @NonNull public android.os.CpuHeadroomParams.Builder setCalculationType(int);
    method @NonNull public android.os.CpuHeadroomParams.Builder setCalculationWindowMillis(@IntRange(from=1) int);
    method @NonNull public android.os.CpuHeadroomParams.Builder setTids(@NonNull int...);
  }
  public final class CpuUsageInfo implements android.os.Parcelable {
    method public int describeContents();
    method public long getActive();
@@ -33881,13 +33888,20 @@ package android.os {
  }
  @FlaggedApi("android.os.cpu_gpu_headrooms") public final class GpuHeadroomParams {
    ctor public GpuHeadroomParams();
    method public int getCalculationType();
    method @IntRange(from=0x32, to=0x2710) public int getCalculationWindowMillis();
    method public void setCalculationType(int);
    method public void setCalculationWindowMillis(@IntRange(from=0x32, to=0x2710) int);
    method public int getCalculationWindowMillis();
    field public static final int GPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1; // 0x1
    field public static final int GPU_HEADROOM_CALCULATION_TYPE_MIN = 0; // 0x0
    field public static final int GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX = 10000; // 0x2710
    field public static final int GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN = 50; // 0x32
  }
  public static final class GpuHeadroomParams.Builder {
    ctor public GpuHeadroomParams.Builder();
    ctor public GpuHeadroomParams.Builder(@NonNull android.os.GpuHeadroomParams);
    method @NonNull public android.os.GpuHeadroomParams build();
    method @NonNull public android.os.GpuHeadroomParams.Builder setCalculationType(int);
    method @NonNull public android.os.GpuHeadroomParams.Builder setCalculationWindowMillis(@IntRange(from=1) int);
  }
  public class Handler {
@@ -35153,9 +35167,12 @@ package android.os.health {
  public class SystemHealthManager {
    method @FlaggedApi("android.os.cpu_gpu_headrooms") @FloatRange(from=0.0f, to=100.0f) public float getCpuHeadroom(@Nullable android.os.CpuHeadroomParams);
    method @FlaggedApi("android.os.cpu_gpu_headrooms") @NonNull public android.util.Pair<java.lang.Integer,java.lang.Integer> getCpuHeadroomCalculationWindowRange();
    method @FlaggedApi("android.os.cpu_gpu_headrooms") public long getCpuHeadroomMinIntervalMillis();
    method @FlaggedApi("android.os.cpu_gpu_headrooms") @FloatRange(from=0.0f, to=100.0f) public float getGpuHeadroom(@Nullable android.os.GpuHeadroomParams);
    method @FlaggedApi("android.os.cpu_gpu_headrooms") @NonNull public android.util.Pair<java.lang.Integer,java.lang.Integer> getGpuHeadroomCalculationWindowRange();
    method @FlaggedApi("android.os.cpu_gpu_headrooms") public long getGpuHeadroomMinIntervalMillis();
    method @FlaggedApi("android.os.cpu_gpu_headrooms") @IntRange(from=1) public int getMaxCpuHeadroomTidsSize();
    method @FlaggedApi("com.android.server.power.optimization.power_monitor_api") public void getPowerMonitorReadings(@NonNull java.util.List<android.os.PowerMonitor>, @Nullable java.util.concurrent.Executor, @NonNull android.os.OutcomeReceiver<android.os.PowerMonitorReadings,java.lang.RuntimeException>);
    method @FlaggedApi("com.android.server.power.optimization.power_monitor_api") public void getSupportedPowerMonitors(@Nullable java.util.concurrent.Executor, @NonNull java.util.function.Consumer<java.util.List<android.os.PowerMonitor>>);
    method public android.os.health.HealthStats takeMyUidSnapshot();
+151 −74
Original line number Diff line number Diff line
@@ -28,15 +28,11 @@ import java.util.Arrays;

/**
 * Headroom request params used by {@link SystemHealthManager#getCpuHeadroom(CpuHeadroomParams)}.
 *
 * <p>This class is immutable and one should use the {@link Builder} to build a new instance.
 */
@FlaggedApi(Flags.FLAG_CPU_GPU_HEADROOMS)
public final class CpuHeadroomParams {
    final CpuHeadroomParamsInternal mInternal;

    public CpuHeadroomParams() {
        mInternal = new CpuHeadroomParamsInternal();
    }

    /** @hide */
    @IntDef(flag = false, prefix = {"CPU_HEADROOM_CALCULATION_TYPE_"}, value = {
            CPU_HEADROOM_CALCULATION_TYPE_MIN, // 0
@@ -47,18 +43,44 @@ public final class CpuHeadroomParams {
    }

    /**
     * Calculates the headroom based on minimum value over a device-defined window.
     * The headroom calculation type bases on minimum value over a specified window.
     */
    public static final int CPU_HEADROOM_CALCULATION_TYPE_MIN = 0;

    /**
     * Calculates the headroom based on average value over a device-defined window.
     * The headroom calculation type bases on average value over a specified window.
     */
    public static final int CPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1;

    private static final int CALCULATION_WINDOW_MILLIS_MIN = 50;
    private static final int CALCULATION_WINDOW_MILLIS_MAX = 10000;
    private static final int MAX_TID_COUNT = 5;
    /** @hide */
    public final CpuHeadroomParamsInternal mInternal;

    private CpuHeadroomParams() {
        mInternal = new CpuHeadroomParamsInternal();
    }

    public static final class Builder {
        private int mCalculationType = -1;
        private int mCalculationWindowMillis = -1;
        private int[] mTids = null;

        public Builder() {
        }

        /**
         * Returns a new builder copy with the same values as the params.
         */
        public Builder(@NonNull CpuHeadroomParams params) {
            if (params.mInternal.calculationType >= 0) {
                mCalculationType = params.mInternal.calculationType;
            }
            if (params.mInternal.calculationWindowMillis >= 0) {
                mCalculationWindowMillis = params.mInternal.calculationWindowMillis;
            }
            if (params.mInternal.tids != null) {
                mTids = Arrays.copyOf(params.mInternal.tids, params.mInternal.tids.length);
            }
        }

        /**
         * Sets the headroom calculation type.
@@ -66,88 +88,143 @@ public final class CpuHeadroomParams {
         *
         * @throws IllegalArgumentException if the type is invalid.
         */
    public void setCalculationType(@CpuHeadroomCalculationType int calculationType) {
        @NonNull
        public Builder setCalculationType(
                @CpuHeadroomCalculationType int calculationType) {
            switch (calculationType) {
                case CPU_HEADROOM_CALCULATION_TYPE_MIN:
            case CPU_HEADROOM_CALCULATION_TYPE_AVERAGE:
                mInternal.calculationType = (byte) calculationType;
                return;
                case CPU_HEADROOM_CALCULATION_TYPE_AVERAGE: {
                    mCalculationType = calculationType;
                    return this;
                }
            }
            throw new IllegalArgumentException("Invalid calculation type: " + calculationType);
        }

        /**
     * Gets the headroom calculation type.
     * Default to {@link #CPU_HEADROOM_CALCULATION_TYPE_MIN} if not set.
         * Sets the headroom calculation window size in milliseconds.
         * <p>
         *
         * @param windowMillis the window size in milliseconds ranges from
         *                     {@link SystemHealthManager#getCpuHeadroomCalculationWindowRange()}.
         *                     The smaller the window size, the larger fluctuation in the headroom
         *                     value should be expected. The default value can be retrieved from
         *                     the {@link CpuHeadroomParams#getCalculationWindowMillis}. The device
         *                     will try to use the closest feasible window size to this param.
         * @throws IllegalArgumentException if the window is invalid.
         */
    public @CpuHeadroomCalculationType int getCalculationType() {
        @CpuHeadroomCalculationType int validatedType = switch ((int) mInternal.calculationType) {
            case CPU_HEADROOM_CALCULATION_TYPE_MIN, CPU_HEADROOM_CALCULATION_TYPE_AVERAGE ->
                    mInternal.calculationType;
            default -> CPU_HEADROOM_CALCULATION_TYPE_MIN;
        };
        return validatedType;
        @NonNull
        public Builder setCalculationWindowMillis(@IntRange(from = 1) int windowMillis) {
            if (windowMillis <= 0) {
                throw new IllegalArgumentException("Invalid calculation window: " + windowMillis);
            }
            mCalculationWindowMillis = windowMillis;
            return this;
        }

        /**
     * Sets the headroom calculation window size in milliseconds.
         * Sets the thread TIDs to track.
         * <p>
         * The TIDs should belong to the same of the process that will make the headroom call. And
         * they should not have different core affinity.
         * <p>
         * If not set or set to empty, the headroom will be based on the PID of the process making
         * the call.
         *
     * @param windowMillis the window size in milliseconds ranges from [50, 10000]. The smaller the
     *                     window size, the larger fluctuation in the headroom value should be
     *                     expected. The default value can be retrieved from the
     *                     {@link #getCalculationWindowMillis}. The device will try to use the
     *                     closest feasible window size to this param.
     * @throws IllegalArgumentException if the window size is not in allowed range.
         * @param tids non-null list of TIDs, where maximum size can be read from
         *             {@link SystemHealthManager#getMaxCpuHeadroomTidsSize()}.
         * @throws IllegalArgumentException if the TID is not positive.
         */
    public void setCalculationWindowMillis(
            @IntRange(from = CALCULATION_WINDOW_MILLIS_MIN, to =
                    CALCULATION_WINDOW_MILLIS_MAX) int windowMillis) {
        if (windowMillis < CALCULATION_WINDOW_MILLIS_MIN
                || windowMillis > CALCULATION_WINDOW_MILLIS_MAX) {
            throw new IllegalArgumentException("Invalid calculation window: " + windowMillis);
        @NonNull
        public Builder setTids(@NonNull int... tids) {
            for (int tid : tids) {
                if (tid <= 0) {
                    throw new IllegalArgumentException("Invalid TID: " + tid);
                }
            }
            mTids = tids;
            return this;
        }

        /**
         * Builds the {@link CpuHeadroomParams} object.
         */
        @NonNull
        public CpuHeadroomParams build() {
            CpuHeadroomParams params = new CpuHeadroomParams();
            if (mCalculationType >= 0) {
                params.mInternal.calculationType = (byte) mCalculationType;
            }
            if (mCalculationWindowMillis >= 0) {
                params.mInternal.calculationWindowMillis = mCalculationWindowMillis;
            }
            if (mTids != null) {
                params.mInternal.tids = mTids;
            }
        mInternal.calculationWindowMillis = windowMillis;
            return params;
        }
    }

    /**
     * Returns a new builder with the same values as this object.
     */
    @NonNull
    public Builder toBuilder() {
        return new Builder(this);
    }

    /**
     * Gets the headroom calculation type.
     * <p>
     * This will return the default value chosen by the device if not set.
     */
    public @CpuHeadroomCalculationType int getCalculationType() {
        @CpuHeadroomCalculationType int validatedType = switch ((int) mInternal.calculationType) {
            case CPU_HEADROOM_CALCULATION_TYPE_MIN,
                 CPU_HEADROOM_CALCULATION_TYPE_AVERAGE -> mInternal.calculationType;
            default -> CPU_HEADROOM_CALCULATION_TYPE_MIN;
        };
        return validatedType;
    }

    /**
     * Gets the headroom calculation window size in milliseconds.
     * <p>
     * This will return the default value chosen by the device if the params is not set.
     * This will return the default value chosen by the device if not set.
     */
    public @IntRange(from = CALCULATION_WINDOW_MILLIS_MIN, to =
            CALCULATION_WINDOW_MILLIS_MAX) long getCalculationWindowMillis() {
    public long getCalculationWindowMillis() {
        return mInternal.calculationWindowMillis;
    }

    /**
     * Sets the thread TIDs to track.
     * <p>
     * The TIDs should belong to the same of the process that will the headroom call. And they
     * should not have different core affinity.
     * Gets the TIDs to track.
     * <p>
     * If not set, the headroom will be based on the PID of the process making the call.
     *
     * @param tids non-empty list of TIDs, maximum 5.
     * @throws IllegalArgumentException if the list size is not in allowed range or TID is not
     *                                  positive.
     * This will return a copy of the TIDs in the params, or null if the params is not set.
     */
    public void setTids(@NonNull int... tids) {
        if (tids.length == 0 || tids.length > MAX_TID_COUNT) {
            throw new IllegalArgumentException("Invalid number of TIDs: " + tids.length);
        }
        for (int tid : tids) {
            if (tid <= 0) {
                throw new IllegalArgumentException("Invalid TID: " + tid);
    @NonNull
    public int[] getTids() {
        return mInternal.tids == null ? null : Arrays.copyOf(mInternal.tids, mInternal.tids.length);
    }

    @Override
    public String toString() {
        return "CpuHeadroomParams{"
                + "calculationType=" + mInternal.calculationType
                + ", calculationWindowMillis=" + mInternal.calculationWindowMillis
                + ", tids=" + Arrays.toString(mInternal.tids)
                + '}';
    }
        mInternal.tids = Arrays.copyOf(tids, tids.length);

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        CpuHeadroomParams that = (CpuHeadroomParams) o;
        return mInternal.equals(that.mInternal);
    }

    /**
     * @hide
     */
    public CpuHeadroomParamsInternal getInternal() {
        return mInternal;
    @Override
    public int hashCode() {
        return mInternal.hashCode();
    }
}
+120 −52
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package android.os;
import android.annotation.FlaggedApi;
import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.os.health.SystemHealthManager;

import java.lang.annotation.Retention;
@@ -26,15 +27,11 @@ import java.lang.annotation.RetentionPolicy;

/**
 * Headroom request params used by {@link SystemHealthManager#getGpuHeadroom(GpuHeadroomParams)}.
 *
 * <p>This class is immutable and one should use the {@link Builder} to build a new instance.
 */
@FlaggedApi(Flags.FLAG_CPU_GPU_HEADROOMS)
public final class GpuHeadroomParams {
    final GpuHeadroomParamsInternal mInternal;

    public GpuHeadroomParams() {
        mInternal = new GpuHeadroomParamsInternal();
    }

    /** @hide */
    @IntDef(flag = false, prefix = {"GPU_HEADROOM_CALCULATION_TYPE_"}, value = {
            GPU_HEADROOM_CALCULATION_TYPE_MIN, // 0
@@ -45,17 +42,55 @@ public final class GpuHeadroomParams {
    }

    /**
     * Calculates the headroom based on minimum value over a device-defined window.
     * The headroom calculation type bases on minimum value over a specified window.
     */
    public static final int GPU_HEADROOM_CALCULATION_TYPE_MIN = 0;

    /**
     * Calculates the headroom based on average value over a device-defined window.
     * The headroom calculation type bases on average value over a specified window.
     */
    public static final int GPU_HEADROOM_CALCULATION_TYPE_AVERAGE = 1;

    private static final int CALCULATION_WINDOW_MILLIS_MIN = 50;
    private static final int CALCULATION_WINDOW_MILLIS_MAX = 10000;
    /**
     * The minimum size of the window to compute the headroom over.
     */
    public static final int GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MIN = 50;

    /**
     * The maximum size of the window to compute the headroom over.
     */
    public static final int GPU_HEADROOM_CALCULATION_WINDOW_MILLIS_MAX = 10000;

    /**
     * @hide
     */
    public final GpuHeadroomParamsInternal mInternal;

    /**
     * @hide
     */
    private GpuHeadroomParams() {
        mInternal = new GpuHeadroomParamsInternal();
    }

    public static final class Builder {
        private int mCalculationType = -1;
        private int mCalculationWindowMillis = -1;

        public Builder() {
        }

        /**
         * Returns a new builder with the same values as this object.
         */
        public Builder(@NonNull GpuHeadroomParams params) {
            if (params.mInternal.calculationType >= 0) {
                mCalculationType = params.mInternal.calculationType;
            }
            if (params.mInternal.calculationWindowMillis >= 0) {
                mCalculationWindowMillis = params.mInternal.calculationWindowMillis;
            }
        }

        /**
         * Sets the headroom calculation type.
@@ -63,64 +98,97 @@ public final class GpuHeadroomParams {
         *
         * @throws IllegalArgumentException if the type is invalid.
         */
    public void setCalculationType(@GpuHeadroomCalculationType int calculationType) {
        @NonNull
        public Builder setCalculationType(
                @GpuHeadroomCalculationType int calculationType) {
            switch (calculationType) {
                case GPU_HEADROOM_CALCULATION_TYPE_MIN:
            case GPU_HEADROOM_CALCULATION_TYPE_AVERAGE:
                mInternal.calculationType = (byte) calculationType;
                return;
                case GPU_HEADROOM_CALCULATION_TYPE_AVERAGE: {
                    mCalculationType = calculationType;
                    return this;
                }
        throw new IllegalArgumentException("Invalid calculation type: " + calculationType);
            }

    /**
     * Gets the headroom calculation type.
     * Default to {@link #GPU_HEADROOM_CALCULATION_TYPE_MIN} if the params is not set.
     */
    public @GpuHeadroomCalculationType int getCalculationType() {
        @GpuHeadroomCalculationType int validatedType = switch ((int) mInternal.calculationType) {
            case GPU_HEADROOM_CALCULATION_TYPE_MIN, GPU_HEADROOM_CALCULATION_TYPE_AVERAGE ->
                    mInternal.calculationType;
            default -> GPU_HEADROOM_CALCULATION_TYPE_MIN;
        };
        return validatedType;
            throw new IllegalArgumentException("Invalid calculation type: " + calculationType);
        }

        /**
         * Sets the headroom calculation window size in milliseconds.
         * <p>
         *
     * @param windowMillis the window size in milliseconds ranges from [50, 10000]. The smaller the
     *                     window size, the larger fluctuation in the headroom value should be
     *                     expected. The default value can be retrieved from the
     *                     {@link #getCalculationWindowMillis}. The device will try to use the
     *                     closest feasible window size to this param.
         * @param windowMillis the window size in milliseconds ranges from
         *                     {@link SystemHealthManager#getGpuHeadroomCalculationWindowRange()}.
         *                     The smaller the window size, the larger fluctuation in the headroom
         *                     value should be expected. The default value can be retrieved from
         *                     the {@link GpuHeadroomParams#getCalculationWindowMillis}. The device
         *                     will try to use the closest feasible window size to this param.
         * @throws IllegalArgumentException if the window is invalid.
         */
    public void setCalculationWindowMillis(
            @IntRange(from = CALCULATION_WINDOW_MILLIS_MIN, to =
                    CALCULATION_WINDOW_MILLIS_MAX) int windowMillis) {
        if (windowMillis < CALCULATION_WINDOW_MILLIS_MIN
                || windowMillis > CALCULATION_WINDOW_MILLIS_MAX) {
        @NonNull
        public Builder setCalculationWindowMillis(@IntRange(from = 1) int windowMillis) {
            if (windowMillis <= 0) {
                throw new IllegalArgumentException("Invalid calculation window: " + windowMillis);
            }
        mInternal.calculationWindowMillis = windowMillis;
            mCalculationWindowMillis = windowMillis;
            return this;
        }

        /**
     * Gets the headroom calculation window size in milliseconds.
         * Builds the {@link GpuHeadroomParams} object.
         */
        @NonNull
        public GpuHeadroomParams build() {
            GpuHeadroomParams params = new GpuHeadroomParams();
            if (mCalculationType >= 0) {
                params.mInternal.calculationType = (byte) mCalculationType;
            }
            if (mCalculationWindowMillis >= 0) {
                params.mInternal.calculationWindowMillis = mCalculationWindowMillis;
            }
            return params;
        }
    }

    /**
     * Gets the headroom calculation type.
     * <p>
     * This will return the default value chosen by the device if not set.
     */
    public @IntRange(from = CALCULATION_WINDOW_MILLIS_MIN, to =
            CALCULATION_WINDOW_MILLIS_MAX) int getCalculationWindowMillis() {
        return mInternal.calculationWindowMillis;
    public @GpuHeadroomCalculationType int getCalculationType() {
        @GpuHeadroomCalculationType int validatedType = switch ((int) mInternal.calculationType) {
            case GPU_HEADROOM_CALCULATION_TYPE_MIN,
                 GPU_HEADROOM_CALCULATION_TYPE_AVERAGE -> mInternal.calculationType;
            default -> GPU_HEADROOM_CALCULATION_TYPE_MIN;
        };
        return validatedType;
    }

    /**
     * @hide
     * Gets the headroom calculation window size in milliseconds.
     * <p>
     * This will return the default value chosen by the device if not set.
     */
    public GpuHeadroomParamsInternal getInternal() {
        return mInternal;
    public int getCalculationWindowMillis() {
        return mInternal.calculationWindowMillis;
    }

    @Override
    public String toString() {
        return "GpuHeadroomParams{"
                + "calculationType=" + mInternal.calculationType
                + ", calculationWindowMillis=" + mInternal.calculationWindowMillis
                + '}';
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        GpuHeadroomParams that = (GpuHeadroomParams) o;
        return mInternal.equals(that.mInternal);
    }

    @Override
    public int hashCode() {
        return mInternal.hashCode();
    }
}
+3 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ interface IHintManager {
    parcelable HintManagerClientData {
        int powerHalVersion;
        int maxGraphicsPipelineThreads;
        int maxCpuHeadroomThreads;
        long preferredRateNanos;
        SupportInfo supportInfo;
    }
@@ -82,4 +83,6 @@ interface IHintManager {
     * passing back a bundle of support and configuration information.
     */
    HintManagerClientData registerClient(in IHintManagerClient client);

    HintManagerClientData getClientData();
}
+177 −17

File changed.

Preview size limit exceeded, changes collapsed.

Loading