CpuFrequencies.java revision ce643a309e8d414395ec36188523d10eb64d6618
1/* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16package com.android.server.power.batterysaver; 17 18import android.util.ArrayMap; 19import android.util.Slog; 20 21import com.android.internal.annotations.GuardedBy; 22 23import java.util.Map; 24 25 26/** 27 * Helper to parse a list of "core-number:frequency" pairs concatenated with / as a separator, 28 * and convert them into a map of "filename -> value" that should be written to 29 * /sys/.../scaling_max_freq. 30 * 31 * Example input: "0:1900800/4:2500000", which will be converted into: 32 * "/sys/devices/system/cpu/cpu0/cpufreq/scaling_max_freq" "1900800" 33 * "/sys/devices/system/cpu/cpu4/cpufreq/scaling_max_freq" "2500000" 34 * 35 * Test: 36 atest $ANDROID_BUILD_TOP/frameworks/base/services/tests/servicestests/src/com/android/server/power/batterysaver/CpuFrequenciesTest.java 37 */ 38public class CpuFrequencies { 39 private static final String TAG = "CpuFrequencies"; 40 41 private final Object mLock = new Object(); 42 43 @GuardedBy("mLock") 44 private final ArrayMap<Integer, Long> mCoreAndFrequencies = new ArrayMap<>(); 45 46 public CpuFrequencies() { 47 } 48 49 /** 50 * Parse a string. 51 */ 52 public CpuFrequencies parseString(String cpuNumberAndFrequencies) { 53 synchronized (mLock) { 54 mCoreAndFrequencies.clear(); 55 try { 56 for (String pair : cpuNumberAndFrequencies.split("/")) { 57 final String[] coreAndFreq = pair.split(":", 2); 58 59 if (coreAndFreq.length != 2) { 60 throw new IllegalArgumentException("Wrong format"); 61 } 62 final int core = Integer.parseInt(coreAndFreq[0]); 63 final long freq = Long.parseLong(coreAndFreq[1]); 64 65 mCoreAndFrequencies.put(core, freq); 66 } 67 } catch (IllegalArgumentException e) { 68 Slog.wtf(TAG, "Invalid configuration: " + cpuNumberAndFrequencies, e); 69 } 70 } 71 return this; 72 } 73 74 /** 75 * Return a new map containing the filename-value pairs. 76 */ 77 public ArrayMap<String, String> toSysFileMap() { 78 final ArrayMap<String, String> map = new ArrayMap<>(); 79 addToSysFileMap(map); 80 return map; 81 } 82 83 /** 84 * Add the filename-value pairs to an existing map. 85 */ 86 public void addToSysFileMap(Map<String, String> map) { 87 synchronized (mLock) { 88 final int size = mCoreAndFrequencies.size(); 89 90 for (int i = 0; i < size; i++) { 91 final int core = mCoreAndFrequencies.keyAt(i); 92 final long freq = mCoreAndFrequencies.valueAt(i); 93 94 final String file = "/sys/devices/system/cpu/cpu" + Integer.toString(core) + 95 "/cpufreq/scaling_max_freq"; 96 97 map.put(file, Long.toString(freq)); 98 } 99 } 100 } 101} 102