diff --git a/services/core/java/com/android/server/cpu/CpuAvailabilityInfo.java b/services/core/java/com/android/server/cpu/CpuAvailabilityInfo.java index 06b45bf0fb4b8..97507be96d84d 100644 --- a/services/core/java/com/android/server/cpu/CpuAvailabilityInfo.java +++ b/services/core/java/com/android/server/cpu/CpuAvailabilityInfo.java @@ -21,6 +21,8 @@ import static com.android.server.cpu.CpuAvailabilityMonitoringConfig.CPUSET_BACK import com.android.internal.util.Preconditions; +import java.util.Objects; + /** CPU availability information. */ public final class CpuAvailabilityInfo { /** Constant to indicate missing CPU availability percent. */ @@ -35,29 +37,64 @@ public final class CpuAvailabilityInfo { @CpuAvailabilityMonitoringConfig.Cpuset public final int cpuset; + /** Uptime (in milliseconds) when the data in this object was captured. */ + public final long dataTimestampUptimeMillis; + /** The latest average CPU availability percent. */ public final int latestAvgAvailabilityPercent; - /** The past N-second average CPU availability percent. */ - public final int pastNSecAvgAvailabilityPercent; + /** + * The past N-millisecond average CPU availability percent. + * + *

When there is not enough data to calculate the past N-millisecond average, this field will + * contain the value {@link MISSING_CPU_AVAILABILITY_PERCENT}. + */ + public final int pastNMillisAvgAvailabilityPercent; - /** The duration over which the {@link pastNSecAvgAvailabilityPercent} was calculated. */ - public final int avgAvailabilityDurationSec; + /** The duration over which the {@link pastNMillisAvgAvailabilityPercent} was calculated. */ + public final long pastNMillisDuration; @Override public String toString() { - return "CpuAvailabilityInfo{" + "cpuset=" + cpuset + ", latestAvgAvailabilityPercent=" - + latestAvgAvailabilityPercent + ", pastNSecAvgAvailabilityPercent=" - + pastNSecAvgAvailabilityPercent + ", avgAvailabilityDurationSec=" - + avgAvailabilityDurationSec + '}'; + return "CpuAvailabilityInfo{" + "cpuset = " + cpuset + ", dataTimestampUptimeMillis = " + + dataTimestampUptimeMillis + ", latestAvgAvailabilityPercent = " + + latestAvgAvailabilityPercent + ", pastNMillisAvgAvailabilityPercent = " + + pastNMillisAvgAvailabilityPercent + ", pastNMillisDuration = " + + pastNMillisDuration + '}'; } - CpuAvailabilityInfo(int cpuset, int latestAvgAvailabilityPercent, - int pastNSecAvgAvailabilityPercent, int avgAvailabilityDurationSec) { + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (!(obj instanceof CpuAvailabilityInfo)) { + return false; + } + CpuAvailabilityInfo info = (CpuAvailabilityInfo) obj; + return cpuset == info.cpuset && dataTimestampUptimeMillis == info.dataTimestampUptimeMillis + && latestAvgAvailabilityPercent == info.latestAvgAvailabilityPercent + && pastNMillisAvgAvailabilityPercent == info.pastNMillisAvgAvailabilityPercent + && pastNMillisDuration == info.pastNMillisDuration; + } + + @Override + public int hashCode() { + return Objects.hash(cpuset, dataTimestampUptimeMillis, latestAvgAvailabilityPercent, + pastNMillisAvgAvailabilityPercent, pastNMillisDuration); + } + + CpuAvailabilityInfo(int cpuset, long dataTimestampUptimeMillis, + int latestAvgAvailabilityPercent, int pastNMillisAvgAvailabilityPercent, + long pastNMillisDuration) { this.cpuset = Preconditions.checkArgumentInRange(cpuset, CPUSET_ALL, CPUSET_BACKGROUND, "cpuset"); - this.latestAvgAvailabilityPercent = latestAvgAvailabilityPercent; - this.pastNSecAvgAvailabilityPercent = pastNSecAvgAvailabilityPercent; - this.avgAvailabilityDurationSec = avgAvailabilityDurationSec; + this.dataTimestampUptimeMillis = + Preconditions.checkArgumentNonnegative(dataTimestampUptimeMillis); + this.latestAvgAvailabilityPercent = Preconditions.checkArgumentNonnegative( + latestAvgAvailabilityPercent); + this.pastNMillisAvgAvailabilityPercent = pastNMillisAvgAvailabilityPercent; + this.pastNMillisDuration = Preconditions.checkArgumentNonnegative( + pastNMillisDuration); } } diff --git a/services/core/java/com/android/server/cpu/CpuAvailabilityMonitoringConfig.java b/services/core/java/com/android/server/cpu/CpuAvailabilityMonitoringConfig.java index a3c4c9e828b4f..cbe02fc09d84c 100644 --- a/services/core/java/com/android/server/cpu/CpuAvailabilityMonitoringConfig.java +++ b/services/core/java/com/android/server/cpu/CpuAvailabilityMonitoringConfig.java @@ -90,8 +90,19 @@ public final class CpuAvailabilityMonitoringConfig { @Override public String toString() { - return "CpuAvailabilityMonitoringConfig{cpuset=" + cpuset + ", mThresholds=" + mThresholds - + ')'; + return "CpuAvailabilityMonitoringConfig{cpuset=" + toCpusetString(cpuset) + ", mThresholds=" + + mThresholds + ')'; + } + + /** Returns the string equivalent of the provided cpuset. */ + public static String toCpusetString(int cpuset) { + switch (cpuset) { + case CPUSET_ALL: + return "CPUSET_ALL"; + case CPUSET_BACKGROUND: + return "CPUSET_BACKGROUND"; + } + return "Invalid cpuset: " + cpuset; } private CpuAvailabilityMonitoringConfig(Builder builder) { diff --git a/services/core/java/com/android/server/cpu/CpuInfoReader.java b/services/core/java/com/android/server/cpu/CpuInfoReader.java index ca97a9847b39b..ce68edbb9fa1f 100644 --- a/services/core/java/com/android/server/cpu/CpuInfoReader.java +++ b/services/core/java/com/android/server/cpu/CpuInfoReader.java @@ -21,8 +21,10 @@ import static com.android.server.cpu.CpuMonitorService.TAG; import android.annotation.IntDef; import android.annotation.Nullable; +import android.os.SystemClock; import android.system.Os; import android.system.OsConstants; +import android.util.IndentingPrintWriter; import android.util.IntArray; import android.util.LongSparseLongArray; import android.util.SparseArray; @@ -50,6 +52,9 @@ public final class CpuInfoReader { private static final String POLICY_DIR_PREFIX = "policy"; private static final String RELATED_CPUS_FILE = "related_cpus"; private static final String AFFECTED_CPUS_FILE = "affected_cpus"; + // TODO(b/263154344): Avoid reading from cpuinfo_cur_freq because non-root users don't have + // read permission for this file. The file permissions are set by the Kernel. Instead, read + // the current frequency only from scaling_cur_freq. private static final String CUR_CPUFREQ_FILE = "cpuinfo_cur_freq"; private static final String MAX_CPUFREQ_FILE = "cpuinfo_max_freq"; private static final String CUR_SCALING_FREQ_FILE = "scaling_cur_freq"; @@ -70,16 +75,18 @@ public final class CpuInfoReader { private static final Pattern TIME_IN_STATE_PATTERN = Pattern.compile("(?[0-9]+)\\s(?