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 package com.android.hoststubgen.filters 17 18 enum class FilterPolicy(val policyStringOrPrefix: String) { 19 /** 20 * Keep the item in the jar file. 21 */ 22 Keep("keep"), 23 24 /** 25 * Only usable with classes. Keep the class in the jar, and also all its members. 26 * Each member can have another policy to override it. 27 */ 28 KeepClass("keepclass"), 29 30 /** 31 * Only usable with methods. Replace a method with a "substitution" method. 32 */ 33 Substitute("@"), // @ is a prefix 34 35 /** 36 * Only usable with methods. Redirect a method to a method in the substitution class. 37 */ 38 Redirect("redirect"), 39 40 /** 41 * Only usable with methods. The item will be kept in the impl jar file, but when called, 42 * it'll throw. 43 */ 44 Throw("throw"), 45 46 /** 47 * Only usable with methods. The item will be kept in the impl jar file, but when called, 48 * it'll no-op. 49 */ 50 Ignore("ignore"), 51 52 /** 53 * Remove the item completely. 54 */ 55 Remove("remove"), 56 57 /** 58 * Special policy used for "partial annotation allowlisting". This policy must not be 59 * used in the "main" filter chain. (which would be detected by [SanitizationFilter].) 60 * It's used in a separate filter chain used by [AnnotationBasedFilter]. 61 */ 62 AnnotationAllowed("allow-annotation"); 63 64 val needsInOutput: Boolean 65 get() { 66 return when (this) { 67 Remove -> false 68 else -> true 69 } 70 } 71 72 /** Returns whether a policy can be used with classes */ 73 val isUsableWithClasses: Boolean 74 get() { 75 return when (this) { 76 Keep, KeepClass, Remove, AnnotationAllowed -> true 77 else -> false 78 } 79 } 80 81 /** Returns whether a policy can be used with fields. */ 82 val isUsableWithFields: Boolean 83 get() { 84 return when (this) { 85 // AnnotationAllowed isn't supported on fields (yet). We could support it if needed. 86 Keep, Remove -> true 87 else -> false 88 } 89 } 90 91 /** Returns whether a policy can be used with methods */ 92 val isUsableWithMethods: Boolean 93 get() { 94 return when (this) { 95 KeepClass -> false 96 else -> true 97 } 98 } 99 100 /** Returns whether a policy can be used as default policy. */ 101 val isUsableWithDefault: Boolean 102 get() { 103 return when (this) { 104 Keep, Throw, Remove -> true 105 else -> false 106 } 107 } 108 109 /** Returns whether a policy is considered supported. */ 110 val isSupported: Boolean 111 get() { 112 return when (this) { 113 Keep, KeepClass, Substitute, Redirect, AnnotationAllowed -> true 114 else -> false 115 } 116 } 117 118 val isMethodRewriteBody: Boolean 119 get() { 120 return when (this) { 121 Redirect, Throw, Ignore -> true 122 else -> false 123 } 124 } 125 126 val isClassWide: Boolean 127 get() { 128 return when (this) { 129 Remove, KeepClass -> true 130 else -> false 131 } 132 } 133 134 /** 135 * Internal policies must not be used in the main filter chain. 136 */ 137 val isInternalPolicy: Boolean 138 get() { 139 return when (this) { 140 AnnotationAllowed -> true 141 else -> false 142 } 143 } 144 145 /** 146 * Convert KeepClass to Keep, or return itself. 147 */ resolveClassWidePolicynull148 fun resolveClassWidePolicy(): FilterPolicy { 149 return when (this) { 150 KeepClass -> Keep 151 else -> this 152 } 153 } 154 155 /** 156 * Create a [FilterPolicyWithReason] with a given reason. 157 */ withReasonnull158 fun withReason( 159 reason: String, 160 statsLabelOverride: StatsLabel? = null, 161 ): FilterPolicyWithReason { 162 return FilterPolicyWithReason(this, reason, statsLabelOverride = statsLabelOverride) 163 } 164 } 165