1 /* 2 * Copyright (C) 2021 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 */ 16 17 package android.car.cts.powerpolicy; 18 19 import com.android.car.power.CarPowerDumpProto.PolicyReaderProto; 20 import com.android.car.power.CarPowerDumpProto.PolicyReaderProto.IdToPolicyGroup; 21 import com.android.car.power.CarPowerDumpProto.PolicyReaderProto.IdToPolicyGroup.PolicyGroup; 22 import com.android.car.power.CarPowerDumpProto.PolicyReaderProto.IdToPolicyGroup.PolicyGroup.StateToDefaultPolicy; 23 import com.android.tradefed.log.LogUtil; 24 25 import java.util.HashMap; 26 import java.util.List; 27 import java.util.Objects; 28 import java.util.Set; 29 30 public final class PowerPolicyGroups { 31 private final HashMap<String, PowerPolicyGroupDef> mPolicyGroups = new HashMap<>(); 32 PowerPolicyGroups()33 public PowerPolicyGroups() { } 34 PowerPolicyGroups(PowerPolicyGroupDef[] defs)35 public PowerPolicyGroups(PowerPolicyGroupDef[] defs) { 36 for (int i = 0; i < defs.length; i++) { 37 mPolicyGroups.put(defs[i].mGroupId, defs[i]); 38 } 39 } 40 41 /** 42 * Add a policy group 43 * @param id policy group ID 44 * @param waitForVHALPolicy ID of default policy for wait for VHAL power state 45 * @param onPolicy ID of default policy for on power state 46 * @throws IllegalArgumentException if a policy group with {@code id} already exists 47 */ add(String id, String waitForVHALPolicy, String onPolicy)48 public void add(String id, String waitForVHALPolicy, String onPolicy) 49 throws IllegalArgumentException { 50 if (mPolicyGroups.containsKey(id)) { 51 throw new IllegalArgumentException(id + " policy group already exists"); 52 } 53 PowerPolicyGroupDef groupDef = new PowerPolicyGroupDef(id, waitForVHALPolicy, onPolicy); 54 mPolicyGroups.put(id, groupDef); 55 } 56 57 @Override toString()58 public String toString() { 59 StringBuilder str = new StringBuilder(); 60 str.append("Power policy groups:\n"); 61 mPolicyGroups.forEach((k, v) -> str.append(v.toString())); 62 return str.toString(); 63 } 64 65 @Override hashCode()66 public int hashCode() { 67 return mPolicyGroups.hashCode(); 68 } 69 70 @Override equals(Object o)71 public boolean equals(Object o) { 72 if (this == o) return true; 73 if (o == null || getClass() != o.getClass()) return false; 74 PowerPolicyGroups peer = (PowerPolicyGroups) o; 75 return mPolicyGroups.equals(peer.mPolicyGroups); 76 } 77 78 /** 79 * Parse an array of strings representing power policy groups in order to define them 80 * @param defStrs strings representing power policy group definitions 81 * @return the {@code PowerPolicyGroups} object with the new power policy group definitions 82 */ parse(List<String> defStrs)83 public static PowerPolicyGroups parse(List<String> defStrs) { 84 PowerPolicyGroups policyGroups = new PowerPolicyGroups(); 85 String groupId = null; 86 String waitForVHALPolicy = null; 87 String onPolicy = null; 88 89 String groupDefDelimiter = "-->"; 90 for (int i = 0; i < defStrs.size(); ++i) { 91 String line = defStrs.get(i); 92 if (line.contains(groupDefDelimiter)) { 93 // this is policy group definition 94 if (line.contains("WaitForVHAL")) { 95 waitForVHALPolicy = parsePolicyGroupDef("WaitForVHAL", line); 96 } else if (line.contains("On")) { 97 onPolicy = parsePolicyGroupDef("On", line); 98 } else { 99 LogUtil.CLog.d("Policy group is ignored: " + line); 100 } 101 } else { 102 // Found name, if name is not empty, another group was already found 103 // add previous group to the policyGroups before proceeding with current one 104 if (groupId != null) { 105 policyGroups.add(groupId, waitForVHALPolicy, onPolicy); 106 waitForVHALPolicy = null; 107 onPolicy = null; 108 } 109 groupId = line.trim(); 110 } 111 } 112 // If group wasn't saved (indicated by non-null values of policies), save it 113 if (groupId != null && (waitForVHALPolicy != null || onPolicy != null)) { 114 policyGroups.add(groupId, waitForVHALPolicy, onPolicy); 115 } 116 return policyGroups; 117 } 118 parseProto(PolicyReaderProto policyReaderProto)119 static PowerPolicyGroups parseProto(PolicyReaderProto policyReaderProto) 120 throws Exception { 121 PowerPolicyGroups policyGroups = new PowerPolicyGroups(); 122 int numPolicyGroups = policyReaderProto.getPowerPolicyGroupMappingsCount(); 123 for (int i = 0; i < numPolicyGroups; i++) { 124 IdToPolicyGroup policyGroupMapping = policyReaderProto.getPowerPolicyGroupMappings(i); 125 String policyGroupId = policyGroupMapping.getPolicyGroupId(); 126 PolicyGroup policyGroup = policyGroupMapping.getPolicyGroup(); 127 int numPolicies = policyGroup.getDefaultPolicyMappingsCount(); 128 String waitForVhalPolicy = null; 129 String onPolicy = null; 130 for (int j = 0; j < numPolicies; j++) { 131 StateToDefaultPolicy policyMapping = policyGroup.getDefaultPolicyMappings(j); 132 String state = policyMapping.getState(); 133 String policyId = policyMapping.getDefaultPolicyId(); 134 if (state.equals("WaitForVHAL") && waitForVhalPolicy == null) { 135 waitForVhalPolicy = policyId; 136 } else if (state.equals("On") && onPolicy == null) { 137 onPolicy = policyId; 138 } else { 139 String errMsg = "Incorrect power policy groups format\nPolicy reader proto:\n" 140 + "state: " + state + "\npolicyId: " + policyId 141 + "\nwaitForVHAL policy: " + waitForVhalPolicy + "\non policy: " 142 + onPolicy; 143 LogUtil.CLog.e(errMsg); 144 throw new IllegalArgumentException(errMsg); 145 } 146 } 147 policyGroups.add(policyGroupId, waitForVhalPolicy, onPolicy); 148 } 149 return policyGroups; 150 } 151 parsePolicyGroupDef(String stateName, String defStr)152 private static String parsePolicyGroupDef(String stateName, String defStr) { 153 String[] tokens = defStr.trim().split("(\\s*)(-{1,2})(>?)(\\s*)"); 154 if (tokens.length != 3) { 155 throw new IllegalArgumentException("malformatted policy group def str: " + defStr); 156 } 157 158 if (!stateName.equals(tokens[1].trim())) { 159 String errMsg = String.format("expected power state: %s but got: %s", 160 stateName, tokens[1]); 161 throw new IllegalArgumentException(errMsg); 162 } 163 164 return tokens[2].trim(); 165 } 166 getGroupIds()167 public Set<String> getGroupIds() { 168 return mPolicyGroups.keySet(); 169 } 170 getGroup(String groupId)171 public PowerPolicyGroupDef getGroup(String groupId) { 172 return mPolicyGroups.get(groupId); 173 } 174 containsGroup(String groupId, PowerPolicyGroupDef expectedGroupDef)175 public boolean containsGroup(String groupId, PowerPolicyGroupDef expectedGroupDef) { 176 PowerPolicyGroupDef policyGroup = mPolicyGroups.get(groupId); 177 if (policyGroup == null) { 178 return false; 179 } 180 181 return policyGroup.equals(expectedGroupDef); 182 } 183 184 public static final class PowerPolicyGroupDef { 185 private final String mGroupId; 186 private final String mWaitForVHALStatePolicy; 187 private final String mOnStatePolicy; 188 PowerPolicyGroupDef(String groupId, String waitForVHALPolicy, String onPolicy)189 private PowerPolicyGroupDef(String groupId, String waitForVHALPolicy, String onPolicy) { 190 mGroupId = groupId; 191 mWaitForVHALStatePolicy = waitForVHALPolicy; 192 mOnStatePolicy = onPolicy; 193 } 194 getGroupId()195 public String getGroupId() { 196 return mGroupId; 197 } 198 getWaitForVHALStatePolicy()199 public String getWaitForVHALStatePolicy() { 200 return mWaitForVHALStatePolicy; 201 } 202 getOnStatePolicy()203 public String getOnStatePolicy() { 204 return mOnStatePolicy; 205 } 206 toShellCommandString()207 public String toShellCommandString() { 208 return String.format("%s WaitForVHAL:%s On:%s", mGroupId, 209 mWaitForVHALStatePolicy, mOnStatePolicy); 210 } 211 212 @Override toString()213 public String toString() { 214 StringBuilder str = new StringBuilder(); 215 str.append(" ").append(mGroupId).append('\n'); 216 str.append(" - WaitForVHAL --> ").append(mWaitForVHALStatePolicy).append('\n'); 217 str.append(" - On --> ").append(mOnStatePolicy).append('\n'); 218 return str.toString(); 219 } 220 221 @Override equals(Object o)222 public boolean equals(Object o) { 223 if (this == o) return true; 224 if (o == null || getClass() != o.getClass()) return false; 225 PowerPolicyGroupDef that = (PowerPolicyGroupDef) o; 226 return Objects.equals(mGroupId, that.mGroupId) 227 && Objects.equals(mWaitForVHALStatePolicy, that.mWaitForVHALStatePolicy) 228 && Objects.equals(mOnStatePolicy, that.mOnStatePolicy); 229 } 230 231 @Override hashCode()232 public int hashCode() { 233 return Objects.hash(mGroupId, mWaitForVHALStatePolicy, mOnStatePolicy); 234 } 235 } 236 237 public static final class TestSet { 238 public static final String GROUP_ID1 = "policy_group1"; 239 public static final String GROUP_ID2 = "policy_group2"; 240 241 public static final PowerPolicyGroupDef POLICY_GROUP_DEF1 = 242 new PowerPolicyGroupDef(GROUP_ID1, PowerPolicyDef.IdSet.TEST1, 243 PowerPolicyDef.IdSet.TEST2); 244 245 public static final PowerPolicyGroupDef POLICY_GROUP_DEF2 = 246 new PowerPolicyGroupDef(GROUP_ID2, PowerPolicyDef.IdSet.TEST2, 247 PowerPolicyDef.IdSet.TEST1); 248 249 public static final PowerPolicyGroups POLICY_GROUPS1 = new PowerPolicyGroups( 250 new PowerPolicyGroupDef[]{POLICY_GROUP_DEF1, POLICY_GROUP_DEF2}); 251 TestSet()252 private TestSet() { } 253 } 254 } 255