xref: /aosp_15_r20/art/test/674-hiddenapi/src-ex/ChildClass.java (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2017 The Android Open Source Project
3*795d594fSAndroid Build Coastguard Worker  *
4*795d594fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*795d594fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*795d594fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*795d594fSAndroid Build Coastguard Worker  *
8*795d594fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*795d594fSAndroid Build Coastguard Worker  *
10*795d594fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*795d594fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*795d594fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*795d594fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*795d594fSAndroid Build Coastguard Worker  * limitations under the License.
15*795d594fSAndroid Build Coastguard Worker  */
16*795d594fSAndroid Build Coastguard Worker 
17*795d594fSAndroid Build Coastguard Worker import dalvik.system.VMRuntime;
18*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.MethodHandles;
19*795d594fSAndroid Build Coastguard Worker import java.lang.invoke.MethodType;
20*795d594fSAndroid Build Coastguard Worker import java.util.function.Consumer;
21*795d594fSAndroid Build Coastguard Worker 
22*795d594fSAndroid Build Coastguard Worker public class ChildClass {
23*795d594fSAndroid Build Coastguard Worker   enum PrimitiveType {
24*795d594fSAndroid Build Coastguard Worker     TInteger('I', Integer.TYPE, Integer.valueOf(0)),
25*795d594fSAndroid Build Coastguard Worker     TLong('J', Long.TYPE, Long.valueOf(0)),
26*795d594fSAndroid Build Coastguard Worker     TFloat('F', Float.TYPE, Float.valueOf(0)),
27*795d594fSAndroid Build Coastguard Worker     TDouble('D', Double.TYPE, Double.valueOf(0)),
28*795d594fSAndroid Build Coastguard Worker     TBoolean('Z', Boolean.TYPE, Boolean.valueOf(false)),
29*795d594fSAndroid Build Coastguard Worker     TByte('B', Byte.TYPE, Byte.valueOf((byte) 0)),
30*795d594fSAndroid Build Coastguard Worker     TShort('S', Short.TYPE, Short.valueOf((short) 0)),
31*795d594fSAndroid Build Coastguard Worker     TCharacter('C', Character.TYPE, Character.valueOf('0'));
32*795d594fSAndroid Build Coastguard Worker 
PrimitiveType(char shorty, Class klass, Object value)33*795d594fSAndroid Build Coastguard Worker     PrimitiveType(char shorty, Class klass, Object value) {
34*795d594fSAndroid Build Coastguard Worker       mShorty = shorty;
35*795d594fSAndroid Build Coastguard Worker       mClass = klass;
36*795d594fSAndroid Build Coastguard Worker       mDefaultValue = value;
37*795d594fSAndroid Build Coastguard Worker     }
38*795d594fSAndroid Build Coastguard Worker 
39*795d594fSAndroid Build Coastguard Worker     public char mShorty;
40*795d594fSAndroid Build Coastguard Worker     public Class mClass;
41*795d594fSAndroid Build Coastguard Worker     public Object mDefaultValue;
42*795d594fSAndroid Build Coastguard Worker   }
43*795d594fSAndroid Build Coastguard Worker 
44*795d594fSAndroid Build Coastguard Worker   enum Hiddenness {
45*795d594fSAndroid Build Coastguard Worker     Sdk(PrimitiveType.TShort),
46*795d594fSAndroid Build Coastguard Worker     Unsupported(PrimitiveType.TBoolean),
47*795d594fSAndroid Build Coastguard Worker     ConditionallyBlocked(PrimitiveType.TByte),
48*795d594fSAndroid Build Coastguard Worker     Blocklist(PrimitiveType.TCharacter),
49*795d594fSAndroid Build Coastguard Worker     BlocklistAndCorePlatformApi(PrimitiveType.TInteger);
50*795d594fSAndroid Build Coastguard Worker 
Hiddenness(PrimitiveType type)51*795d594fSAndroid Build Coastguard Worker     Hiddenness(PrimitiveType type) { mAssociatedType = type; }
52*795d594fSAndroid Build Coastguard Worker     public PrimitiveType mAssociatedType;
53*795d594fSAndroid Build Coastguard Worker   }
54*795d594fSAndroid Build Coastguard Worker 
55*795d594fSAndroid Build Coastguard Worker   enum Visibility {
56*795d594fSAndroid Build Coastguard Worker     Public(PrimitiveType.TInteger),
57*795d594fSAndroid Build Coastguard Worker     Package(PrimitiveType.TFloat),
58*795d594fSAndroid Build Coastguard Worker     Protected(PrimitiveType.TLong),
59*795d594fSAndroid Build Coastguard Worker     Private(PrimitiveType.TDouble);
60*795d594fSAndroid Build Coastguard Worker 
Visibility(PrimitiveType type)61*795d594fSAndroid Build Coastguard Worker     Visibility(PrimitiveType type) { mAssociatedType = type; }
62*795d594fSAndroid Build Coastguard Worker     public PrimitiveType mAssociatedType;
63*795d594fSAndroid Build Coastguard Worker   }
64*795d594fSAndroid Build Coastguard Worker 
65*795d594fSAndroid Build Coastguard Worker   enum Behaviour {
66*795d594fSAndroid Build Coastguard Worker     Granted,
67*795d594fSAndroid Build Coastguard Worker     Warning,
68*795d594fSAndroid Build Coastguard Worker     Denied,
69*795d594fSAndroid Build Coastguard Worker   }
70*795d594fSAndroid Build Coastguard Worker 
71*795d594fSAndroid Build Coastguard Worker   // This needs to be kept in sync with DexDomain in Main.
72*795d594fSAndroid Build Coastguard Worker   enum DexDomain {
73*795d594fSAndroid Build Coastguard Worker     CorePlatform,
74*795d594fSAndroid Build Coastguard Worker     Platform,
75*795d594fSAndroid Build Coastguard Worker     Application
76*795d594fSAndroid Build Coastguard Worker   }
77*795d594fSAndroid Build Coastguard Worker 
78*795d594fSAndroid Build Coastguard Worker   private static final boolean booleanValues[] = new boolean[] { false, true };
79*795d594fSAndroid Build Coastguard Worker 
runTest(String libFileName, int parentDomainOrdinal, int childDomainOrdinal, boolean everythingSdked)80*795d594fSAndroid Build Coastguard Worker   public static void runTest(String libFileName, int parentDomainOrdinal,
81*795d594fSAndroid Build Coastguard Worker       int childDomainOrdinal, boolean everythingSdked) throws Exception {
82*795d594fSAndroid Build Coastguard Worker     System.load(libFileName);
83*795d594fSAndroid Build Coastguard Worker 
84*795d594fSAndroid Build Coastguard Worker     parentDomain = DexDomain.values()[parentDomainOrdinal];
85*795d594fSAndroid Build Coastguard Worker     childDomain = DexDomain.values()[childDomainOrdinal];
86*795d594fSAndroid Build Coastguard Worker 
87*795d594fSAndroid Build Coastguard Worker     configMessage = "parentDomain=" + parentDomain.name() + ", childDomain=" + childDomain.name()
88*795d594fSAndroid Build Coastguard Worker         + ", everythingSdked=" + everythingSdked;
89*795d594fSAndroid Build Coastguard Worker 
90*795d594fSAndroid Build Coastguard Worker     // Check expectations about loading into boot class path.
91*795d594fSAndroid Build Coastguard Worker     boolean isParentInBoot = (ParentClass.class.getClassLoader().getParent() == null);
92*795d594fSAndroid Build Coastguard Worker     boolean expectedParentInBoot = (parentDomain != DexDomain.Application);
93*795d594fSAndroid Build Coastguard Worker     if (isParentInBoot != expectedParentInBoot) {
94*795d594fSAndroid Build Coastguard Worker       throw new RuntimeException("Expected ParentClass " +
95*795d594fSAndroid Build Coastguard Worker                                  (expectedParentInBoot ? "" : "not ") + "in boot class path");
96*795d594fSAndroid Build Coastguard Worker     }
97*795d594fSAndroid Build Coastguard Worker     boolean isChildInBoot = (ChildClass.class.getClassLoader().getParent() == null);
98*795d594fSAndroid Build Coastguard Worker     boolean expectedChildInBoot = (childDomain != DexDomain.Application);
99*795d594fSAndroid Build Coastguard Worker     if (isChildInBoot != expectedChildInBoot) {
100*795d594fSAndroid Build Coastguard Worker       throw new RuntimeException("Expected ChildClass " + (expectedChildInBoot ? "" : "not ") +
101*795d594fSAndroid Build Coastguard Worker                                  "in boot class path");
102*795d594fSAndroid Build Coastguard Worker     }
103*795d594fSAndroid Build Coastguard Worker     ChildClass.everythingSdked = everythingSdked;
104*795d594fSAndroid Build Coastguard Worker 
105*795d594fSAndroid Build Coastguard Worker     boolean isSameBoot = (isParentInBoot == isChildInBoot);
106*795d594fSAndroid Build Coastguard Worker 
107*795d594fSAndroid Build Coastguard Worker     // For compat reasons, meta-reflection should still be usable by apps if hidden api check
108*795d594fSAndroid Build Coastguard Worker     // hardening is disabled (i.e. target SDK is Q or earlier). The only configuration where this
109*795d594fSAndroid Build Coastguard Worker     // workaround used to work is for ChildClass in the Application domain and ParentClass in the
110*795d594fSAndroid Build Coastguard Worker     // Platform domain, so only test that configuration with hidden api check hardening disabled.
111*795d594fSAndroid Build Coastguard Worker     boolean testHiddenApiCheckHardeningDisabled =
112*795d594fSAndroid Build Coastguard Worker         (childDomain == DexDomain.Application) && (parentDomain == DexDomain.Platform);
113*795d594fSAndroid Build Coastguard Worker 
114*795d594fSAndroid Build Coastguard Worker     // Run meaningful combinations of access flags.
115*795d594fSAndroid Build Coastguard Worker     for (Hiddenness hiddenness : Hiddenness.values()) {
116*795d594fSAndroid Build Coastguard Worker       final Behaviour expected;
117*795d594fSAndroid Build Coastguard Worker       final boolean invokesMemberCallback;
118*795d594fSAndroid Build Coastguard Worker       // Warnings are now disabled whenever access is granted, even for
119*795d594fSAndroid Build Coastguard Worker       // greylisted APIs. This is the behaviour for release builds.
120*795d594fSAndroid Build Coastguard Worker       if (everythingSdked || hiddenness == Hiddenness.Sdk) {
121*795d594fSAndroid Build Coastguard Worker         expected = Behaviour.Granted;
122*795d594fSAndroid Build Coastguard Worker         invokesMemberCallback = false;
123*795d594fSAndroid Build Coastguard Worker       } else if (parentDomain == DexDomain.CorePlatform && childDomain == DexDomain.Platform) {
124*795d594fSAndroid Build Coastguard Worker         expected = (hiddenness == Hiddenness.BlocklistAndCorePlatformApi)
125*795d594fSAndroid Build Coastguard Worker             ? Behaviour.Granted : Behaviour.Denied;
126*795d594fSAndroid Build Coastguard Worker         invokesMemberCallback = false;
127*795d594fSAndroid Build Coastguard Worker       } else if (isSameBoot) {
128*795d594fSAndroid Build Coastguard Worker         expected = Behaviour.Granted;
129*795d594fSAndroid Build Coastguard Worker         invokesMemberCallback = false;
130*795d594fSAndroid Build Coastguard Worker       } else if (hiddenness == Hiddenness.Blocklist ||
131*795d594fSAndroid Build Coastguard Worker                  hiddenness == Hiddenness.BlocklistAndCorePlatformApi) {
132*795d594fSAndroid Build Coastguard Worker         expected = Behaviour.Denied;
133*795d594fSAndroid Build Coastguard Worker         invokesMemberCallback = true;
134*795d594fSAndroid Build Coastguard Worker       } else {
135*795d594fSAndroid Build Coastguard Worker         expected = Behaviour.Warning;
136*795d594fSAndroid Build Coastguard Worker         invokesMemberCallback = true;
137*795d594fSAndroid Build Coastguard Worker       }
138*795d594fSAndroid Build Coastguard Worker 
139*795d594fSAndroid Build Coastguard Worker       for (boolean isStatic : booleanValues) {
140*795d594fSAndroid Build Coastguard Worker         String suffix = (isStatic ? "Static" : "") + hiddenness.name();
141*795d594fSAndroid Build Coastguard Worker 
142*795d594fSAndroid Build Coastguard Worker         for (Visibility visibility : Visibility.values()) {
143*795d594fSAndroid Build Coastguard Worker           // Test reflection and JNI on methods and fields
144*795d594fSAndroid Build Coastguard Worker           for (Class klass : new Class<?>[] { ParentClass.class, ParentInterface.class }) {
145*795d594fSAndroid Build Coastguard Worker             String baseName = visibility.name() + suffix;
146*795d594fSAndroid Build Coastguard Worker             checkField(klass, "field" + baseName, isStatic, visibility, expected,
147*795d594fSAndroid Build Coastguard Worker                 invokesMemberCallback, testHiddenApiCheckHardeningDisabled);
148*795d594fSAndroid Build Coastguard Worker             checkMethod(klass, "method" + baseName, isStatic, visibility, expected,
149*795d594fSAndroid Build Coastguard Worker                 invokesMemberCallback, testHiddenApiCheckHardeningDisabled);
150*795d594fSAndroid Build Coastguard Worker           }
151*795d594fSAndroid Build Coastguard Worker 
152*795d594fSAndroid Build Coastguard Worker           // Check whether one can use a class constructor.
153*795d594fSAndroid Build Coastguard Worker           checkConstructor(ParentClass.class, visibility, hiddenness, expected,
154*795d594fSAndroid Build Coastguard Worker                 testHiddenApiCheckHardeningDisabled);
155*795d594fSAndroid Build Coastguard Worker 
156*795d594fSAndroid Build Coastguard Worker           // Check whether one can use an interface default method.
157*795d594fSAndroid Build Coastguard Worker           String name = "method" + visibility.name() + "Default" + hiddenness.name();
158*795d594fSAndroid Build Coastguard Worker           checkMethod(ParentInterface.class, name, /*isStatic*/ false, visibility, expected,
159*795d594fSAndroid Build Coastguard Worker               invokesMemberCallback, testHiddenApiCheckHardeningDisabled);
160*795d594fSAndroid Build Coastguard Worker         }
161*795d594fSAndroid Build Coastguard Worker 
162*795d594fSAndroid Build Coastguard Worker         // Test whether static linking succeeds.
163*795d594fSAndroid Build Coastguard Worker         checkLinking("LinkFieldGet" + suffix, /*takesParameter*/ false, expected);
164*795d594fSAndroid Build Coastguard Worker         checkLinking("LinkFieldSet" + suffix, /*takesParameter*/ true, expected);
165*795d594fSAndroid Build Coastguard Worker         checkLinking("LinkMethod" + suffix, /*takesParameter*/ false, expected);
166*795d594fSAndroid Build Coastguard Worker         checkLinking("LinkMethodInterface" + suffix, /*takesParameter*/ false, expected);
167*795d594fSAndroid Build Coastguard Worker       }
168*795d594fSAndroid Build Coastguard Worker 
169*795d594fSAndroid Build Coastguard Worker       // Check whether Class.newInstance succeeds.
170*795d594fSAndroid Build Coastguard Worker       checkNullaryConstructor(Class.forName("NullaryConstructor" + hiddenness.name()), expected);
171*795d594fSAndroid Build Coastguard Worker     }
172*795d594fSAndroid Build Coastguard Worker   }
173*795d594fSAndroid Build Coastguard Worker 
174*795d594fSAndroid Build Coastguard Worker   static final class RecordingConsumer implements Consumer<String> {
175*795d594fSAndroid Build Coastguard Worker       public String recordedValue = null;
176*795d594fSAndroid Build Coastguard Worker 
177*795d594fSAndroid Build Coastguard Worker       @Override
accept(String value)178*795d594fSAndroid Build Coastguard Worker       public void accept(String value) {
179*795d594fSAndroid Build Coastguard Worker           recordedValue = value;
180*795d594fSAndroid Build Coastguard Worker       }
181*795d594fSAndroid Build Coastguard Worker   }
182*795d594fSAndroid Build Coastguard Worker 
checkMemberCallback(Class<?> klass, String name, boolean isPublic, boolean isField, boolean expectedCallback)183*795d594fSAndroid Build Coastguard Worker   private static void checkMemberCallback(Class<?> klass, String name,
184*795d594fSAndroid Build Coastguard Worker           boolean isPublic, boolean isField, boolean expectedCallback) {
185*795d594fSAndroid Build Coastguard Worker       try {
186*795d594fSAndroid Build Coastguard Worker           RecordingConsumer consumer = new RecordingConsumer();
187*795d594fSAndroid Build Coastguard Worker           VMRuntime.setNonSdkApiUsageConsumer(consumer);
188*795d594fSAndroid Build Coastguard Worker           try {
189*795d594fSAndroid Build Coastguard Worker               if (isPublic) {
190*795d594fSAndroid Build Coastguard Worker                   if (isField) {
191*795d594fSAndroid Build Coastguard Worker                       klass.getField(name);
192*795d594fSAndroid Build Coastguard Worker                   } else {
193*795d594fSAndroid Build Coastguard Worker                       klass.getMethod(name);
194*795d594fSAndroid Build Coastguard Worker                   }
195*795d594fSAndroid Build Coastguard Worker               } else {
196*795d594fSAndroid Build Coastguard Worker                   if (isField) {
197*795d594fSAndroid Build Coastguard Worker                       klass.getDeclaredField(name);
198*795d594fSAndroid Build Coastguard Worker                   } else {
199*795d594fSAndroid Build Coastguard Worker                       klass.getDeclaredMethod(name);
200*795d594fSAndroid Build Coastguard Worker                   }
201*795d594fSAndroid Build Coastguard Worker               }
202*795d594fSAndroid Build Coastguard Worker           } catch (NoSuchFieldException|NoSuchMethodException ignored) {
203*795d594fSAndroid Build Coastguard Worker               // We're not concerned whether an exception is thrown or not - we're
204*795d594fSAndroid Build Coastguard Worker               // only interested in whether the callback is invoked.
205*795d594fSAndroid Build Coastguard Worker           }
206*795d594fSAndroid Build Coastguard Worker 
207*795d594fSAndroid Build Coastguard Worker           boolean actualCallback = consumer.recordedValue != null &&
208*795d594fSAndroid Build Coastguard Worker                           consumer.recordedValue.contains(name);
209*795d594fSAndroid Build Coastguard Worker           if (expectedCallback != actualCallback) {
210*795d594fSAndroid Build Coastguard Worker               if (expectedCallback) {
211*795d594fSAndroid Build Coastguard Worker                 throw new RuntimeException("Expected callback for member: " + name);
212*795d594fSAndroid Build Coastguard Worker               } else {
213*795d594fSAndroid Build Coastguard Worker                 throw new RuntimeException("Did not expect callback for member: " + name);
214*795d594fSAndroid Build Coastguard Worker               }
215*795d594fSAndroid Build Coastguard Worker           }
216*795d594fSAndroid Build Coastguard Worker       } finally {
217*795d594fSAndroid Build Coastguard Worker           VMRuntime.setNonSdkApiUsageConsumer(null);
218*795d594fSAndroid Build Coastguard Worker       }
219*795d594fSAndroid Build Coastguard Worker   }
220*795d594fSAndroid Build Coastguard Worker 
checkField(Class<?> klass, String name, boolean isStatic, Visibility visibility, Behaviour behaviour, boolean invokesMemberCallback, boolean testHiddenApiCheckHardeningDisabled)221*795d594fSAndroid Build Coastguard Worker   private static void checkField(Class<?> klass, String name, boolean isStatic,
222*795d594fSAndroid Build Coastguard Worker       Visibility visibility, Behaviour behaviour, boolean invokesMemberCallback,
223*795d594fSAndroid Build Coastguard Worker       boolean testHiddenApiCheckHardeningDisabled) throws Exception {
224*795d594fSAndroid Build Coastguard Worker 
225*795d594fSAndroid Build Coastguard Worker     boolean isPublic = (visibility == Visibility.Public);
226*795d594fSAndroid Build Coastguard Worker     boolean canDiscover = (behaviour != Behaviour.Denied);
227*795d594fSAndroid Build Coastguard Worker 
228*795d594fSAndroid Build Coastguard Worker     if (klass.isInterface() && (!isStatic || !isPublic)) {
229*795d594fSAndroid Build Coastguard Worker       // Interfaces only have public static fields.
230*795d594fSAndroid Build Coastguard Worker       return;
231*795d594fSAndroid Build Coastguard Worker     }
232*795d594fSAndroid Build Coastguard Worker 
233*795d594fSAndroid Build Coastguard Worker     // Test discovery with reflection.
234*795d594fSAndroid Build Coastguard Worker 
235*795d594fSAndroid Build Coastguard Worker     if (Reflection.canDiscoverWithGetDeclaredField(klass, name) != canDiscover) {
236*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, true, "getDeclaredField()", canDiscover);
237*795d594fSAndroid Build Coastguard Worker     }
238*795d594fSAndroid Build Coastguard Worker 
239*795d594fSAndroid Build Coastguard Worker     if (Reflection.canDiscoverWithGetDeclaredFields(klass, name) != canDiscover) {
240*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, true, "getDeclaredFields()", canDiscover);
241*795d594fSAndroid Build Coastguard Worker     }
242*795d594fSAndroid Build Coastguard Worker 
243*795d594fSAndroid Build Coastguard Worker     if (Reflection.canDiscoverWithGetField(klass, name) != (canDiscover && isPublic)) {
244*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, true, "getField()", (canDiscover && isPublic));
245*795d594fSAndroid Build Coastguard Worker     }
246*795d594fSAndroid Build Coastguard Worker 
247*795d594fSAndroid Build Coastguard Worker     if (Reflection.canDiscoverWithGetFields(klass, name) != (canDiscover && isPublic)) {
248*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, true, "getFields()", (canDiscover && isPublic));
249*795d594fSAndroid Build Coastguard Worker     }
250*795d594fSAndroid Build Coastguard Worker 
251*795d594fSAndroid Build Coastguard Worker     // Test discovery with JNI.
252*795d594fSAndroid Build Coastguard Worker 
253*795d594fSAndroid Build Coastguard Worker     if (JNI.canDiscoverField(klass, name, isStatic) != canDiscover) {
254*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, true, "JNI", canDiscover);
255*795d594fSAndroid Build Coastguard Worker     }
256*795d594fSAndroid Build Coastguard Worker 
257*795d594fSAndroid Build Coastguard Worker     // Test discovery with MethodHandles.lookup() which is caller
258*795d594fSAndroid Build Coastguard Worker     // context sensitive.
259*795d594fSAndroid Build Coastguard Worker 
260*795d594fSAndroid Build Coastguard Worker     final MethodHandles.Lookup lookup = MethodHandles.lookup();
261*795d594fSAndroid Build Coastguard Worker     if (JLI.canDiscoverWithLookupFindGetter(lookup, klass, name, int.class)
262*795d594fSAndroid Build Coastguard Worker         != canDiscover) {
263*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, true, "MethodHandles.lookup().findGetter()",
264*795d594fSAndroid Build Coastguard Worker                               canDiscover);
265*795d594fSAndroid Build Coastguard Worker     }
266*795d594fSAndroid Build Coastguard Worker     if (JLI.canDiscoverWithLookupFindStaticGetter(lookup, klass, name, int.class)
267*795d594fSAndroid Build Coastguard Worker         != canDiscover) {
268*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, true, "MethodHandles.lookup().findStaticGetter()",
269*795d594fSAndroid Build Coastguard Worker                               canDiscover);
270*795d594fSAndroid Build Coastguard Worker     }
271*795d594fSAndroid Build Coastguard Worker 
272*795d594fSAndroid Build Coastguard Worker     // Test discovery with MethodHandles.publicLookup() which can only
273*795d594fSAndroid Build Coastguard Worker     // see public fields. Looking up setters here and fields in
274*795d594fSAndroid Build Coastguard Worker     // interfaces are implicitly final.
275*795d594fSAndroid Build Coastguard Worker 
276*795d594fSAndroid Build Coastguard Worker     final MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
277*795d594fSAndroid Build Coastguard Worker     if (JLI.canDiscoverWithLookupFindSetter(publicLookup, klass, name, int.class)
278*795d594fSAndroid Build Coastguard Worker         != canDiscover) {
279*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, true, "MethodHandles.publicLookup().findSetter()",
280*795d594fSAndroid Build Coastguard Worker                               canDiscover);
281*795d594fSAndroid Build Coastguard Worker     }
282*795d594fSAndroid Build Coastguard Worker     if (JLI.canDiscoverWithLookupFindStaticSetter(publicLookup, klass, name, int.class)
283*795d594fSAndroid Build Coastguard Worker         != canDiscover) {
284*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, true, "MethodHandles.publicLookup().findStaticSetter()",
285*795d594fSAndroid Build Coastguard Worker                               canDiscover);
286*795d594fSAndroid Build Coastguard Worker     }
287*795d594fSAndroid Build Coastguard Worker 
288*795d594fSAndroid Build Coastguard Worker     // Check for meta reflection.
289*795d594fSAndroid Build Coastguard Worker 
290*795d594fSAndroid Build Coastguard Worker     // With hidden api check hardening enabled, only white and light greylisted fields should be
291*795d594fSAndroid Build Coastguard Worker     // discoverable.
292*795d594fSAndroid Build Coastguard Worker     if (Reflection.canDiscoverFieldWithMetaReflection(klass, name, true) != canDiscover) {
293*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, false,
294*795d594fSAndroid Build Coastguard Worker           "Meta reflection with hidden api hardening enabled", canDiscover);
295*795d594fSAndroid Build Coastguard Worker     }
296*795d594fSAndroid Build Coastguard Worker 
297*795d594fSAndroid Build Coastguard Worker     if (testHiddenApiCheckHardeningDisabled) {
298*795d594fSAndroid Build Coastguard Worker       // With hidden api check hardening disabled, all fields should be discoverable.
299*795d594fSAndroid Build Coastguard Worker       if (Reflection.canDiscoverFieldWithMetaReflection(klass, name, false) != true) {
300*795d594fSAndroid Build Coastguard Worker         throwDiscoveryException(klass, name, false,
301*795d594fSAndroid Build Coastguard Worker             "Meta reflection with hidden api hardening enabled", canDiscover);
302*795d594fSAndroid Build Coastguard Worker       }
303*795d594fSAndroid Build Coastguard Worker     }
304*795d594fSAndroid Build Coastguard Worker 
305*795d594fSAndroid Build Coastguard Worker     if (canDiscover) {
306*795d594fSAndroid Build Coastguard Worker       // Test that modifiers are unaffected.
307*795d594fSAndroid Build Coastguard Worker 
308*795d594fSAndroid Build Coastguard Worker       if (Reflection.canObserveFieldHiddenAccessFlags(klass, name)) {
309*795d594fSAndroid Build Coastguard Worker         throwModifiersException(klass, name, true);
310*795d594fSAndroid Build Coastguard Worker       }
311*795d594fSAndroid Build Coastguard Worker 
312*795d594fSAndroid Build Coastguard Worker       // Test getters and setters when meaningful.
313*795d594fSAndroid Build Coastguard Worker 
314*795d594fSAndroid Build Coastguard Worker       if (!Reflection.canGetField(klass, name)) {
315*795d594fSAndroid Build Coastguard Worker         throwAccessException(klass, name, true, "Field.getInt()");
316*795d594fSAndroid Build Coastguard Worker       }
317*795d594fSAndroid Build Coastguard Worker       if (!Reflection.canSetField(klass, name)) {
318*795d594fSAndroid Build Coastguard Worker         throwAccessException(klass, name, true, "Field.setInt()");
319*795d594fSAndroid Build Coastguard Worker       }
320*795d594fSAndroid Build Coastguard Worker       if (!JNI.canGetField(klass, name, isStatic)) {
321*795d594fSAndroid Build Coastguard Worker         throwAccessException(klass, name, true, "getIntField");
322*795d594fSAndroid Build Coastguard Worker       }
323*795d594fSAndroid Build Coastguard Worker       if (!JNI.canSetField(klass, name, isStatic)) {
324*795d594fSAndroid Build Coastguard Worker         throwAccessException(klass, name, true, "setIntField");
325*795d594fSAndroid Build Coastguard Worker       }
326*795d594fSAndroid Build Coastguard Worker     }
327*795d594fSAndroid Build Coastguard Worker 
328*795d594fSAndroid Build Coastguard Worker     // Test that callbacks are invoked correctly.
329*795d594fSAndroid Build Coastguard Worker     checkMemberCallback(klass, name, isPublic, true /* isField */, invokesMemberCallback);
330*795d594fSAndroid Build Coastguard Worker   }
331*795d594fSAndroid Build Coastguard Worker 
checkMethod(Class<?> klass, String name, boolean isStatic, Visibility visibility, Behaviour behaviour, boolean invokesMemberCallback, boolean testHiddenApiCheckHardeningDisabled)332*795d594fSAndroid Build Coastguard Worker   private static void checkMethod(Class<?> klass, String name, boolean isStatic,
333*795d594fSAndroid Build Coastguard Worker       Visibility visibility, Behaviour behaviour, boolean invokesMemberCallback,
334*795d594fSAndroid Build Coastguard Worker       boolean testHiddenApiCheckHardeningDisabled) throws Exception {
335*795d594fSAndroid Build Coastguard Worker 
336*795d594fSAndroid Build Coastguard Worker     boolean isPublic = (visibility == Visibility.Public);
337*795d594fSAndroid Build Coastguard Worker     if (klass.isInterface() && !isPublic) {
338*795d594fSAndroid Build Coastguard Worker       // All interface members are public.
339*795d594fSAndroid Build Coastguard Worker       return;
340*795d594fSAndroid Build Coastguard Worker     }
341*795d594fSAndroid Build Coastguard Worker 
342*795d594fSAndroid Build Coastguard Worker     boolean canDiscover = (behaviour != Behaviour.Denied);
343*795d594fSAndroid Build Coastguard Worker 
344*795d594fSAndroid Build Coastguard Worker     // Test discovery with reflection.
345*795d594fSAndroid Build Coastguard Worker 
346*795d594fSAndroid Build Coastguard Worker     if (Reflection.canDiscoverWithGetDeclaredMethod(klass, name) != canDiscover) {
347*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, false, "getDeclaredMethod()", canDiscover);
348*795d594fSAndroid Build Coastguard Worker     }
349*795d594fSAndroid Build Coastguard Worker 
350*795d594fSAndroid Build Coastguard Worker     if (Reflection.canDiscoverWithGetDeclaredMethods(klass, name) != canDiscover) {
351*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, false, "getDeclaredMethods()", canDiscover);
352*795d594fSAndroid Build Coastguard Worker     }
353*795d594fSAndroid Build Coastguard Worker 
354*795d594fSAndroid Build Coastguard Worker     if (Reflection.canDiscoverWithGetMethod(klass, name) != (canDiscover && isPublic)) {
355*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, false, "getMethod()", (canDiscover && isPublic));
356*795d594fSAndroid Build Coastguard Worker     }
357*795d594fSAndroid Build Coastguard Worker 
358*795d594fSAndroid Build Coastguard Worker     if (Reflection.canDiscoverWithGetMethods(klass, name) != (canDiscover && isPublic)) {
359*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, false, "getMethods()", (canDiscover && isPublic));
360*795d594fSAndroid Build Coastguard Worker     }
361*795d594fSAndroid Build Coastguard Worker 
362*795d594fSAndroid Build Coastguard Worker     // Test discovery with JNI.
363*795d594fSAndroid Build Coastguard Worker 
364*795d594fSAndroid Build Coastguard Worker     if (JNI.canDiscoverMethod(klass, name, isStatic) != canDiscover) {
365*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, false, "JNI", canDiscover);
366*795d594fSAndroid Build Coastguard Worker     }
367*795d594fSAndroid Build Coastguard Worker 
368*795d594fSAndroid Build Coastguard Worker     // Test discovery with MethodHandles.lookup().
369*795d594fSAndroid Build Coastguard Worker 
370*795d594fSAndroid Build Coastguard Worker     final MethodHandles.Lookup lookup = MethodHandles.lookup();
371*795d594fSAndroid Build Coastguard Worker     final MethodType methodType = MethodType.methodType(int.class);
372*795d594fSAndroid Build Coastguard Worker     if (JLI.canDiscoverWithLookupFindVirtual(lookup, klass, name, methodType) != canDiscover) {
373*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, false, "MethodHandles.lookup().findVirtual()",
374*795d594fSAndroid Build Coastguard Worker                               canDiscover);
375*795d594fSAndroid Build Coastguard Worker     }
376*795d594fSAndroid Build Coastguard Worker 
377*795d594fSAndroid Build Coastguard Worker     if (JLI.canDiscoverWithLookupFindStatic(lookup, klass, name, methodType) != canDiscover) {
378*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, false, "MethodHandles.lookup().findStatic()",
379*795d594fSAndroid Build Coastguard Worker                               canDiscover);
380*795d594fSAndroid Build Coastguard Worker     }
381*795d594fSAndroid Build Coastguard Worker 
382*795d594fSAndroid Build Coastguard Worker     // Check for meta reflection.
383*795d594fSAndroid Build Coastguard Worker 
384*795d594fSAndroid Build Coastguard Worker     // With hidden api check hardening enabled, only white and light greylisted methods should be
385*795d594fSAndroid Build Coastguard Worker     // discoverable.
386*795d594fSAndroid Build Coastguard Worker     if (Reflection.canDiscoverMethodWithMetaReflection(klass, name, true) != canDiscover) {
387*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, name, false,
388*795d594fSAndroid Build Coastguard Worker           "Meta reflection with hidden api hardening enabled", canDiscover);
389*795d594fSAndroid Build Coastguard Worker     }
390*795d594fSAndroid Build Coastguard Worker 
391*795d594fSAndroid Build Coastguard Worker     if (testHiddenApiCheckHardeningDisabled) {
392*795d594fSAndroid Build Coastguard Worker       // With hidden api check hardening disabled, all methods should be discoverable.
393*795d594fSAndroid Build Coastguard Worker       if (Reflection.canDiscoverMethodWithMetaReflection(klass, name, false) != true) {
394*795d594fSAndroid Build Coastguard Worker         throwDiscoveryException(klass, name, false,
395*795d594fSAndroid Build Coastguard Worker             "Meta reflection with hidden api hardening enabled", canDiscover);
396*795d594fSAndroid Build Coastguard Worker       }
397*795d594fSAndroid Build Coastguard Worker     }
398*795d594fSAndroid Build Coastguard Worker 
399*795d594fSAndroid Build Coastguard Worker     // Finish here if we could not discover the method.
400*795d594fSAndroid Build Coastguard Worker 
401*795d594fSAndroid Build Coastguard Worker     if (canDiscover) {
402*795d594fSAndroid Build Coastguard Worker       // Test that modifiers are unaffected.
403*795d594fSAndroid Build Coastguard Worker 
404*795d594fSAndroid Build Coastguard Worker       if (Reflection.canObserveMethodHiddenAccessFlags(klass, name)) {
405*795d594fSAndroid Build Coastguard Worker         throwModifiersException(klass, name, false);
406*795d594fSAndroid Build Coastguard Worker       }
407*795d594fSAndroid Build Coastguard Worker 
408*795d594fSAndroid Build Coastguard Worker       // Test whether we can invoke the method. This skips non-static interface methods.
409*795d594fSAndroid Build Coastguard Worker       if (!klass.isInterface() || isStatic) {
410*795d594fSAndroid Build Coastguard Worker         if (!Reflection.canInvokeMethod(klass, name)) {
411*795d594fSAndroid Build Coastguard Worker           throwAccessException(klass, name, false, "invoke()");
412*795d594fSAndroid Build Coastguard Worker         }
413*795d594fSAndroid Build Coastguard Worker         if (!JNI.canInvokeMethodA(klass, name, isStatic)) {
414*795d594fSAndroid Build Coastguard Worker           throwAccessException(klass, name, false, "CallMethodA");
415*795d594fSAndroid Build Coastguard Worker         }
416*795d594fSAndroid Build Coastguard Worker         if (!JNI.canInvokeMethodV(klass, name, isStatic)) {
417*795d594fSAndroid Build Coastguard Worker           throwAccessException(klass, name, false, "CallMethodV");
418*795d594fSAndroid Build Coastguard Worker         }
419*795d594fSAndroid Build Coastguard Worker       }
420*795d594fSAndroid Build Coastguard Worker     }
421*795d594fSAndroid Build Coastguard Worker 
422*795d594fSAndroid Build Coastguard Worker     // Test that callbacks are invoked correctly.
423*795d594fSAndroid Build Coastguard Worker     checkMemberCallback(klass, name, isPublic, false /* isField */, invokesMemberCallback);
424*795d594fSAndroid Build Coastguard Worker   }
425*795d594fSAndroid Build Coastguard Worker 
checkConstructor(Class<?> klass, Visibility visibility, Hiddenness hiddenness, Behaviour behaviour, boolean testHiddenApiCheckHardeningDisabled)426*795d594fSAndroid Build Coastguard Worker   private static void checkConstructor(Class<?> klass, Visibility visibility, Hiddenness hiddenness,
427*795d594fSAndroid Build Coastguard Worker       Behaviour behaviour, boolean testHiddenApiCheckHardeningDisabled) throws Exception {
428*795d594fSAndroid Build Coastguard Worker 
429*795d594fSAndroid Build Coastguard Worker     boolean isPublic = (visibility == Visibility.Public);
430*795d594fSAndroid Build Coastguard Worker     String signature = "(" + visibility.mAssociatedType.mShorty +
431*795d594fSAndroid Build Coastguard Worker                              hiddenness.mAssociatedType.mShorty + ")V";
432*795d594fSAndroid Build Coastguard Worker     String fullName = "<init>" + signature;
433*795d594fSAndroid Build Coastguard Worker     Class<?> args[] = new Class[] { visibility.mAssociatedType.mClass,
434*795d594fSAndroid Build Coastguard Worker                                     hiddenness.mAssociatedType.mClass };
435*795d594fSAndroid Build Coastguard Worker     Object initargs[] = new Object[] { visibility.mAssociatedType.mDefaultValue,
436*795d594fSAndroid Build Coastguard Worker                                        hiddenness.mAssociatedType.mDefaultValue };
437*795d594fSAndroid Build Coastguard Worker     MethodType methodType = MethodType.methodType(void.class, args);
438*795d594fSAndroid Build Coastguard Worker 
439*795d594fSAndroid Build Coastguard Worker     boolean canDiscover = (behaviour != Behaviour.Denied);
440*795d594fSAndroid Build Coastguard Worker 
441*795d594fSAndroid Build Coastguard Worker     // Test discovery with reflection.
442*795d594fSAndroid Build Coastguard Worker 
443*795d594fSAndroid Build Coastguard Worker     if (Reflection.canDiscoverWithGetDeclaredConstructor(klass, args) != canDiscover) {
444*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, fullName, false, "getDeclaredConstructor()", canDiscover);
445*795d594fSAndroid Build Coastguard Worker     }
446*795d594fSAndroid Build Coastguard Worker 
447*795d594fSAndroid Build Coastguard Worker     if (Reflection.canDiscoverWithGetDeclaredConstructors(klass, args) != canDiscover) {
448*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, fullName, false, "getDeclaredConstructors()", canDiscover);
449*795d594fSAndroid Build Coastguard Worker     }
450*795d594fSAndroid Build Coastguard Worker 
451*795d594fSAndroid Build Coastguard Worker     if (Reflection.canDiscoverWithGetConstructor(klass, args) != (canDiscover && isPublic)) {
452*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(
453*795d594fSAndroid Build Coastguard Worker           klass, fullName, false, "getConstructor()", (canDiscover && isPublic));
454*795d594fSAndroid Build Coastguard Worker     }
455*795d594fSAndroid Build Coastguard Worker 
456*795d594fSAndroid Build Coastguard Worker     if (Reflection.canDiscoverWithGetConstructors(klass, args) != (canDiscover && isPublic)) {
457*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(
458*795d594fSAndroid Build Coastguard Worker           klass, fullName, false, "getConstructors()", (canDiscover && isPublic));
459*795d594fSAndroid Build Coastguard Worker     }
460*795d594fSAndroid Build Coastguard Worker 
461*795d594fSAndroid Build Coastguard Worker     // Test discovery with JNI.
462*795d594fSAndroid Build Coastguard Worker 
463*795d594fSAndroid Build Coastguard Worker     if (JNI.canDiscoverConstructor(klass, signature) != canDiscover) {
464*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, fullName, false, "JNI", canDiscover);
465*795d594fSAndroid Build Coastguard Worker     }
466*795d594fSAndroid Build Coastguard Worker 
467*795d594fSAndroid Build Coastguard Worker     // Test discovery with MethodHandles.lookup()
468*795d594fSAndroid Build Coastguard Worker 
469*795d594fSAndroid Build Coastguard Worker     final MethodHandles.Lookup lookup = MethodHandles.lookup();
470*795d594fSAndroid Build Coastguard Worker     if (JLI.canDiscoverWithLookupFindConstructor(lookup, klass, methodType) != canDiscover) {
471*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, fullName, false, "MethodHandles.lookup().findConstructor",
472*795d594fSAndroid Build Coastguard Worker                               canDiscover);
473*795d594fSAndroid Build Coastguard Worker     }
474*795d594fSAndroid Build Coastguard Worker 
475*795d594fSAndroid Build Coastguard Worker     final MethodHandles.Lookup publicLookup = MethodHandles.publicLookup();
476*795d594fSAndroid Build Coastguard Worker     if (JLI.canDiscoverWithLookupFindConstructor(publicLookup, klass, methodType) != canDiscover) {
477*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, fullName, false,
478*795d594fSAndroid Build Coastguard Worker                               "MethodHandles.publicLookup().findConstructor",
479*795d594fSAndroid Build Coastguard Worker                               canDiscover);
480*795d594fSAndroid Build Coastguard Worker     }
481*795d594fSAndroid Build Coastguard Worker 
482*795d594fSAndroid Build Coastguard Worker     // Check for meta reflection.
483*795d594fSAndroid Build Coastguard Worker 
484*795d594fSAndroid Build Coastguard Worker     // With hidden api check hardening enabled, only white and light greylisted constructors should
485*795d594fSAndroid Build Coastguard Worker     // be discoverable.
486*795d594fSAndroid Build Coastguard Worker     if (Reflection.canDiscoverConstructorWithMetaReflection(klass, args, true) != canDiscover) {
487*795d594fSAndroid Build Coastguard Worker       throwDiscoveryException(klass, fullName, false,
488*795d594fSAndroid Build Coastguard Worker           "Meta reflection with hidden api hardening enabled", canDiscover);
489*795d594fSAndroid Build Coastguard Worker     }
490*795d594fSAndroid Build Coastguard Worker 
491*795d594fSAndroid Build Coastguard Worker     if (testHiddenApiCheckHardeningDisabled) {
492*795d594fSAndroid Build Coastguard Worker       // With hidden api check hardening disabled, all constructors should be discoverable.
493*795d594fSAndroid Build Coastguard Worker       if (Reflection.canDiscoverConstructorWithMetaReflection(klass, args, false) != true) {
494*795d594fSAndroid Build Coastguard Worker         throwDiscoveryException(klass, fullName, false,
495*795d594fSAndroid Build Coastguard Worker             "Meta reflection with hidden api hardening enabled", canDiscover);
496*795d594fSAndroid Build Coastguard Worker       }
497*795d594fSAndroid Build Coastguard Worker     }
498*795d594fSAndroid Build Coastguard Worker 
499*795d594fSAndroid Build Coastguard Worker     if (canDiscover) {
500*795d594fSAndroid Build Coastguard Worker       // Test whether we can invoke the constructor.
501*795d594fSAndroid Build Coastguard Worker 
502*795d594fSAndroid Build Coastguard Worker       if (!Reflection.canInvokeConstructor(klass, args, initargs)) {
503*795d594fSAndroid Build Coastguard Worker         throwAccessException(klass, fullName, false, "invoke()");
504*795d594fSAndroid Build Coastguard Worker       }
505*795d594fSAndroid Build Coastguard Worker       if (!JNI.canInvokeConstructorA(klass, signature)) {
506*795d594fSAndroid Build Coastguard Worker         throwAccessException(klass, fullName, false, "NewObjectA");
507*795d594fSAndroid Build Coastguard Worker       }
508*795d594fSAndroid Build Coastguard Worker       if (!JNI.canInvokeConstructorV(klass, signature)) {
509*795d594fSAndroid Build Coastguard Worker         throwAccessException(klass, fullName, false, "NewObjectV");
510*795d594fSAndroid Build Coastguard Worker       }
511*795d594fSAndroid Build Coastguard Worker     }
512*795d594fSAndroid Build Coastguard Worker   }
513*795d594fSAndroid Build Coastguard Worker 
checkNullaryConstructor(Class<?> klass, Behaviour behaviour)514*795d594fSAndroid Build Coastguard Worker   private static void checkNullaryConstructor(Class<?> klass, Behaviour behaviour)
515*795d594fSAndroid Build Coastguard Worker       throws Exception {
516*795d594fSAndroid Build Coastguard Worker     boolean canAccess = (behaviour != Behaviour.Denied);
517*795d594fSAndroid Build Coastguard Worker 
518*795d594fSAndroid Build Coastguard Worker     if (Reflection.canUseNewInstance(klass) != canAccess) {
519*795d594fSAndroid Build Coastguard Worker       throw new RuntimeException("Expected to " + (canAccess ? "" : "not ") +
520*795d594fSAndroid Build Coastguard Worker           "be able to construct " + klass.getName() + ". " + configMessage);
521*795d594fSAndroid Build Coastguard Worker     }
522*795d594fSAndroid Build Coastguard Worker   }
523*795d594fSAndroid Build Coastguard Worker 
checkLinking(String className, boolean takesParameter, Behaviour behaviour)524*795d594fSAndroid Build Coastguard Worker   private static void checkLinking(String className, boolean takesParameter, Behaviour behaviour)
525*795d594fSAndroid Build Coastguard Worker       throws Exception {
526*795d594fSAndroid Build Coastguard Worker     boolean canAccess = (behaviour != Behaviour.Denied);
527*795d594fSAndroid Build Coastguard Worker 
528*795d594fSAndroid Build Coastguard Worker     if (Linking.canAccess(className, takesParameter) != canAccess) {
529*795d594fSAndroid Build Coastguard Worker       throw new RuntimeException("Expected to " + (canAccess ? "" : "not ") +
530*795d594fSAndroid Build Coastguard Worker           "be able to verify " + className + "." + configMessage);
531*795d594fSAndroid Build Coastguard Worker     }
532*795d594fSAndroid Build Coastguard Worker   }
533*795d594fSAndroid Build Coastguard Worker 
throwDiscoveryException(Class<?> klass, String name, boolean isField, String fn, boolean canAccess)534*795d594fSAndroid Build Coastguard Worker   private static void throwDiscoveryException(Class<?> klass, String name, boolean isField,
535*795d594fSAndroid Build Coastguard Worker       String fn, boolean canAccess) {
536*795d594fSAndroid Build Coastguard Worker     throw new RuntimeException("Expected " + (isField ? "field " : "method ") + klass.getName() +
537*795d594fSAndroid Build Coastguard Worker         "." + name + " to " + (canAccess ? "" : "not ") + "be discoverable with " + fn + ". " +
538*795d594fSAndroid Build Coastguard Worker         configMessage);
539*795d594fSAndroid Build Coastguard Worker   }
540*795d594fSAndroid Build Coastguard Worker 
throwAccessException(Class<?> klass, String name, boolean isField, String fn)541*795d594fSAndroid Build Coastguard Worker   private static void throwAccessException(Class<?> klass, String name, boolean isField,
542*795d594fSAndroid Build Coastguard Worker       String fn) {
543*795d594fSAndroid Build Coastguard Worker     throw new RuntimeException("Expected to be able to access " + (isField ? "field " : "method ") +
544*795d594fSAndroid Build Coastguard Worker         klass.getName() + "." + name + " using " + fn + ". " + configMessage);
545*795d594fSAndroid Build Coastguard Worker   }
546*795d594fSAndroid Build Coastguard Worker 
throwModifiersException(Class<?> klass, String name, boolean isField)547*795d594fSAndroid Build Coastguard Worker   private static void throwModifiersException(Class<?> klass, String name, boolean isField) {
548*795d594fSAndroid Build Coastguard Worker     throw new RuntimeException("Expected " + (isField ? "field " : "method ") + klass.getName() +
549*795d594fSAndroid Build Coastguard Worker         "." + name + " to not expose hidden modifiers");
550*795d594fSAndroid Build Coastguard Worker   }
551*795d594fSAndroid Build Coastguard Worker 
552*795d594fSAndroid Build Coastguard Worker   private static DexDomain parentDomain;
553*795d594fSAndroid Build Coastguard Worker   private static DexDomain childDomain;
554*795d594fSAndroid Build Coastguard Worker   private static boolean everythingSdked;
555*795d594fSAndroid Build Coastguard Worker 
556*795d594fSAndroid Build Coastguard Worker   private static String configMessage;
557*795d594fSAndroid Build Coastguard Worker }
558