1 /*
2  * Copyright (C) 2018 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 import java.lang.reflect.InvocationTargetException;
18 
19 public class Linking {
canAccess(String className, boolean takesParameter)20   public static boolean canAccess(String className, boolean takesParameter) throws Exception {
21     try {
22       Class<?> c = Class.forName(className);
23       if (takesParameter) {
24         c.getDeclaredMethod("access", Integer.TYPE).invoke(null, 42);
25       } else {
26         c.getDeclaredMethod("access").invoke(null);
27       }
28       return true;
29     } catch (InvocationTargetException ex) {
30       if (ex.getCause() instanceof NoSuchFieldError || ex.getCause() instanceof NoSuchMethodError) {
31         return false;
32       } else {
33         throw ex;
34       }
35     }
36   }
37 }
38 
39 // INSTANCE FIELD GET
40 
41 class LinkFieldGetWhitelist {
access()42   public static int access() {
43     return new ParentClass().fieldPublicWhitelist;
44   }
45 }
46 
47 class LinkFieldGetLightGreylist {
access()48   public static int access() {
49     return new ParentClass().fieldPublicLightGreylist;
50   }
51 }
52 
53 class LinkFieldGetDarkGreylist {
access()54   public static int access() {
55     return new ParentClass().fieldPublicDarkGreylist;
56   }
57 }
58 
59 class LinkFieldGetBlacklist {
access()60   public static int access() {
61     return new ParentClass().fieldPublicBlacklist;
62   }
63 }
64 
65 class LinkFieldGetBlacklistAndCorePlatformApi {
access()66   public static int access() {
67     return new ParentClass().fieldPublicBlacklistAndCorePlatformApi;
68   }
69 }
70 
71 // INSTANCE FIELD SET
72 
73 class LinkFieldSetWhitelist {
access(int x)74   public static void access(int x) {
75     // Need to use a different field from the getter to bypass DexCache.
76     new ParentClass().fieldPublicWhitelistB = x;
77   }
78 }
79 
80 class LinkFieldSetLightGreylist {
access(int x)81   public static void access(int x) {
82     // Need to use a different field from the getter to bypass DexCache.
83     new ParentClass().fieldPublicLightGreylistB = x;
84   }
85 }
86 
87 class LinkFieldSetDarkGreylist {
access(int x)88   public static void access(int x) {
89     // Need to use a different field from the getter to bypass DexCache.
90     new ParentClass().fieldPublicDarkGreylistB = x;
91   }
92 }
93 
94 class LinkFieldSetBlacklist {
access(int x)95   public static void access(int x) {
96     // Need to use a different field from the getter to bypass DexCache.
97     new ParentClass().fieldPublicBlacklistB = x;
98   }
99 }
100 
101 class LinkFieldSetBlacklistAndCorePlatformApi {
access(int x)102   public static void access(int x) {
103     // Need to use a different field from the getter to bypass DexCache.
104     new ParentClass().fieldPublicBlacklistAndCorePlatformApiB = x;
105   }
106 }
107 
108 // STATIC FIELD GET
109 
110 class LinkFieldGetStaticWhitelist {
access()111   public static int access() {
112     return ParentClass.fieldPublicStaticWhitelist;
113   }
114 }
115 
116 class LinkFieldGetStaticLightGreylist {
access()117   public static int access() {
118     return ParentClass.fieldPublicStaticLightGreylist;
119   }
120 }
121 
122 class LinkFieldGetStaticDarkGreylist {
access()123   public static int access() {
124     return ParentClass.fieldPublicStaticDarkGreylist;
125   }
126 }
127 
128 class LinkFieldGetStaticBlacklist {
access()129   public static int access() {
130     return ParentClass.fieldPublicStaticBlacklist;
131   }
132 }
133 
134 class LinkFieldGetStaticBlacklistAndCorePlatformApi {
access()135   public static int access() {
136     return ParentClass.fieldPublicStaticBlacklistAndCorePlatformApi;
137   }
138 }
139 
140 // STATIC FIELD SET
141 
142 class LinkFieldSetStaticWhitelist {
access(int x)143   public static void access(int x) {
144     // Need to use a different field from the getter to bypass DexCache.
145     ParentClass.fieldPublicStaticWhitelistB = x;
146   }
147 }
148 
149 class LinkFieldSetStaticLightGreylist {
access(int x)150   public static void access(int x) {
151     // Need to use a different field from the getter to bypass DexCache.
152     ParentClass.fieldPublicStaticLightGreylistB = x;
153   }
154 }
155 
156 class LinkFieldSetStaticDarkGreylist {
access(int x)157   public static void access(int x) {
158     // Need to use a different field from the getter to bypass DexCache.
159     ParentClass.fieldPublicStaticDarkGreylistB = x;
160   }
161 }
162 
163 class LinkFieldSetStaticBlacklist {
access(int x)164   public static void access(int x) {
165     // Need to use a different field from the getter to bypass DexCache.
166     ParentClass.fieldPublicStaticBlacklistB = x;
167   }
168 }
169 
170 class LinkFieldSetStaticBlacklistAndCorePlatformApi {
access(int x)171   public static void access(int x) {
172     // Need to use a different field from the getter to bypass DexCache.
173     ParentClass.fieldPublicStaticBlacklistAndCorePlatformApiB = x;
174   }
175 }
176 
177 // INVOKE INSTANCE METHOD
178 
179 class LinkMethodWhitelist {
access()180   public static int access() {
181     return new ParentClass().methodPublicWhitelist();
182   }
183 }
184 
185 class LinkMethodLightGreylist {
access()186   public static int access() {
187     return new ParentClass().methodPublicLightGreylist();
188   }
189 }
190 
191 class LinkMethodDarkGreylist {
access()192   public static int access() {
193     return new ParentClass().methodPublicDarkGreylist();
194   }
195 }
196 
197 class LinkMethodBlacklist {
access()198   public static int access() {
199     return new ParentClass().methodPublicBlacklist();
200   }
201 }
202 
203 class LinkMethodBlacklistAndCorePlatformApi {
access()204   public static int access() {
205     return new ParentClass().methodPublicBlacklistAndCorePlatformApi();
206   }
207 }
208 
209 // INVOKE INSTANCE INTERFACE METHOD
210 
211 class LinkMethodInterfaceWhitelist {
access()212   public static int access() {
213     return DummyClass.getInterfaceInstance().methodPublicWhitelist();
214   }
215 }
216 
217 class LinkMethodInterfaceLightGreylist {
access()218   public static int access() {
219     return DummyClass.getInterfaceInstance().methodPublicLightGreylist();
220   }
221 }
222 
223 class LinkMethodInterfaceDarkGreylist {
access()224   public static int access() {
225     return DummyClass.getInterfaceInstance().methodPublicDarkGreylist();
226   }
227 }
228 
229 class LinkMethodInterfaceBlacklist {
access()230   public static int access() {
231     return DummyClass.getInterfaceInstance().methodPublicBlacklist();
232   }
233 }
234 
235 class LinkMethodInterfaceBlacklistAndCorePlatformApi {
access()236   public static int access() {
237     return DummyClass.getInterfaceInstance().methodPublicBlacklistAndCorePlatformApi();
238   }
239 }
240 
241 // INVOKE STATIC METHOD
242 
243 class LinkMethodStaticWhitelist {
access()244   public static int access() {
245     return ParentClass.methodPublicStaticWhitelist();
246   }
247 }
248 
249 class LinkMethodStaticLightGreylist {
access()250   public static int access() {
251     return ParentClass.methodPublicStaticLightGreylist();
252   }
253 }
254 
255 class LinkMethodStaticDarkGreylist {
access()256   public static int access() {
257     return ParentClass.methodPublicStaticDarkGreylist();
258   }
259 }
260 
261 class LinkMethodStaticBlacklist {
access()262   public static int access() {
263     return ParentClass.methodPublicStaticBlacklist();
264   }
265 }
266 
267 class LinkMethodStaticBlacklistAndCorePlatformApi {
access()268   public static int access() {
269     return ParentClass.methodPublicStaticBlacklistAndCorePlatformApi();
270   }
271 }
272 
273 // INVOKE INTERFACE STATIC METHOD
274 
275 class LinkMethodInterfaceStaticWhitelist {
access()276   public static int access() {
277     return ParentInterface.methodPublicStaticWhitelist();
278   }
279 }
280 
281 class LinkMethodInterfaceStaticLightGreylist {
access()282   public static int access() {
283     return ParentInterface.methodPublicStaticLightGreylist();
284   }
285 }
286 
287 class LinkMethodInterfaceStaticDarkGreylist {
access()288   public static int access() {
289     return ParentInterface.methodPublicStaticDarkGreylist();
290   }
291 }
292 
293 class LinkMethodInterfaceStaticBlacklist {
access()294   public static int access() {
295     return ParentInterface.methodPublicStaticBlacklist();
296   }
297 }
298 
299 class LinkMethodInterfaceStaticBlacklistAndCorePlatformApi {
access()300   public static int access() {
301     return ParentInterface.methodPublicStaticBlacklistAndCorePlatformApi();
302   }
303 }
304