Add sources for API 35
Downloaded from https://dl.google.com/android/repository/source-35_r01.zip
using SdkManager in Studio
Test: None
Change-Id: I83f78aa820b66edfdc9f8594d17bc7b6cacccec1
diff --git a/android-35/com/android/internal/os/CpuScalingPolicyReader.java b/android-35/com/android/internal/os/CpuScalingPolicyReader.java
new file mode 100644
index 0000000..720577e
--- /dev/null
+++ b/android-35/com/android/internal/os/CpuScalingPolicyReader.java
@@ -0,0 +1,148 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.os;
+
+import android.annotation.NonNull;
+import android.os.FileUtils;
+import android.util.IntArray;
+import android.util.Slog;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import libcore.util.EmptyArray;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * Captures a CPU scaling policies such as available scaling frequencies as well as
+ * CPUs (cores) for each policy.
+ *
+ * See <a
+ * href="https://www.kernel.org/doc/html/latest/admin-guide/pm/cpufreq.html
+ * #policy-interface-in-sysfs">Policy Interface in sysfs</a>
+ */
[email protected]
+public class CpuScalingPolicyReader {
+ private static final String TAG = "CpuScalingPolicyReader";
+ private static final String CPUFREQ_DIR = "/sys/devices/system/cpu/cpufreq";
+ private static final Pattern POLICY_PATTERN = Pattern.compile("policy(\\d+)");
+ private static final String FILE_NAME_RELATED_CPUS = "related_cpus";
+ private static final String FILE_NAME_SCALING_AVAILABLE_FREQUENCIES =
+ "scaling_available_frequencies";
+ private static final String FILE_NAME_SCALING_BOOST_FREQUENCIES = "scaling_boost_frequencies";
+ private static final String FILE_NAME_CPUINFO_CUR_FREQ = "cpuinfo_cur_freq";
+
+ private final String mCpuFreqDir;
+
+ public CpuScalingPolicyReader() {
+ this(CPUFREQ_DIR);
+ }
+
+ @VisibleForTesting
+ public CpuScalingPolicyReader(String cpuFreqDir) {
+ mCpuFreqDir = cpuFreqDir;
+ }
+
+ /**
+ * Reads scaling policy info from sysfs files in /sys/devices/system/cpu/cpufreq
+ */
+ @NonNull
+ public CpuScalingPolicies read() {
+ SparseArray<int[]> cpusByPolicy = new SparseArray<>();
+ SparseArray<int[]> freqsByPolicy = new SparseArray<>();
+
+ File cpuFreqDir = new File(mCpuFreqDir);
+ File[] policyDirs = cpuFreqDir.listFiles();
+ if (policyDirs != null) {
+ for (File policyDir : policyDirs) {
+ Matcher matcher = POLICY_PATTERN.matcher(policyDir.getName());
+ if (matcher.matches()) {
+ int[] relatedCpus = readIntsFromFile(
+ new File(policyDir, FILE_NAME_RELATED_CPUS));
+ if (relatedCpus.length == 0) {
+ continue;
+ }
+
+ int[] availableFreqs = readIntsFromFile(
+ new File(policyDir, FILE_NAME_SCALING_AVAILABLE_FREQUENCIES));
+ int[] boostFreqs = readIntsFromFile(
+ new File(policyDir, FILE_NAME_SCALING_BOOST_FREQUENCIES));
+ int[] freqs;
+ if (boostFreqs.length == 0) {
+ freqs = availableFreqs;
+ } else {
+ freqs = Arrays.copyOf(availableFreqs,
+ availableFreqs.length + boostFreqs.length);
+ System.arraycopy(boostFreqs, 0, freqs, availableFreqs.length,
+ boostFreqs.length);
+ }
+ if (freqs.length == 0) {
+ freqs = readIntsFromFile(new File(policyDir, FILE_NAME_CPUINFO_CUR_FREQ));
+ if (freqs.length == 0) {
+ freqs = new int[]{0}; // Unknown frequency
+ }
+ }
+ int policy = Integer.parseInt(matcher.group(1));
+ cpusByPolicy.put(policy, relatedCpus);
+ freqsByPolicy.put(policy, freqs);
+ }
+ }
+ }
+
+ if (cpusByPolicy.size() == 0) {
+ // There just has to be at least one CPU - otherwise, what's executing this code?
+ cpusByPolicy.put(0, new int[]{0});
+ freqsByPolicy.put(0, new int[]{0});
+ }
+
+ return new CpuScalingPolicies(cpusByPolicy, freqsByPolicy);
+ }
+
+ @NonNull
+ private static int[] readIntsFromFile(File file) {
+ if (!file.exists()) {
+ return EmptyArray.INT;
+ }
+
+ IntArray intArray = new IntArray(16);
+ try {
+ String contents = FileUtils.readTextFile(file, 0, null).trim();
+ String[] strings = contents.split(" ");
+ intArray.clear();
+ for (String s : strings) {
+ if (s.isBlank()) {
+ continue;
+ }
+ try {
+ intArray.add(Integer.parseInt(s));
+ } catch (NumberFormatException e) {
+ Slog.e(TAG, "Unexpected file format " + file
+ + ": " + contents, e);
+ }
+ }
+ return intArray.toArray();
+ } catch (IOException e) {
+ Slog.e(TAG, "Cannot read " + file, e);
+ return EmptyArray.INT;
+ }
+ }
+}