1 /* 2 * Copyright (C) 2023 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.platform.test.flag.util; 18 19 import com.google.auto.value.AutoValue; 20 21 import javax.annotation.Nullable; 22 23 /** 24 * Contains the information of a flag. 25 * 26 * <p>There are two types of flags: 27 * <li>Legacy flags: the format is {namespace}/{flagName}. For these flags, packageName and 28 * flagsClassName will be null, and both fullFlagName and simpleFlagName will be the flagName. 29 * <li>AConfig flags: the format is {packageName}.{simpleFlagName}. For these flags, namespace will 30 * be null, fullFlagName will be {packageName}.{simpleFlagName}, and flagsClassName will be 31 * {packageName}.Flags. 32 */ 33 @AutoValue 34 public abstract class Flag { 35 public static final String NAMESPACE_FLAG_SEPARATOR = "/"; 36 37 /** The format of flag with namespace is {namespace}/{flagName}. */ 38 public static final String FLAG_WITH_NAMESPACE_FORMAT = "%s/%s"; 39 40 /** The format of aconfig full flag name is {packageName}.{simpleFlagName}. */ 41 public static final String ACONFIG_FULL_FLAG_FORMAT = "%s.%s"; 42 43 private static final String PACKAGE_NAME_SIMPLE_NAME_SEPARATOR = "."; 44 private static final String FLAGS_CLASS_FORMAT = "%s.Flags"; 45 46 /** 47 * The possible prefix when flag repackaging is happened on the class. TODO(b/324009565): Remove 48 * this prefix when the long term solution is ready. 49 */ 50 private static final String REPACKAGE_PREFIX = "com.android.internal.hidden_from_bootclasspath"; 51 createFlag(String flag)52 public static Flag createFlag(String flag) { 53 String namespace = null; 54 String fullFlagName = null; 55 String packageName = null; 56 String simpleFlagName = null; 57 if (flag.contains(NAMESPACE_FLAG_SEPARATOR)) { 58 String[] flagSplits = flag.split(NAMESPACE_FLAG_SEPARATOR, /* limit= */ 2); 59 namespace = flagSplits[0]; 60 fullFlagName = flagSplits[1]; 61 simpleFlagName = fullFlagName; 62 } else { 63 fullFlagName = flag; 64 if (!fullFlagName.contains(PACKAGE_NAME_SIMPLE_NAME_SEPARATOR)) { 65 throw new IllegalArgumentException( 66 String.format( 67 "Flag %s is invalid. The format should be {packageName}" 68 + ".{simpleFlagName}", 69 flag)); 70 } 71 int index = fullFlagName.lastIndexOf(PACKAGE_NAME_SIMPLE_NAME_SEPARATOR); 72 packageName = fullFlagName.substring(0, index); 73 simpleFlagName = fullFlagName.substring(index + 1); 74 } 75 76 return new AutoValue_Flag(namespace, fullFlagName, packageName, simpleFlagName); 77 } 78 79 @Nullable namespace()80 public abstract String namespace(); 81 fullFlagName()82 public abstract String fullFlagName(); 83 84 @Nullable packageName()85 public abstract String packageName(); 86 simpleFlagName()87 public abstract String simpleFlagName(); 88 89 @Nullable flagsClassName()90 public String flagsClassName() { 91 return flagsClassPackageName() == null 92 ? null 93 : String.format(FLAGS_CLASS_FORMAT, flagsClassPackageName()); 94 } 95 96 /** 97 * The real package name of the Flags class. May be different to the packageName when 98 * repackaging is applied. 99 */ 100 @Nullable flagsClassPackageName()101 public String flagsClassPackageName() { 102 String packageName = packageName(); 103 if (packageName == null) { 104 return null; 105 } 106 107 try { 108 Class.forName( 109 String.format(FLAGS_CLASS_FORMAT, packageName), 110 false, 111 this.getClass().getClassLoader()); 112 return packageName; 113 } catch (ClassNotFoundException e) { 114 return String.format("%s.%s", REPACKAGE_PREFIX, packageName); 115 } 116 } 117 } 118