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 get() = field 39 set(value) { 40 field = value 41 } 42 getPolicyForClassnull43 abstract fun getPolicyForClass(className: String): FilterPolicyWithReason 44 45 abstract fun getPolicyForField(className: String, fieldName: String): FilterPolicyWithReason 46 47 abstract fun getPolicyForMethod( 48 className: String, 49 methodName: String, 50 descriptor: String, 51 ): FilterPolicyWithReason 52 53 /** 54 * If a given method is a substitute-from method, return the substitute-to method name. 55 * 56 * The substitute-to and from methods must have the same signature, in the same class. 57 */ 58 open fun getRenameTo(className: String, methodName: String, descriptor: String): String? { 59 return null 60 } 61 62 /** 63 * Return a "native substitution class" name for a given class. 64 * 65 * The result will be in a "human readable" form. (e.g. uses '.'s instead of '/'s) 66 * 67 * (which corresponds to @HostSideTestNativeSubstitutionClass of the standard annotations.) 68 */ getNativeSubstitutionClassnull69 open fun getNativeSubstitutionClass(className: String): String? { 70 return null 71 } 72 73 /** 74 * Return a "class load hook" class name for a given class. 75 * 76 * (which corresponds to @HostSideTestClassLoadHook of the standard annotations.) 77 */ getClassLoadHooksnull78 open fun getClassLoadHooks(className: String): List<String> { 79 return emptyList() 80 } 81 82 /** 83 * Return the "method call hook" class name. 84 * 85 * The class has to have a function with the following signature: 86 * `public static void onMethodCalled(Class<?> clazz, String name, String descriptor)`. 87 */ getMethodCallHooksnull88 open fun getMethodCallHooks(className: String, methodName: String, descriptor: String): 89 List<String> { 90 return emptyList() 91 } 92 }