• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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