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 /** 19 * Base class for "filters", which decides what APIs should go to the stub / impl jars. 20 */ 21 abstract class OutputFilter { 22 /** 23 * Filters are stacked over one another. This fields contains the "outermost" filter in a 24 * filter stack chain. 25 * 26 * Subclasses must use this filter to get a policy, when they need to infer a policy 27 * from the policy of another API. 28 * 29 * For example, [ClassWidePolicyPropagatingFilter] needs to check the policy of the enclosing 30 * class to propagate "class-wide" policies, but when it does so, it can't just use 31 * `this.getPolicyForClass()` because that wouldn't return policies decided by "outer" 32 * filters. Instead, it uses [outermostFilter.getPolicyForClass()]. 33 * 34 * Note, [outermostFilter] can be itself, so make sure not to cause infinity recursions when 35 * using it. 36 */ 37 open var outermostFilter: OutputFilter = this 38 getPolicyForClassnull39 abstract fun getPolicyForClass(className: String): FilterPolicyWithReason 40 41 abstract fun getPolicyForField(className: String, fieldName: String): FilterPolicyWithReason 42 43 abstract fun getPolicyForMethod( 44 className: String, 45 methodName: String, 46 descriptor: String, 47 ): FilterPolicyWithReason 48 49 /** 50 * If a given method is a substitute-from method, return the substitute-to method name. 51 * 52 * The substitute-to and from methods must have the same signature, in the same class. 53 */ 54 open fun getRenameTo(className: String, methodName: String, descriptor: String): String? { 55 return null 56 } 57 58 /** 59 * Return a "redirection class" name for a given class. 60 * 61 * The result will be in a JVM internal form. (e.g. uses '/'s instead of '.'s) 62 * 63 * (which corresponds to @HostSideTestRedirectClass of the standard annotations.) 64 */ getRedirectionClassnull65 open fun getRedirectionClass(className: String): String? { 66 return null 67 } 68 69 /** 70 * Return a "class load hook" class name for a given class. 71 * 72 * (which corresponds to @HostSideTestClassLoadHook of the standard annotations.) 73 */ getClassLoadHooksnull74 open fun getClassLoadHooks(className: String): List<String> { 75 return emptyList() 76 } 77 78 /** 79 * Return the "method call hook" class name. 80 * 81 * The class has to have a function with the following signature: 82 * `public static void onMethodCalled(Class<?> clazz, String name, String descriptor)`. 83 */ getMethodCallHooksnull84 open fun getMethodCallHooks(className: String, methodName: String, descriptor: String): 85 List<String> { 86 return emptyList() 87 } 88 89 /** 90 * Take a class (internal) name. If the class needs to be renamed, return the new name. 91 * This is used by [FilterRemapper]. 92 */ remapTypenull93 open fun remapType(className: String): String? { 94 return null 95 } 96 97 data class MethodReplaceTarget(val className: String, val methodName: String) 98 99 /** 100 * Return if this filter may return non-null from [getMethodCallReplaceTo]. 101 * (Used for a small optimization) 102 */ hasAnyMethodCallReplacenull103 open fun hasAnyMethodCallReplace(): Boolean { 104 return false 105 } 106 107 /** 108 * If a method call should be forwarded to another method, return the target's class / method. 109 */ getMethodCallReplaceTonull110 open fun getMethodCallReplaceTo( 111 className: String, 112 methodName: String, 113 descriptor: String, 114 ): MethodReplaceTarget? { 115 return null 116 } 117 } 118