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.tradefed.log.LogUtil.CLog; 20 21 import java.util.ArrayList; 22 import java.util.Arrays; 23 import java.util.List; 24 import java.util.Objects; 25 import java.util.StringTokenizer; 26 27 public final class PowerPolicyDef { 28 public static final String[] ENABLED_HEADERS = 29 {"enabledComponents", "Enabled components"}; 30 public static final String[] DISABLED_HEADERS = 31 {"disabledComponents", "Disabled components"}; 32 public static final int STRING_BUILDER_BUF_SIZE = 1024; 33 34 private final String mPolicyId; 35 private final PowerComponent[] mEnables; 36 private final PowerComponent[] mDisables; 37 PowerPolicyDef(String policyId, PowerComponent[] enables, PowerComponent[] disables)38 private PowerPolicyDef(String policyId, PowerComponent[] enables, PowerComponent[] disables) { 39 mPolicyId = policyId; 40 mEnables = enables; 41 mDisables = disables; 42 } 43 getPolicyId()44 public String getPolicyId() { 45 return mPolicyId; 46 } 47 getEnables()48 public PowerComponent[] getEnables() { 49 return mEnables; 50 } 51 getDisables()52 public PowerComponent[] getDisables() { 53 return mDisables; 54 } 55 56 @Override toString()57 public String toString() { 58 String[] enables = Arrays.stream(mEnables).map(PowerComponent::getValue) 59 .toArray(String[]::new); 60 String[] disables = Arrays.stream(mDisables).map(PowerComponent::getValue) 61 .toArray(String[]::new); 62 StringBuilder str = new StringBuilder(); 63 str.append(mPolicyId); 64 if (enables.length > 0) { 65 str.append(" --enable ").append(String.join(",", enables)); 66 } 67 if (disables.length > 0) { 68 str.append(" --disable ").append(String.join(",", disables)); 69 } 70 return str.toString(); 71 } 72 73 @Override equals(Object o)74 public boolean equals(Object o) { 75 if (this == o) return true; 76 if (o == null || getClass() != o.getClass()) return false; 77 PowerPolicyDef that = (PowerPolicyDef) o; 78 return Objects.equals(mPolicyId, that.mPolicyId) 79 && Arrays.equals(mEnables, that.mEnables) 80 && Arrays.equals(mDisables, that.mDisables); 81 } 82 83 @Override hashCode()84 public int hashCode() { 85 int result = Objects.hash(mPolicyId); 86 result = 31 * result + Arrays.hashCode(mEnables); 87 result = 31 * result + Arrays.hashCode(mDisables); 88 return result; 89 } 90 parse(String policyDefStr, boolean hasPolicyId, int offset)91 public static PowerPolicyDef parse(String policyDefStr, boolean hasPolicyId, int offset) 92 throws Exception { 93 if (policyDefStr == null) { 94 throw new IllegalArgumentException("null policyDefStr parameter"); 95 } 96 CLog.d("policyDefStr: " + policyDefStr); 97 98 StringTokenizer tokens = new StringTokenizer(policyDefStr, "():"); 99 String policyId = hasPolicyId 100 ? tokens.nextToken().trim().substring(offset).trim() : IdSet.NONE; 101 102 if (!search(ENABLED_HEADERS, tokens.nextToken().trim())) { 103 throw new IllegalArgumentException("malformatted enabled headers string: " 104 + policyDefStr); 105 } 106 107 int idx = 0; 108 String[] enables = null; 109 String tmpStr = tokens.nextToken().trim(); 110 CLog.d("enables: " + tmpStr); 111 for (String hdr : DISABLED_HEADERS) { 112 idx = tmpStr.indexOf(hdr); 113 if (idx >= 0) { 114 tmpStr = tmpStr.substring(0, idx).trim(); 115 if (!tmpStr.isEmpty()) { 116 enables = tmpStr.split(",\\s*"); 117 } 118 break; 119 } 120 } 121 if (idx < 0) { 122 throw new IllegalArgumentException("malformatted disabled headers string: " 123 + policyDefStr); 124 } 125 PowerComponent[] enabledComps = PowerComponent.asComponentArray(enables); 126 127 String[] disables = null; 128 tmpStr = tokens.nextToken().trim(); 129 CLog.d("disables: " + tmpStr); 130 if (!tmpStr.isEmpty()) { 131 disables = tmpStr.split(",\\s*"); 132 } 133 PowerComponent[] disabledComps = PowerComponent.asComponentArray(disables); 134 135 return new PowerPolicyDef(policyId, enabledComps, disabledComps); 136 } 137 createWithComponentOff(String component)138 public static PowerPolicyDef createWithComponentOff(String component) 139 throws Exception { 140 PowerComponent removingComp = PowerComponent.valueOf(component); 141 142 ArrayList<PowerComponent> enableList = new ArrayList<PowerComponent>( 143 Arrays.asList(ComponentList.ALL_COMPONENTS)); 144 if (!enableList.remove(removingComp)) { 145 throw new IllegalArgumentException(component + " is not in the all list"); 146 } 147 148 PowerComponent[] enables = enableList.toArray(new PowerComponent[0]); 149 PowerComponent[] disables = {removingComp}; 150 String policyId = component + "_disable"; 151 152 return new PowerPolicyDef(policyId, enables, disables); 153 } 154 search(String[] strList, String str)155 private static boolean search(String[] strList, String str) { 156 return Arrays.stream(strList).anyMatch(s -> str.contains(s)); 157 } 158 159 public static final class IdSet { 160 public static final String DEFAULT_ALL_ON = "system_power_policy_all_on"; 161 public static final String INITIAL_ALL_ON = "system_power_policy_initiall_on"; 162 public static final String NO_USER_INTERACTION = "system_power_policy_no_user_interaction"; 163 public static final String NONE = "none"; 164 public static final String TEST1 = "test1"; 165 public static final String TEST2 = "test2"; 166 public static final String ERROR_TEST1 = "error_test1"; 167 public static final String ERROR_TEST2 = "error_test2"; 168 public static final String LISTENER_TEST = "listener_test"; 169 } 170 171 public enum PowerComponent { 172 NONE("none"), 173 UNKNOWN("UNKNOWN"), 174 AUDIO("AUDIO"), 175 MEDIA("MEDIA"), 176 DISPLAY("DISPLAY"), 177 BLUETOOTH("BLUETOOTH"), 178 WIFI("WIFI"), 179 CELLULAR("CELLULAR"), 180 ETHERNET("ETHERNET"), 181 PROJECTION("PROJECTION"), 182 NFC("NFC"), 183 INPUT("INPUT"), 184 VOICE_INTERACTION("VOICE_INTERACTION"), 185 VISUAL_INTERACTION("VISUAL_INTERACTION"), 186 TRUSTED_DEVICE_DETECTION("TRUSTED_DEVICE_DETECTION"), 187 LOCATION("LOCATION"), 188 MICROPHONE("MICROPHONE"), 189 CPU("CPU"); 190 191 private final String mValue; 192 PowerComponent(String v)193 PowerComponent(String v) { 194 mValue = v; 195 } 196 getValue()197 public String getValue() { 198 return mValue; 199 } 200 asComponentArray(String[] componentNames)201 public static PowerComponent[] asComponentArray(String[] componentNames) { 202 if (componentNames == null) { 203 return new PowerComponent[0]; 204 } 205 normalizeComponentName(componentNames); 206 PowerComponent[] compArray = Arrays.stream(componentNames).map(PowerComponent::valueOf) 207 .filter(e -> e != NONE).toArray(PowerComponent[]::new); 208 Arrays.sort(compArray); 209 return compArray; 210 } 211 asComponentArray(List<String> nameList)212 public static PowerComponent[] asComponentArray(List<String> nameList) { 213 if (nameList == null) { 214 return new PowerComponent[0]; 215 } 216 return asComponentArray(nameList.toArray(new String[0])); 217 } 218 normalizeComponentName(String[] comps)219 private static void normalizeComponentName(String[] comps) { 220 for (int i = 0; i < comps.length; i++) { 221 try { 222 PowerComponent.valueOf(comps[i]); 223 } catch (Exception e) { 224 if (comps[i] != null && comps[i].equals("none")) { 225 comps[i] = "NONE"; 226 } 227 } 228 } 229 } 230 } 231 232 private static final class ComponentList { 233 static final PowerComponent[] ALL_COMPONENTS = { 234 PowerComponent.AUDIO, 235 PowerComponent.MEDIA, 236 PowerComponent.DISPLAY, 237 PowerComponent.BLUETOOTH, 238 PowerComponent.WIFI, 239 PowerComponent.CELLULAR, 240 PowerComponent.ETHERNET, 241 PowerComponent.PROJECTION, 242 PowerComponent.NFC, 243 PowerComponent.INPUT, 244 PowerComponent.VOICE_INTERACTION, 245 PowerComponent.VISUAL_INTERACTION, 246 PowerComponent.TRUSTED_DEVICE_DETECTION, 247 PowerComponent.LOCATION, 248 PowerComponent.MICROPHONE, 249 PowerComponent.CPU 250 }; 251 252 static final PowerComponent[] INIT_ALL_ON_ENABLE = { 253 PowerComponent.AUDIO, 254 PowerComponent.DISPLAY, 255 PowerComponent.CPU 256 }; 257 258 static final PowerComponent[] INIT_ALL_ON_DISABLE = { 259 PowerComponent.MEDIA, 260 PowerComponent.BLUETOOTH, 261 PowerComponent.WIFI, 262 PowerComponent.CELLULAR, 263 PowerComponent.ETHERNET, 264 PowerComponent.PROJECTION, 265 PowerComponent.NFC, 266 PowerComponent.INPUT, 267 PowerComponent.VOICE_INTERACTION, 268 PowerComponent.VISUAL_INTERACTION, 269 PowerComponent.TRUSTED_DEVICE_DETECTION, 270 PowerComponent.LOCATION, 271 PowerComponent.MICROPHONE 272 }; 273 274 static final PowerComponent[] DEFAULT_ALL_ON_ENABLE = ALL_COMPONENTS; 275 static final PowerComponent[] DEFAULT_ALL_ON_DISABLE = {}; 276 277 static final PowerComponent[] NO_USER_INTERACT_ENABLE = { 278 PowerComponent.WIFI, 279 PowerComponent.CELLULAR, 280 PowerComponent.ETHERNET, 281 PowerComponent.TRUSTED_DEVICE_DETECTION, 282 PowerComponent.CPU 283 }; 284 285 static final PowerComponent[] NO_USER_INTERACT_DISABLE = { 286 PowerComponent.AUDIO, 287 PowerComponent.MEDIA, 288 PowerComponent.DISPLAY, 289 PowerComponent.BLUETOOTH, 290 PowerComponent.PROJECTION, 291 PowerComponent.NFC, 292 PowerComponent.INPUT, 293 PowerComponent.VOICE_INTERACTION, 294 PowerComponent.VISUAL_INTERACTION, 295 PowerComponent.LOCATION, 296 PowerComponent.MICROPHONE 297 }; 298 299 static final PowerComponent[] TEST1_ENABLE = ALL_COMPONENTS; 300 static final PowerComponent[] TEST1_DISABLE = {}; 301 302 static final PowerComponent[] TEST2_ENABLE = {}; 303 static final PowerComponent[] TEST2_DISABLE = ALL_COMPONENTS; 304 305 static final PowerComponent[] ERROR_TEST1_ENABLE = ALL_COMPONENTS; 306 static final PowerComponent[] ERROR_TEST1_DISABLE = {PowerComponent.UNKNOWN}; 307 308 static final PowerComponent[] ERROR_TEST2_ENABLE = { 309 PowerComponent.AUDIO, 310 PowerComponent.MEDIA, 311 PowerComponent.DISPLAY, 312 PowerComponent.UNKNOWN, 313 PowerComponent.WIFI, 314 PowerComponent.CELLULAR, 315 PowerComponent.ETHERNET, 316 PowerComponent.PROJECTION, 317 PowerComponent.NFC, 318 PowerComponent.INPUT, 319 PowerComponent.VOICE_INTERACTION, 320 PowerComponent.VISUAL_INTERACTION, 321 PowerComponent.TRUSTED_DEVICE_DETECTION, 322 PowerComponent.LOCATION, 323 PowerComponent.MICROPHONE, 324 PowerComponent.CPU 325 }; 326 static final PowerComponent[] ERROR_TEST2_DISABLE = {}; 327 328 static final PowerComponent[] RUNTIME_DEFAULT_ENABLE = ALL_COMPONENTS; 329 static final PowerComponent[] RUNTIME_DEFAULT_DISABLE = {}; 330 331 static final PowerComponent[] RUNTIME_SILENT_ENABLE = { 332 PowerComponent.AUDIO, 333 PowerComponent.MEDIA, 334 PowerComponent.DISPLAY, 335 PowerComponent.BLUETOOTH, 336 PowerComponent.WIFI, 337 PowerComponent.CELLULAR, 338 PowerComponent.ETHERNET, 339 PowerComponent.PROJECTION, 340 PowerComponent.NFC, 341 PowerComponent.INPUT, 342 PowerComponent.VOICE_INTERACTION, 343 PowerComponent.VISUAL_INTERACTION, 344 PowerComponent.TRUSTED_DEVICE_DETECTION, 345 PowerComponent.LOCATION, 346 PowerComponent.MICROPHONE, 347 PowerComponent.CPU 348 }; 349 static final PowerComponent[] RUNTIME_SILENT_DISABLE = {}; 350 351 static final PowerComponent[] LISTENER_TEST_ENABLE = { 352 PowerComponent.MEDIA, 353 PowerComponent.DISPLAY, 354 PowerComponent.BLUETOOTH, 355 PowerComponent.WIFI, 356 PowerComponent.CELLULAR, 357 PowerComponent.ETHERNET, 358 PowerComponent.PROJECTION, 359 PowerComponent.NFC, 360 PowerComponent.INPUT, 361 PowerComponent.VOICE_INTERACTION, 362 PowerComponent.VISUAL_INTERACTION, 363 PowerComponent.TRUSTED_DEVICE_DETECTION, 364 PowerComponent.LOCATION, 365 PowerComponent.CPU 366 }; 367 368 static final PowerComponent[] LISTENER_TEST_DISABLE = { 369 PowerComponent.AUDIO, 370 PowerComponent.MICROPHONE 371 }; 372 } 373 374 public static final class PolicySet { 375 public static final int TOTAL_DEFAULT_REGISTERED_POLICIES = 2; 376 377 public static final PowerPolicyDef 378 INITIAL_ALL_ON = new PowerPolicyDef(IdSet.INITIAL_ALL_ON, 379 ComponentList.INIT_ALL_ON_ENABLE, ComponentList.INIT_ALL_ON_DISABLE); 380 381 public static final PowerPolicyDef 382 DEFAULT_ALL_ON = new PowerPolicyDef(IdSet.DEFAULT_ALL_ON, 383 ComponentList.DEFAULT_ALL_ON_ENABLE, ComponentList.DEFAULT_ALL_ON_DISABLE); 384 385 public static final PowerPolicyDef 386 NO_USER_INTERACT = new PowerPolicyDef(IdSet.NO_USER_INTERACTION, 387 ComponentList.NO_USER_INTERACT_ENABLE, ComponentList.NO_USER_INTERACT_DISABLE); 388 389 public static final PowerPolicyDef TEST1 = new PowerPolicyDef(IdSet.TEST1, 390 ComponentList.TEST1_ENABLE, ComponentList.TEST1_DISABLE); 391 392 public static final PowerPolicyDef TEST2 = new PowerPolicyDef(IdSet.TEST2, 393 ComponentList.TEST2_ENABLE, ComponentList.TEST2_DISABLE); 394 395 public static final PowerPolicyDef ERROR_TEST1 = new PowerPolicyDef(IdSet.ERROR_TEST1, 396 ComponentList.ERROR_TEST1_ENABLE, ComponentList.ERROR_TEST1_DISABLE); 397 398 public static final PowerPolicyDef ERROR_TEST2 = new PowerPolicyDef(IdSet.ERROR_TEST2, 399 ComponentList.ERROR_TEST2_ENABLE, ComponentList.ERROR_TEST2_DISABLE); 400 401 public static final PowerPolicyDef LISTENER_TEST = new PowerPolicyDef(IdSet.LISTENER_TEST, 402 ComponentList.LISTENER_TEST_ENABLE, ComponentList.LISTENER_TEST_DISABLE); 403 } 404 405 public static final class ComponentSet { 406 public static final PowerPolicyDef RUNTIME_DEFAULT = new PowerPolicyDef(null, 407 ComponentList.RUNTIME_DEFAULT_ENABLE, ComponentList.RUNTIME_DEFAULT_DISABLE); 408 409 public static final PowerPolicyDef RUNTIME_SILENT = new PowerPolicyDef(null, 410 ComponentList.RUNTIME_SILENT_ENABLE, ComponentList.RUNTIME_SILENT_DISABLE); 411 } 412 } 413