xref: /aosp_15_r20/art/runtime/hidden_api.cc (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker /*
2*795d594fSAndroid Build Coastguard Worker  * Copyright (C) 2018 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 #include "hidden_api.h"
18*795d594fSAndroid Build Coastguard Worker 
19*795d594fSAndroid Build Coastguard Worker #include <atomic>
20*795d594fSAndroid Build Coastguard Worker 
21*795d594fSAndroid Build Coastguard Worker #include "art_field-inl.h"
22*795d594fSAndroid Build Coastguard Worker #include "art_method-inl.h"
23*795d594fSAndroid Build Coastguard Worker #include "base/dumpable.h"
24*795d594fSAndroid Build Coastguard Worker #include "base/file_utils.h"
25*795d594fSAndroid Build Coastguard Worker #include "class_root-inl.h"
26*795d594fSAndroid Build Coastguard Worker #include "compat_framework.h"
27*795d594fSAndroid Build Coastguard Worker #include "dex/class_accessor-inl.h"
28*795d594fSAndroid Build Coastguard Worker #include "dex/dex_file_loader.h"
29*795d594fSAndroid Build Coastguard Worker #include "mirror/class_ext.h"
30*795d594fSAndroid Build Coastguard Worker #include "mirror/proxy.h"
31*795d594fSAndroid Build Coastguard Worker #include "nativehelper/scoped_local_ref.h"
32*795d594fSAndroid Build Coastguard Worker #include "oat/oat_file.h"
33*795d594fSAndroid Build Coastguard Worker #include "scoped_thread_state_change.h"
34*795d594fSAndroid Build Coastguard Worker #include "stack.h"
35*795d594fSAndroid Build Coastguard Worker #include "thread-inl.h"
36*795d594fSAndroid Build Coastguard Worker #include "well_known_classes.h"
37*795d594fSAndroid Build Coastguard Worker 
38*795d594fSAndroid Build Coastguard Worker namespace art HIDDEN {
39*795d594fSAndroid Build Coastguard Worker namespace hiddenapi {
40*795d594fSAndroid Build Coastguard Worker 
41*795d594fSAndroid Build Coastguard Worker // Should be the same as dalvik.system.VMRuntime.HIDE_MAXTARGETSDK_P_HIDDEN_APIS,
42*795d594fSAndroid Build Coastguard Worker // dalvik.system.VMRuntime.HIDE_MAXTARGETSDK_Q_HIDDEN_APIS, and
43*795d594fSAndroid Build Coastguard Worker // dalvik.system.VMRuntime.ALLOW_TEST_API_ACCESS.
44*795d594fSAndroid Build Coastguard Worker // Corresponds to bug ids.
45*795d594fSAndroid Build Coastguard Worker static constexpr uint64_t kHideMaxtargetsdkPHiddenApis = 149997251;
46*795d594fSAndroid Build Coastguard Worker static constexpr uint64_t kHideMaxtargetsdkQHiddenApis = 149994052;
47*795d594fSAndroid Build Coastguard Worker static constexpr uint64_t kAllowTestApiAccess = 166236554;
48*795d594fSAndroid Build Coastguard Worker 
49*795d594fSAndroid Build Coastguard Worker static constexpr uint64_t kMaxLogWarnings = 100;
50*795d594fSAndroid Build Coastguard Worker 
51*795d594fSAndroid Build Coastguard Worker // Should be the same as dalvik.system.VMRuntime.PREVENT_META_REFLECTION_BLOCKLIST_ACCESS.
52*795d594fSAndroid Build Coastguard Worker // Corresponds to a bug id.
53*795d594fSAndroid Build Coastguard Worker static constexpr uint64_t kPreventMetaReflectionBlocklistAccess = 142365358;
54*795d594fSAndroid Build Coastguard Worker 
55*795d594fSAndroid Build Coastguard Worker // Set to true if we should always print a warning in logcat for all hidden API accesses, not just
56*795d594fSAndroid Build Coastguard Worker // conditionally and unconditionally blocked. This can be set to true for developer preview / beta
57*795d594fSAndroid Build Coastguard Worker // builds, but should be false for public release builds.
58*795d594fSAndroid Build Coastguard Worker // Note that when flipping this flag, you must also update the expectations of test 674-hiddenapi
59*795d594fSAndroid Build Coastguard Worker // as it affects whether or not we warn for unsupported APIs that have been added to the exemptions
60*795d594fSAndroid Build Coastguard Worker // list.
61*795d594fSAndroid Build Coastguard Worker static constexpr bool kLogAllAccesses = false;
62*795d594fSAndroid Build Coastguard Worker 
63*795d594fSAndroid Build Coastguard Worker // Exemptions for logcat warning. Following signatures do not produce a warning as app developers
64*795d594fSAndroid Build Coastguard Worker // should not be alerted on the usage of these unsupported APIs. See b/154851649.
65*795d594fSAndroid Build Coastguard Worker static const std::vector<std::string> kWarningExemptions = {
66*795d594fSAndroid Build Coastguard Worker     "Ljava/nio/Buffer;",
67*795d594fSAndroid Build Coastguard Worker     "Llibcore/io/Memory;",
68*795d594fSAndroid Build Coastguard Worker     "Lsun/misc/Unsafe;",
69*795d594fSAndroid Build Coastguard Worker };
70*795d594fSAndroid Build Coastguard Worker 
operator <<(std::ostream & os,AccessMethod value)71*795d594fSAndroid Build Coastguard Worker static inline std::ostream& operator<<(std::ostream& os, AccessMethod value) {
72*795d594fSAndroid Build Coastguard Worker   switch (value) {
73*795d594fSAndroid Build Coastguard Worker     case AccessMethod::kNone:
74*795d594fSAndroid Build Coastguard Worker       LOG(FATAL) << "Internal access to hidden API should not be logged";
75*795d594fSAndroid Build Coastguard Worker       UNREACHABLE();
76*795d594fSAndroid Build Coastguard Worker     case AccessMethod::kReflection:
77*795d594fSAndroid Build Coastguard Worker       os << "reflection";
78*795d594fSAndroid Build Coastguard Worker       break;
79*795d594fSAndroid Build Coastguard Worker     case AccessMethod::kJNI:
80*795d594fSAndroid Build Coastguard Worker       os << "JNI";
81*795d594fSAndroid Build Coastguard Worker       break;
82*795d594fSAndroid Build Coastguard Worker     case AccessMethod::kLinking:
83*795d594fSAndroid Build Coastguard Worker       os << "linking";
84*795d594fSAndroid Build Coastguard Worker       break;
85*795d594fSAndroid Build Coastguard Worker   }
86*795d594fSAndroid Build Coastguard Worker   return os;
87*795d594fSAndroid Build Coastguard Worker }
88*795d594fSAndroid Build Coastguard Worker 
operator <<(std::ostream & os,const AccessContext & value)89*795d594fSAndroid Build Coastguard Worker static inline std::ostream& operator<<(std::ostream& os, const AccessContext& value)
90*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
91*795d594fSAndroid Build Coastguard Worker   if (!value.GetClass().IsNull()) {
92*795d594fSAndroid Build Coastguard Worker     std::string tmp;
93*795d594fSAndroid Build Coastguard Worker     os << value.GetClass()->GetDescriptor(&tmp);
94*795d594fSAndroid Build Coastguard Worker   } else if (value.GetDexFile() != nullptr) {
95*795d594fSAndroid Build Coastguard Worker     os << value.GetDexFile()->GetLocation();
96*795d594fSAndroid Build Coastguard Worker   } else {
97*795d594fSAndroid Build Coastguard Worker     os << "<unknown_caller>";
98*795d594fSAndroid Build Coastguard Worker   }
99*795d594fSAndroid Build Coastguard Worker   return os;
100*795d594fSAndroid Build Coastguard Worker }
101*795d594fSAndroid Build Coastguard Worker 
DetermineDomainFromLocation(const std::string & dex_location,ObjPtr<mirror::ClassLoader> class_loader)102*795d594fSAndroid Build Coastguard Worker static Domain DetermineDomainFromLocation(const std::string& dex_location,
103*795d594fSAndroid Build Coastguard Worker                                           ObjPtr<mirror::ClassLoader> class_loader) {
104*795d594fSAndroid Build Coastguard Worker   // If running with APEX, check `path` against known APEX locations.
105*795d594fSAndroid Build Coastguard Worker   // These checks will be skipped on target buildbots where ANDROID_ART_ROOT
106*795d594fSAndroid Build Coastguard Worker   // is set to "/system".
107*795d594fSAndroid Build Coastguard Worker   if (ArtModuleRootDistinctFromAndroidRoot()) {
108*795d594fSAndroid Build Coastguard Worker     if (LocationIsOnArtModule(dex_location) || LocationIsOnConscryptModule(dex_location) ||
109*795d594fSAndroid Build Coastguard Worker         LocationIsOnI18nModule(dex_location)) {
110*795d594fSAndroid Build Coastguard Worker       return Domain::kCorePlatform;
111*795d594fSAndroid Build Coastguard Worker     }
112*795d594fSAndroid Build Coastguard Worker 
113*795d594fSAndroid Build Coastguard Worker     if (LocationIsOnApex(dex_location)) {
114*795d594fSAndroid Build Coastguard Worker       return Domain::kPlatform;
115*795d594fSAndroid Build Coastguard Worker     }
116*795d594fSAndroid Build Coastguard Worker   }
117*795d594fSAndroid Build Coastguard Worker 
118*795d594fSAndroid Build Coastguard Worker   if (LocationIsOnSystemFramework(dex_location)) {
119*795d594fSAndroid Build Coastguard Worker     return Domain::kPlatform;
120*795d594fSAndroid Build Coastguard Worker   }
121*795d594fSAndroid Build Coastguard Worker 
122*795d594fSAndroid Build Coastguard Worker   if (LocationIsOnSystemExtFramework(dex_location)) {
123*795d594fSAndroid Build Coastguard Worker     return Domain::kPlatform;
124*795d594fSAndroid Build Coastguard Worker   }
125*795d594fSAndroid Build Coastguard Worker 
126*795d594fSAndroid Build Coastguard Worker   if (class_loader.IsNull()) {
127*795d594fSAndroid Build Coastguard Worker     if (kIsTargetBuild && !kIsTargetLinux) {
128*795d594fSAndroid Build Coastguard Worker       // This is unexpected only when running on Android.
129*795d594fSAndroid Build Coastguard Worker       LOG(WARNING) << "DexFile " << dex_location
130*795d594fSAndroid Build Coastguard Worker                    << " is in boot class path but is not in a known location";
131*795d594fSAndroid Build Coastguard Worker     }
132*795d594fSAndroid Build Coastguard Worker     return Domain::kPlatform;
133*795d594fSAndroid Build Coastguard Worker   }
134*795d594fSAndroid Build Coastguard Worker 
135*795d594fSAndroid Build Coastguard Worker   return Domain::kApplication;
136*795d594fSAndroid Build Coastguard Worker }
137*795d594fSAndroid Build Coastguard Worker 
InitializeDexFileDomain(const DexFile & dex_file,ObjPtr<mirror::ClassLoader> class_loader)138*795d594fSAndroid Build Coastguard Worker void InitializeDexFileDomain(const DexFile& dex_file, ObjPtr<mirror::ClassLoader> class_loader) {
139*795d594fSAndroid Build Coastguard Worker   Domain dex_domain = DetermineDomainFromLocation(dex_file.GetLocation(), class_loader);
140*795d594fSAndroid Build Coastguard Worker 
141*795d594fSAndroid Build Coastguard Worker   // Assign the domain unless a more permissive domain has already been assigned.
142*795d594fSAndroid Build Coastguard Worker   // This may happen when DexFile is initialized as trusted.
143*795d594fSAndroid Build Coastguard Worker   if (IsDomainMoreTrustedThan(dex_domain, dex_file.GetHiddenapiDomain())) {
144*795d594fSAndroid Build Coastguard Worker     dex_file.SetHiddenapiDomain(dex_domain);
145*795d594fSAndroid Build Coastguard Worker   }
146*795d594fSAndroid Build Coastguard Worker }
147*795d594fSAndroid Build Coastguard Worker 
InitializeCorePlatformApiPrivateFields()148*795d594fSAndroid Build Coastguard Worker void InitializeCorePlatformApiPrivateFields() {
149*795d594fSAndroid Build Coastguard Worker   // The following fields in WellKnownClasses correspond to private fields in the Core Platform
150*795d594fSAndroid Build Coastguard Worker   // API that cannot be otherwise expressed and propagated through tooling (b/144502743).
151*795d594fSAndroid Build Coastguard Worker   ArtField* private_core_platform_api_fields[] = {
152*795d594fSAndroid Build Coastguard Worker       WellKnownClasses::java_io_FileDescriptor_descriptor,
153*795d594fSAndroid Build Coastguard Worker       WellKnownClasses::java_nio_Buffer_address,
154*795d594fSAndroid Build Coastguard Worker       WellKnownClasses::java_nio_Buffer_elementSizeShift,
155*795d594fSAndroid Build Coastguard Worker       WellKnownClasses::java_nio_Buffer_limit,
156*795d594fSAndroid Build Coastguard Worker       WellKnownClasses::java_nio_Buffer_position,
157*795d594fSAndroid Build Coastguard Worker   };
158*795d594fSAndroid Build Coastguard Worker 
159*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(Thread::Current());
160*795d594fSAndroid Build Coastguard Worker   for (ArtField* field : private_core_platform_api_fields) {
161*795d594fSAndroid Build Coastguard Worker     const uint32_t access_flags = field->GetAccessFlags();
162*795d594fSAndroid Build Coastguard Worker     uint32_t new_access_flags = access_flags | kAccCorePlatformApi;
163*795d594fSAndroid Build Coastguard Worker     DCHECK(new_access_flags != access_flags);
164*795d594fSAndroid Build Coastguard Worker     field->SetAccessFlags(new_access_flags);
165*795d594fSAndroid Build Coastguard Worker   }
166*795d594fSAndroid Build Coastguard Worker }
167*795d594fSAndroid Build Coastguard Worker 
GetReflectionCallerAccessContext(Thread * self)168*795d594fSAndroid Build Coastguard Worker hiddenapi::AccessContext GetReflectionCallerAccessContext(Thread* self)
169*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
170*795d594fSAndroid Build Coastguard Worker   // Walk the stack and find the first frame not from java.lang.Class,
171*795d594fSAndroid Build Coastguard Worker   // java.lang.invoke or java.lang.reflect. This is very expensive.
172*795d594fSAndroid Build Coastguard Worker   // Save this till the last.
173*795d594fSAndroid Build Coastguard Worker   struct FirstExternalCallerVisitor : public StackVisitor {
174*795d594fSAndroid Build Coastguard Worker     explicit FirstExternalCallerVisitor(Thread* thread)
175*795d594fSAndroid Build Coastguard Worker         : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
176*795d594fSAndroid Build Coastguard Worker           caller(nullptr) {}
177*795d594fSAndroid Build Coastguard Worker 
178*795d594fSAndroid Build Coastguard Worker     bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
179*795d594fSAndroid Build Coastguard Worker       ArtMethod* m = GetMethod();
180*795d594fSAndroid Build Coastguard Worker       if (m == nullptr) {
181*795d594fSAndroid Build Coastguard Worker         // Attached native thread. Assume this is *not* boot class path.
182*795d594fSAndroid Build Coastguard Worker         caller = nullptr;
183*795d594fSAndroid Build Coastguard Worker         return false;
184*795d594fSAndroid Build Coastguard Worker       } else if (m->IsRuntimeMethod()) {
185*795d594fSAndroid Build Coastguard Worker         // Internal runtime method, continue walking the stack.
186*795d594fSAndroid Build Coastguard Worker         return true;
187*795d594fSAndroid Build Coastguard Worker       }
188*795d594fSAndroid Build Coastguard Worker 
189*795d594fSAndroid Build Coastguard Worker       ObjPtr<mirror::Class> declaring_class = m->GetDeclaringClass();
190*795d594fSAndroid Build Coastguard Worker       if (declaring_class->IsBootStrapClassLoaded()) {
191*795d594fSAndroid Build Coastguard Worker         if (declaring_class->IsClassClass()) {
192*795d594fSAndroid Build Coastguard Worker           return true;
193*795d594fSAndroid Build Coastguard Worker         }
194*795d594fSAndroid Build Coastguard Worker 
195*795d594fSAndroid Build Coastguard Worker         // MethodHandles.makeIdentity is doing findStatic to find hidden methods,
196*795d594fSAndroid Build Coastguard Worker         // where reflection is used.
197*795d594fSAndroid Build Coastguard Worker         if (m == WellKnownClasses::java_lang_invoke_MethodHandles_makeIdentity) {
198*795d594fSAndroid Build Coastguard Worker           return false;
199*795d594fSAndroid Build Coastguard Worker         }
200*795d594fSAndroid Build Coastguard Worker 
201*795d594fSAndroid Build Coastguard Worker         // Check classes in the java.lang.invoke package. At the time of writing, the
202*795d594fSAndroid Build Coastguard Worker         // classes of interest are MethodHandles and MethodHandles.Lookup, but this
203*795d594fSAndroid Build Coastguard Worker         // is subject to change so conservatively cover the entire package.
204*795d594fSAndroid Build Coastguard Worker         // NB Static initializers within java.lang.invoke are permitted and do not
205*795d594fSAndroid Build Coastguard Worker         // need further stack inspection.
206*795d594fSAndroid Build Coastguard Worker         ObjPtr<mirror::Class> lookup_class = GetClassRoot<mirror::MethodHandlesLookup>();
207*795d594fSAndroid Build Coastguard Worker         if ((declaring_class == lookup_class || declaring_class->IsInSamePackage(lookup_class)) &&
208*795d594fSAndroid Build Coastguard Worker             !m->IsClassInitializer()) {
209*795d594fSAndroid Build Coastguard Worker           return true;
210*795d594fSAndroid Build Coastguard Worker         }
211*795d594fSAndroid Build Coastguard Worker         // Check for classes in the java.lang.reflect package, except for java.lang.reflect.Proxy.
212*795d594fSAndroid Build Coastguard Worker         // java.lang.reflect.Proxy does its own hidden api checks (https://r.android.com/915496),
213*795d594fSAndroid Build Coastguard Worker         // and walking over this frame would cause a null pointer dereference
214*795d594fSAndroid Build Coastguard Worker         // (e.g. in 691-hiddenapi-proxy).
215*795d594fSAndroid Build Coastguard Worker         ObjPtr<mirror::Class> proxy_class = GetClassRoot<mirror::Proxy>();
216*795d594fSAndroid Build Coastguard Worker         CompatFramework& compat_framework = Runtime::Current()->GetCompatFramework();
217*795d594fSAndroid Build Coastguard Worker         if (declaring_class->IsInSamePackage(proxy_class) && declaring_class != proxy_class) {
218*795d594fSAndroid Build Coastguard Worker           if (compat_framework.IsChangeEnabled(kPreventMetaReflectionBlocklistAccess)) {
219*795d594fSAndroid Build Coastguard Worker             return true;
220*795d594fSAndroid Build Coastguard Worker           }
221*795d594fSAndroid Build Coastguard Worker         }
222*795d594fSAndroid Build Coastguard Worker       }
223*795d594fSAndroid Build Coastguard Worker 
224*795d594fSAndroid Build Coastguard Worker       caller = m;
225*795d594fSAndroid Build Coastguard Worker       return false;
226*795d594fSAndroid Build Coastguard Worker     }
227*795d594fSAndroid Build Coastguard Worker 
228*795d594fSAndroid Build Coastguard Worker     ArtMethod* caller;
229*795d594fSAndroid Build Coastguard Worker   };
230*795d594fSAndroid Build Coastguard Worker 
231*795d594fSAndroid Build Coastguard Worker   FirstExternalCallerVisitor visitor(self);
232*795d594fSAndroid Build Coastguard Worker   visitor.WalkStack();
233*795d594fSAndroid Build Coastguard Worker 
234*795d594fSAndroid Build Coastguard Worker   // Construct AccessContext from the calling class found on the stack.
235*795d594fSAndroid Build Coastguard Worker   // If the calling class cannot be determined, e.g. unattached threads,
236*795d594fSAndroid Build Coastguard Worker   // we conservatively assume the caller is trusted.
237*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Class> caller =
238*795d594fSAndroid Build Coastguard Worker       (visitor.caller == nullptr) ? nullptr : visitor.caller->GetDeclaringClass();
239*795d594fSAndroid Build Coastguard Worker   return caller.IsNull() ? AccessContext(/* is_trusted= */ true) : AccessContext(caller);
240*795d594fSAndroid Build Coastguard Worker }
241*795d594fSAndroid Build Coastguard Worker 
242*795d594fSAndroid Build Coastguard Worker namespace detail {
243*795d594fSAndroid Build Coastguard Worker 
244*795d594fSAndroid Build Coastguard Worker // Do not change the values of items in this enum, as they are written to the
245*795d594fSAndroid Build Coastguard Worker // event log for offline analysis. Any changes will interfere with that analysis.
246*795d594fSAndroid Build Coastguard Worker enum AccessContextFlags {
247*795d594fSAndroid Build Coastguard Worker   // Accessed member is a field if this bit is set, else a method
248*795d594fSAndroid Build Coastguard Worker   kMemberIsField = 1 << 0,
249*795d594fSAndroid Build Coastguard Worker   // Indicates if access was denied to the member, instead of just printing a warning.
250*795d594fSAndroid Build Coastguard Worker   kAccessDenied = 1 << 1,
251*795d594fSAndroid Build Coastguard Worker };
252*795d594fSAndroid Build Coastguard Worker 
MemberSignature(ArtField * field)253*795d594fSAndroid Build Coastguard Worker MemberSignature::MemberSignature(ArtField* field) {
254*795d594fSAndroid Build Coastguard Worker   // Note: `ArtField::GetDeclaringClassDescriptor()` does not support proxy classes.
255*795d594fSAndroid Build Coastguard Worker   class_name_ = field->GetDeclaringClass()->GetDescriptor(&tmp_);
256*795d594fSAndroid Build Coastguard Worker   member_name_ = field->GetNameView();
257*795d594fSAndroid Build Coastguard Worker   type_signature_ = field->GetTypeDescriptorView();
258*795d594fSAndroid Build Coastguard Worker   type_ = kField;
259*795d594fSAndroid Build Coastguard Worker }
260*795d594fSAndroid Build Coastguard Worker 
MemberSignature(ArtMethod * method)261*795d594fSAndroid Build Coastguard Worker MemberSignature::MemberSignature(ArtMethod* method) {
262*795d594fSAndroid Build Coastguard Worker   DCHECK(method == method->GetInterfaceMethodIfProxy(kRuntimePointerSize))
263*795d594fSAndroid Build Coastguard Worker       << "Caller should have replaced proxy method with interface method";
264*795d594fSAndroid Build Coastguard Worker   class_name_ = method->GetDeclaringClassDescriptorView();
265*795d594fSAndroid Build Coastguard Worker   member_name_ = method->GetNameView();
266*795d594fSAndroid Build Coastguard Worker   type_signature_ = method->GetSignature().ToString();
267*795d594fSAndroid Build Coastguard Worker   type_ = kMethod;
268*795d594fSAndroid Build Coastguard Worker }
269*795d594fSAndroid Build Coastguard Worker 
MemberSignature(const ClassAccessor::Field & field)270*795d594fSAndroid Build Coastguard Worker MemberSignature::MemberSignature(const ClassAccessor::Field& field) {
271*795d594fSAndroid Build Coastguard Worker   const DexFile& dex_file = field.GetDexFile();
272*795d594fSAndroid Build Coastguard Worker   const dex::FieldId& field_id = dex_file.GetFieldId(field.GetIndex());
273*795d594fSAndroid Build Coastguard Worker   class_name_ = dex_file.GetFieldDeclaringClassDescriptor(field_id);
274*795d594fSAndroid Build Coastguard Worker   member_name_ = dex_file.GetFieldName(field_id);
275*795d594fSAndroid Build Coastguard Worker   type_signature_ = dex_file.GetFieldTypeDescriptor(field_id);
276*795d594fSAndroid Build Coastguard Worker   type_ = kField;
277*795d594fSAndroid Build Coastguard Worker }
278*795d594fSAndroid Build Coastguard Worker 
MemberSignature(const ClassAccessor::Method & method)279*795d594fSAndroid Build Coastguard Worker MemberSignature::MemberSignature(const ClassAccessor::Method& method) {
280*795d594fSAndroid Build Coastguard Worker   const DexFile& dex_file = method.GetDexFile();
281*795d594fSAndroid Build Coastguard Worker   const dex::MethodId& method_id = dex_file.GetMethodId(method.GetIndex());
282*795d594fSAndroid Build Coastguard Worker   class_name_ = dex_file.GetMethodDeclaringClassDescriptor(method_id);
283*795d594fSAndroid Build Coastguard Worker   member_name_ = dex_file.GetMethodName(method_id);
284*795d594fSAndroid Build Coastguard Worker   type_signature_ = dex_file.GetMethodSignature(method_id).ToString();
285*795d594fSAndroid Build Coastguard Worker   type_ = kMethod;
286*795d594fSAndroid Build Coastguard Worker }
287*795d594fSAndroid Build Coastguard Worker 
GetSignatureParts() const288*795d594fSAndroid Build Coastguard Worker inline std::vector<const char*> MemberSignature::GetSignatureParts() const {
289*795d594fSAndroid Build Coastguard Worker   if (type_ == kField) {
290*795d594fSAndroid Build Coastguard Worker     return {class_name_.c_str(), "->", member_name_.c_str(), ":", type_signature_.c_str()};
291*795d594fSAndroid Build Coastguard Worker   } else {
292*795d594fSAndroid Build Coastguard Worker     DCHECK_EQ(type_, kMethod);
293*795d594fSAndroid Build Coastguard Worker     return {class_name_.c_str(), "->", member_name_.c_str(), type_signature_.c_str()};
294*795d594fSAndroid Build Coastguard Worker   }
295*795d594fSAndroid Build Coastguard Worker }
296*795d594fSAndroid Build Coastguard Worker 
DoesPrefixMatch(const std::string & prefix) const297*795d594fSAndroid Build Coastguard Worker bool MemberSignature::DoesPrefixMatch(const std::string& prefix) const {
298*795d594fSAndroid Build Coastguard Worker   size_t pos = 0;
299*795d594fSAndroid Build Coastguard Worker   for (const char* part : GetSignatureParts()) {
300*795d594fSAndroid Build Coastguard Worker     size_t count = std::min(prefix.length() - pos, strlen(part));
301*795d594fSAndroid Build Coastguard Worker     if (prefix.compare(pos, count, part, 0, count) == 0) {
302*795d594fSAndroid Build Coastguard Worker       pos += count;
303*795d594fSAndroid Build Coastguard Worker     } else {
304*795d594fSAndroid Build Coastguard Worker       return false;
305*795d594fSAndroid Build Coastguard Worker     }
306*795d594fSAndroid Build Coastguard Worker   }
307*795d594fSAndroid Build Coastguard Worker   // We have a complete match if all parts match (we exit the loop without
308*795d594fSAndroid Build Coastguard Worker   // returning) AND we've matched the whole prefix.
309*795d594fSAndroid Build Coastguard Worker   return pos == prefix.length();
310*795d594fSAndroid Build Coastguard Worker }
311*795d594fSAndroid Build Coastguard Worker 
DoesPrefixMatchAny(const std::vector<std::string> & exemptions)312*795d594fSAndroid Build Coastguard Worker bool MemberSignature::DoesPrefixMatchAny(const std::vector<std::string>& exemptions) {
313*795d594fSAndroid Build Coastguard Worker   for (const std::string& exemption : exemptions) {
314*795d594fSAndroid Build Coastguard Worker     if (DoesPrefixMatch(exemption)) {
315*795d594fSAndroid Build Coastguard Worker       return true;
316*795d594fSAndroid Build Coastguard Worker     }
317*795d594fSAndroid Build Coastguard Worker   }
318*795d594fSAndroid Build Coastguard Worker   return false;
319*795d594fSAndroid Build Coastguard Worker }
320*795d594fSAndroid Build Coastguard Worker 
Dump(std::ostream & os) const321*795d594fSAndroid Build Coastguard Worker void MemberSignature::Dump(std::ostream& os) const {
322*795d594fSAndroid Build Coastguard Worker   for (const char* part : GetSignatureParts()) {
323*795d594fSAndroid Build Coastguard Worker     os << part;
324*795d594fSAndroid Build Coastguard Worker   }
325*795d594fSAndroid Build Coastguard Worker }
326*795d594fSAndroid Build Coastguard Worker 
WarnAboutAccess(AccessMethod access_method,hiddenapi::ApiList list,bool access_denied)327*795d594fSAndroid Build Coastguard Worker void MemberSignature::WarnAboutAccess(AccessMethod access_method,
328*795d594fSAndroid Build Coastguard Worker                                       hiddenapi::ApiList list,
329*795d594fSAndroid Build Coastguard Worker                                       bool access_denied) {
330*795d594fSAndroid Build Coastguard Worker   static std::atomic<uint64_t> log_warning_count_ = 0;
331*795d594fSAndroid Build Coastguard Worker   if (log_warning_count_ > kMaxLogWarnings) {
332*795d594fSAndroid Build Coastguard Worker     return;
333*795d594fSAndroid Build Coastguard Worker   }
334*795d594fSAndroid Build Coastguard Worker   LOG(WARNING) << "Accessing hidden " << (type_ == kField ? "field " : "method ")
335*795d594fSAndroid Build Coastguard Worker                << Dumpable<MemberSignature>(*this) << " (" << list << ", " << access_method
336*795d594fSAndroid Build Coastguard Worker                << (access_denied ? ", denied)" : ", allowed)");
337*795d594fSAndroid Build Coastguard Worker   if (access_denied && list.IsTestApi()) {
338*795d594fSAndroid Build Coastguard Worker     // see b/177047045 for more details about test api access getting denied
339*795d594fSAndroid Build Coastguard Worker     LOG(WARNING) << "If this is a platform test consider enabling "
340*795d594fSAndroid Build Coastguard Worker                  << "VMRuntime.ALLOW_TEST_API_ACCESS change id for this package.";
341*795d594fSAndroid Build Coastguard Worker   }
342*795d594fSAndroid Build Coastguard Worker   if (log_warning_count_ >= kMaxLogWarnings) {
343*795d594fSAndroid Build Coastguard Worker     LOG(WARNING) << "Reached maximum number of hidden api access warnings.";
344*795d594fSAndroid Build Coastguard Worker   }
345*795d594fSAndroid Build Coastguard Worker   ++log_warning_count_;
346*795d594fSAndroid Build Coastguard Worker }
347*795d594fSAndroid Build Coastguard Worker 
Equals(const MemberSignature & other)348*795d594fSAndroid Build Coastguard Worker bool MemberSignature::Equals(const MemberSignature& other) {
349*795d594fSAndroid Build Coastguard Worker   return type_ == other.type_ && class_name_ == other.class_name_ &&
350*795d594fSAndroid Build Coastguard Worker          member_name_ == other.member_name_ && type_signature_ == other.type_signature_;
351*795d594fSAndroid Build Coastguard Worker }
352*795d594fSAndroid Build Coastguard Worker 
MemberNameAndTypeMatch(const MemberSignature & other)353*795d594fSAndroid Build Coastguard Worker bool MemberSignature::MemberNameAndTypeMatch(const MemberSignature& other) {
354*795d594fSAndroid Build Coastguard Worker   return member_name_ == other.member_name_ && type_signature_ == other.type_signature_;
355*795d594fSAndroid Build Coastguard Worker }
356*795d594fSAndroid Build Coastguard Worker 
LogAccessToEventLog(uint32_t sampled_value,AccessMethod access_method,bool access_denied)357*795d594fSAndroid Build Coastguard Worker void MemberSignature::LogAccessToEventLog(uint32_t sampled_value,
358*795d594fSAndroid Build Coastguard Worker                                           AccessMethod access_method,
359*795d594fSAndroid Build Coastguard Worker                                           bool access_denied) {
360*795d594fSAndroid Build Coastguard Worker #ifdef ART_TARGET_ANDROID
361*795d594fSAndroid Build Coastguard Worker   if (access_method == AccessMethod::kLinking || access_method == AccessMethod::kNone) {
362*795d594fSAndroid Build Coastguard Worker     // Linking warnings come from static analysis/compilation of the bytecode
363*795d594fSAndroid Build Coastguard Worker     // and can contain false positives (i.e. code that is never run). We choose
364*795d594fSAndroid Build Coastguard Worker     // not to log these in the event log.
365*795d594fSAndroid Build Coastguard Worker     // None does not correspond to actual access, so should also be ignored.
366*795d594fSAndroid Build Coastguard Worker     return;
367*795d594fSAndroid Build Coastguard Worker   }
368*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
369*795d594fSAndroid Build Coastguard Worker   if (runtime->IsAotCompiler()) {
370*795d594fSAndroid Build Coastguard Worker     return;
371*795d594fSAndroid Build Coastguard Worker   }
372*795d594fSAndroid Build Coastguard Worker 
373*795d594fSAndroid Build Coastguard Worker   const std::string& package_name = runtime->GetProcessPackageName();
374*795d594fSAndroid Build Coastguard Worker   std::ostringstream signature_str;
375*795d594fSAndroid Build Coastguard Worker   Dump(signature_str);
376*795d594fSAndroid Build Coastguard Worker 
377*795d594fSAndroid Build Coastguard Worker   ScopedObjectAccess soa(Thread::Current());
378*795d594fSAndroid Build Coastguard Worker   StackHandleScope<2u> hs(soa.Self());
379*795d594fSAndroid Build Coastguard Worker   Handle<mirror::String> package_str =
380*795d594fSAndroid Build Coastguard Worker       hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), package_name.c_str()));
381*795d594fSAndroid Build Coastguard Worker   if (soa.Self()->IsExceptionPending()) {
382*795d594fSAndroid Build Coastguard Worker     soa.Self()->ClearException();
383*795d594fSAndroid Build Coastguard Worker     LOG(ERROR) << "Unable to allocate string for package name which called hidden api";
384*795d594fSAndroid Build Coastguard Worker   }
385*795d594fSAndroid Build Coastguard Worker   Handle<mirror::String> signature_jstr =
386*795d594fSAndroid Build Coastguard Worker       hs.NewHandle(mirror::String::AllocFromModifiedUtf8(soa.Self(), signature_str.str().c_str()));
387*795d594fSAndroid Build Coastguard Worker   if (soa.Self()->IsExceptionPending()) {
388*795d594fSAndroid Build Coastguard Worker     soa.Self()->ClearException();
389*795d594fSAndroid Build Coastguard Worker     LOG(ERROR) << "Unable to allocate string for hidden api method signature";
390*795d594fSAndroid Build Coastguard Worker   }
391*795d594fSAndroid Build Coastguard Worker   WellKnownClasses::dalvik_system_VMRuntime_hiddenApiUsed
392*795d594fSAndroid Build Coastguard Worker       ->InvokeStatic<'V', 'I', 'L', 'L', 'I', 'Z'>(soa.Self(),
393*795d594fSAndroid Build Coastguard Worker                                                    static_cast<jint>(sampled_value),
394*795d594fSAndroid Build Coastguard Worker                                                    package_str.Get(),
395*795d594fSAndroid Build Coastguard Worker                                                    signature_jstr.Get(),
396*795d594fSAndroid Build Coastguard Worker                                                    static_cast<jint>(access_method),
397*795d594fSAndroid Build Coastguard Worker                                                    access_denied);
398*795d594fSAndroid Build Coastguard Worker   if (soa.Self()->IsExceptionPending()) {
399*795d594fSAndroid Build Coastguard Worker     soa.Self()->ClearException();
400*795d594fSAndroid Build Coastguard Worker     LOG(ERROR) << "Unable to report hidden api usage";
401*795d594fSAndroid Build Coastguard Worker   }
402*795d594fSAndroid Build Coastguard Worker #else
403*795d594fSAndroid Build Coastguard Worker   UNUSED(sampled_value);
404*795d594fSAndroid Build Coastguard Worker   UNUSED(access_method);
405*795d594fSAndroid Build Coastguard Worker   UNUSED(access_denied);
406*795d594fSAndroid Build Coastguard Worker #endif
407*795d594fSAndroid Build Coastguard Worker }
408*795d594fSAndroid Build Coastguard Worker 
NotifyHiddenApiListener(AccessMethod access_method)409*795d594fSAndroid Build Coastguard Worker void MemberSignature::NotifyHiddenApiListener(AccessMethod access_method) {
410*795d594fSAndroid Build Coastguard Worker   if (access_method != AccessMethod::kReflection && access_method != AccessMethod::kJNI) {
411*795d594fSAndroid Build Coastguard Worker     // We can only up-call into Java during reflection and JNI down-calls.
412*795d594fSAndroid Build Coastguard Worker     return;
413*795d594fSAndroid Build Coastguard Worker   }
414*795d594fSAndroid Build Coastguard Worker 
415*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
416*795d594fSAndroid Build Coastguard Worker   if (!runtime->IsAotCompiler()) {
417*795d594fSAndroid Build Coastguard Worker     ScopedObjectAccess soa(Thread::Current());
418*795d594fSAndroid Build Coastguard Worker     StackHandleScope<2u> hs(soa.Self());
419*795d594fSAndroid Build Coastguard Worker 
420*795d594fSAndroid Build Coastguard Worker     ArtField* consumer_field = WellKnownClasses::dalvik_system_VMRuntime_nonSdkApiUsageConsumer;
421*795d594fSAndroid Build Coastguard Worker     DCHECK(consumer_field->GetDeclaringClass()->IsInitialized());
422*795d594fSAndroid Build Coastguard Worker     Handle<mirror::Object> consumer_object =
423*795d594fSAndroid Build Coastguard Worker         hs.NewHandle(consumer_field->GetObject(consumer_field->GetDeclaringClass()));
424*795d594fSAndroid Build Coastguard Worker 
425*795d594fSAndroid Build Coastguard Worker     // If the consumer is non-null, we call back to it to let it know that we
426*795d594fSAndroid Build Coastguard Worker     // have encountered an API that's in one of our lists.
427*795d594fSAndroid Build Coastguard Worker     if (consumer_object != nullptr) {
428*795d594fSAndroid Build Coastguard Worker       std::ostringstream member_signature_str;
429*795d594fSAndroid Build Coastguard Worker       Dump(member_signature_str);
430*795d594fSAndroid Build Coastguard Worker 
431*795d594fSAndroid Build Coastguard Worker       Handle<mirror::String> signature_str = hs.NewHandle(
432*795d594fSAndroid Build Coastguard Worker           mirror::String::AllocFromModifiedUtf8(soa.Self(), member_signature_str.str().c_str()));
433*795d594fSAndroid Build Coastguard Worker       // FIXME: Handle OOME. For now, crash immediatelly (do not continue with a pending exception).
434*795d594fSAndroid Build Coastguard Worker       CHECK(signature_str != nullptr);
435*795d594fSAndroid Build Coastguard Worker 
436*795d594fSAndroid Build Coastguard Worker       // Call through to Consumer.accept(String memberSignature);
437*795d594fSAndroid Build Coastguard Worker       WellKnownClasses::java_util_function_Consumer_accept->InvokeInterface<'V', 'L'>(
438*795d594fSAndroid Build Coastguard Worker           soa.Self(), consumer_object.Get(), signature_str.Get());
439*795d594fSAndroid Build Coastguard Worker     }
440*795d594fSAndroid Build Coastguard Worker   }
441*795d594fSAndroid Build Coastguard Worker }
442*795d594fSAndroid Build Coastguard Worker 
CanUpdateRuntimeFlags(ArtField *)443*795d594fSAndroid Build Coastguard Worker static ALWAYS_INLINE bool CanUpdateRuntimeFlags(ArtField*) { return true; }
444*795d594fSAndroid Build Coastguard Worker 
CanUpdateRuntimeFlags(ArtMethod * method)445*795d594fSAndroid Build Coastguard Worker static ALWAYS_INLINE bool CanUpdateRuntimeFlags(ArtMethod* method) {
446*795d594fSAndroid Build Coastguard Worker   return !method->IsIntrinsic();
447*795d594fSAndroid Build Coastguard Worker }
448*795d594fSAndroid Build Coastguard Worker 
449*795d594fSAndroid Build Coastguard Worker template <typename T>
MaybeUpdateAccessFlags(Runtime * runtime,T * member,uint32_t flag)450*795d594fSAndroid Build Coastguard Worker static ALWAYS_INLINE void MaybeUpdateAccessFlags(Runtime* runtime, T* member, uint32_t flag)
451*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
452*795d594fSAndroid Build Coastguard Worker   // Update the access flags unless:
453*795d594fSAndroid Build Coastguard Worker   // (a) `member` is an intrinsic
454*795d594fSAndroid Build Coastguard Worker   // (b) this is AOT compiler, as we do not want the updated access flags in the boot/app image
455*795d594fSAndroid Build Coastguard Worker   // (c) deduping warnings has been explicitly switched off.
456*795d594fSAndroid Build Coastguard Worker   if (CanUpdateRuntimeFlags(member) && !runtime->IsAotCompiler() &&
457*795d594fSAndroid Build Coastguard Worker       runtime->ShouldDedupeHiddenApiWarnings()) {
458*795d594fSAndroid Build Coastguard Worker     member->SetAccessFlags(member->GetAccessFlags() | flag);
459*795d594fSAndroid Build Coastguard Worker   }
460*795d594fSAndroid Build Coastguard Worker }
461*795d594fSAndroid Build Coastguard Worker 
GetMemberDexIndex(ArtField * field)462*795d594fSAndroid Build Coastguard Worker static ALWAYS_INLINE uint32_t GetMemberDexIndex(ArtField* field) {
463*795d594fSAndroid Build Coastguard Worker   return field->GetDexFieldIndex();
464*795d594fSAndroid Build Coastguard Worker }
465*795d594fSAndroid Build Coastguard Worker 
GetMemberDexIndex(ArtMethod * method)466*795d594fSAndroid Build Coastguard Worker static ALWAYS_INLINE uint32_t GetMemberDexIndex(ArtMethod* method)
467*795d594fSAndroid Build Coastguard Worker     REQUIRES_SHARED(Locks::mutator_lock_) {
468*795d594fSAndroid Build Coastguard Worker   // Use the non-obsolete method to avoid DexFile mismatch between
469*795d594fSAndroid Build Coastguard Worker   // the method index and the declaring class.
470*795d594fSAndroid Build Coastguard Worker   return method->GetNonObsoleteMethod()->GetDexMethodIndex();
471*795d594fSAndroid Build Coastguard Worker }
472*795d594fSAndroid Build Coastguard Worker 
VisitMembers(const DexFile & dex_file,const dex::ClassDef & class_def,const std::function<void (const ClassAccessor::Field &)> & fn_visit)473*795d594fSAndroid Build Coastguard Worker static void VisitMembers(const DexFile& dex_file,
474*795d594fSAndroid Build Coastguard Worker                          const dex::ClassDef& class_def,
475*795d594fSAndroid Build Coastguard Worker                          const std::function<void(const ClassAccessor::Field&)>& fn_visit) {
476*795d594fSAndroid Build Coastguard Worker   ClassAccessor accessor(dex_file, class_def, /* parse_hiddenapi_class_data= */ true);
477*795d594fSAndroid Build Coastguard Worker   accessor.VisitFields(fn_visit, fn_visit);
478*795d594fSAndroid Build Coastguard Worker }
479*795d594fSAndroid Build Coastguard Worker 
VisitMembers(const DexFile & dex_file,const dex::ClassDef & class_def,const std::function<void (const ClassAccessor::Method &)> & fn_visit)480*795d594fSAndroid Build Coastguard Worker static void VisitMembers(const DexFile& dex_file,
481*795d594fSAndroid Build Coastguard Worker                          const dex::ClassDef& class_def,
482*795d594fSAndroid Build Coastguard Worker                          const std::function<void(const ClassAccessor::Method&)>& fn_visit) {
483*795d594fSAndroid Build Coastguard Worker   ClassAccessor accessor(dex_file, class_def, /* parse_hiddenapi_class_data= */ true);
484*795d594fSAndroid Build Coastguard Worker   accessor.VisitMethods(fn_visit, fn_visit);
485*795d594fSAndroid Build Coastguard Worker }
486*795d594fSAndroid Build Coastguard Worker 
487*795d594fSAndroid Build Coastguard Worker template <typename T>
GetDexFlags(T * member)488*795d594fSAndroid Build Coastguard Worker uint32_t GetDexFlags(T* member) REQUIRES_SHARED(Locks::mutator_lock_) {
489*795d594fSAndroid Build Coastguard Worker   static_assert(std::is_same<T, ArtField>::value || std::is_same<T, ArtMethod>::value);
490*795d594fSAndroid Build Coastguard Worker   constexpr bool kMemberIsField = std::is_same<T, ArtField>::value;
491*795d594fSAndroid Build Coastguard Worker   using AccessorType = typename std::conditional<std::is_same<T, ArtField>::value,
492*795d594fSAndroid Build Coastguard Worker                                                  ClassAccessor::Field,
493*795d594fSAndroid Build Coastguard Worker                                                  ClassAccessor::Method>::type;
494*795d594fSAndroid Build Coastguard Worker 
495*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::Class> declaring_class = member->GetDeclaringClass();
496*795d594fSAndroid Build Coastguard Worker   DCHECK(!declaring_class.IsNull()) << "Attempting to access a runtime method";
497*795d594fSAndroid Build Coastguard Worker 
498*795d594fSAndroid Build Coastguard Worker   ApiList flags;
499*795d594fSAndroid Build Coastguard Worker   DCHECK(!flags.IsValid());
500*795d594fSAndroid Build Coastguard Worker 
501*795d594fSAndroid Build Coastguard Worker   // Check if the declaring class has ClassExt allocated. If it does, check if
502*795d594fSAndroid Build Coastguard Worker   // the pre-JVMTI redefine dex file has been set to determine if the declaring
503*795d594fSAndroid Build Coastguard Worker   // class has been JVMTI-redefined.
504*795d594fSAndroid Build Coastguard Worker   ObjPtr<mirror::ClassExt> ext(declaring_class->GetExtData());
505*795d594fSAndroid Build Coastguard Worker   const DexFile* original_dex = ext.IsNull() ? nullptr : ext->GetPreRedefineDexFile();
506*795d594fSAndroid Build Coastguard Worker   if (LIKELY(original_dex == nullptr)) {
507*795d594fSAndroid Build Coastguard Worker     // Class is not redefined. Find the class def, iterate over its members and
508*795d594fSAndroid Build Coastguard Worker     // find the entry corresponding to this `member`.
509*795d594fSAndroid Build Coastguard Worker     const dex::ClassDef* class_def = declaring_class->GetClassDef();
510*795d594fSAndroid Build Coastguard Worker     if (class_def == nullptr) {
511*795d594fSAndroid Build Coastguard Worker       // ClassDef is not set for proxy classes. Only their fields can ever be inspected.
512*795d594fSAndroid Build Coastguard Worker       DCHECK(declaring_class->IsProxyClass())
513*795d594fSAndroid Build Coastguard Worker           << "Only proxy classes are expected not to have a class def";
514*795d594fSAndroid Build Coastguard Worker       DCHECK(kMemberIsField)
515*795d594fSAndroid Build Coastguard Worker           << "Interface methods should be inspected instead of proxy class methods";
516*795d594fSAndroid Build Coastguard Worker       flags = ApiList::Unsupported();
517*795d594fSAndroid Build Coastguard Worker     } else {
518*795d594fSAndroid Build Coastguard Worker       uint32_t member_index = GetMemberDexIndex(member);
519*795d594fSAndroid Build Coastguard Worker       auto fn_visit = [&](const AccessorType& dex_member) {
520*795d594fSAndroid Build Coastguard Worker         if (dex_member.GetIndex() == member_index) {
521*795d594fSAndroid Build Coastguard Worker           flags = ApiList(dex_member.GetHiddenapiFlags());
522*795d594fSAndroid Build Coastguard Worker         }
523*795d594fSAndroid Build Coastguard Worker       };
524*795d594fSAndroid Build Coastguard Worker       VisitMembers(declaring_class->GetDexFile(), *class_def, fn_visit);
525*795d594fSAndroid Build Coastguard Worker     }
526*795d594fSAndroid Build Coastguard Worker   } else {
527*795d594fSAndroid Build Coastguard Worker     // Class was redefined using JVMTI. We have a pointer to the original dex file
528*795d594fSAndroid Build Coastguard Worker     // and the class def index of this class in that dex file, but the field/method
529*795d594fSAndroid Build Coastguard Worker     // indices are lost. Iterate over all members of the class def and find the one
530*795d594fSAndroid Build Coastguard Worker     // corresponding to this `member` by name and type string comparison.
531*795d594fSAndroid Build Coastguard Worker     // This is obviously very slow, but it is only used when non-exempt code tries
532*795d594fSAndroid Build Coastguard Worker     // to access a hidden member of a JVMTI-redefined class.
533*795d594fSAndroid Build Coastguard Worker     uint16_t class_def_idx = ext->GetPreRedefineClassDefIndex();
534*795d594fSAndroid Build Coastguard Worker     DCHECK_NE(class_def_idx, DexFile::kDexNoIndex16);
535*795d594fSAndroid Build Coastguard Worker     const dex::ClassDef& original_class_def = original_dex->GetClassDef(class_def_idx);
536*795d594fSAndroid Build Coastguard Worker     MemberSignature member_signature(member);
537*795d594fSAndroid Build Coastguard Worker     auto fn_visit = [&](const AccessorType& dex_member) {
538*795d594fSAndroid Build Coastguard Worker       MemberSignature cur_signature(dex_member);
539*795d594fSAndroid Build Coastguard Worker       if (member_signature.MemberNameAndTypeMatch(cur_signature)) {
540*795d594fSAndroid Build Coastguard Worker         DCHECK(member_signature.Equals(cur_signature));
541*795d594fSAndroid Build Coastguard Worker         flags = ApiList(dex_member.GetHiddenapiFlags());
542*795d594fSAndroid Build Coastguard Worker       }
543*795d594fSAndroid Build Coastguard Worker     };
544*795d594fSAndroid Build Coastguard Worker     VisitMembers(*original_dex, original_class_def, fn_visit);
545*795d594fSAndroid Build Coastguard Worker   }
546*795d594fSAndroid Build Coastguard Worker 
547*795d594fSAndroid Build Coastguard Worker   CHECK(flags.IsValid()) << "Could not find hiddenapi flags for "
548*795d594fSAndroid Build Coastguard Worker                          << Dumpable<MemberSignature>(MemberSignature(member));
549*795d594fSAndroid Build Coastguard Worker   return flags.GetDexFlags();
550*795d594fSAndroid Build Coastguard Worker }
551*795d594fSAndroid Build Coastguard Worker 
552*795d594fSAndroid Build Coastguard Worker template <typename T>
HandleCorePlatformApiViolation(T * member,const AccessContext & caller_context,AccessMethod access_method,EnforcementPolicy policy)553*795d594fSAndroid Build Coastguard Worker bool HandleCorePlatformApiViolation(T* member,
554*795d594fSAndroid Build Coastguard Worker                                     const AccessContext& caller_context,
555*795d594fSAndroid Build Coastguard Worker                                     AccessMethod access_method,
556*795d594fSAndroid Build Coastguard Worker                                     EnforcementPolicy policy) {
557*795d594fSAndroid Build Coastguard Worker   DCHECK(policy != EnforcementPolicy::kDisabled)
558*795d594fSAndroid Build Coastguard Worker       << "Should never enter this function when access checks are completely disabled";
559*795d594fSAndroid Build Coastguard Worker 
560*795d594fSAndroid Build Coastguard Worker   if (access_method != AccessMethod::kNone) {
561*795d594fSAndroid Build Coastguard Worker     LOG(WARNING) << "Core platform API violation: "
562*795d594fSAndroid Build Coastguard Worker                  << Dumpable<MemberSignature>(MemberSignature(member)) << " from " << caller_context
563*795d594fSAndroid Build Coastguard Worker                  << " using " << access_method;
564*795d594fSAndroid Build Coastguard Worker 
565*795d594fSAndroid Build Coastguard Worker     // If policy is set to just warn, add kAccCorePlatformApi to access flags of
566*795d594fSAndroid Build Coastguard Worker     // `member` to avoid reporting the violation again next time.
567*795d594fSAndroid Build Coastguard Worker     if (policy == EnforcementPolicy::kJustWarn) {
568*795d594fSAndroid Build Coastguard Worker       MaybeUpdateAccessFlags(Runtime::Current(), member, kAccCorePlatformApi);
569*795d594fSAndroid Build Coastguard Worker     }
570*795d594fSAndroid Build Coastguard Worker   }
571*795d594fSAndroid Build Coastguard Worker 
572*795d594fSAndroid Build Coastguard Worker   // Deny access if enforcement is enabled.
573*795d594fSAndroid Build Coastguard Worker   return policy == EnforcementPolicy::kEnabled;
574*795d594fSAndroid Build Coastguard Worker }
575*795d594fSAndroid Build Coastguard Worker 
576*795d594fSAndroid Build Coastguard Worker template <typename T>
ShouldDenyAccessToMemberImpl(T * member,ApiList api_list,AccessMethod access_method)577*795d594fSAndroid Build Coastguard Worker bool ShouldDenyAccessToMemberImpl(T* member, ApiList api_list, AccessMethod access_method) {
578*795d594fSAndroid Build Coastguard Worker   DCHECK(member != nullptr);
579*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
580*795d594fSAndroid Build Coastguard Worker   CompatFramework& compatFramework = runtime->GetCompatFramework();
581*795d594fSAndroid Build Coastguard Worker 
582*795d594fSAndroid Build Coastguard Worker   EnforcementPolicy hiddenApiPolicy = runtime->GetHiddenApiEnforcementPolicy();
583*795d594fSAndroid Build Coastguard Worker   DCHECK(hiddenApiPolicy != EnforcementPolicy::kDisabled)
584*795d594fSAndroid Build Coastguard Worker       << "Should never enter this function when access checks are completely disabled";
585*795d594fSAndroid Build Coastguard Worker 
586*795d594fSAndroid Build Coastguard Worker   MemberSignature member_signature(member);
587*795d594fSAndroid Build Coastguard Worker 
588*795d594fSAndroid Build Coastguard Worker   // Check for an exemption first. Exempted APIs are treated as SDK.
589*795d594fSAndroid Build Coastguard Worker   if (member_signature.DoesPrefixMatchAny(runtime->GetHiddenApiExemptions())) {
590*795d594fSAndroid Build Coastguard Worker     // Avoid re-examining the exemption list next time.
591*795d594fSAndroid Build Coastguard Worker     // Note this results in no warning for the member, which seems like what one would expect.
592*795d594fSAndroid Build Coastguard Worker     // Exemptions effectively adds new members to the public API list.
593*795d594fSAndroid Build Coastguard Worker     MaybeUpdateAccessFlags(runtime, member, kAccPublicApi);
594*795d594fSAndroid Build Coastguard Worker     return false;
595*795d594fSAndroid Build Coastguard Worker   }
596*795d594fSAndroid Build Coastguard Worker 
597*795d594fSAndroid Build Coastguard Worker   EnforcementPolicy testApiPolicy = runtime->GetTestApiEnforcementPolicy();
598*795d594fSAndroid Build Coastguard Worker 
599*795d594fSAndroid Build Coastguard Worker   bool deny_access = false;
600*795d594fSAndroid Build Coastguard Worker   if (hiddenApiPolicy == EnforcementPolicy::kEnabled) {
601*795d594fSAndroid Build Coastguard Worker     if (api_list.IsTestApi() && (testApiPolicy == EnforcementPolicy::kDisabled ||
602*795d594fSAndroid Build Coastguard Worker                                  compatFramework.IsChangeEnabled(kAllowTestApiAccess))) {
603*795d594fSAndroid Build Coastguard Worker       deny_access = false;
604*795d594fSAndroid Build Coastguard Worker     } else {
605*795d594fSAndroid Build Coastguard Worker       switch (api_list.GetMaxAllowedSdkVersion()) {
606*795d594fSAndroid Build Coastguard Worker         case SdkVersion::kP:
607*795d594fSAndroid Build Coastguard Worker           deny_access = compatFramework.IsChangeEnabled(kHideMaxtargetsdkPHiddenApis);
608*795d594fSAndroid Build Coastguard Worker           break;
609*795d594fSAndroid Build Coastguard Worker         case SdkVersion::kQ:
610*795d594fSAndroid Build Coastguard Worker           deny_access = compatFramework.IsChangeEnabled(kHideMaxtargetsdkQHiddenApis);
611*795d594fSAndroid Build Coastguard Worker           break;
612*795d594fSAndroid Build Coastguard Worker         default:
613*795d594fSAndroid Build Coastguard Worker           deny_access = IsSdkVersionSetAndMoreThan(runtime->GetTargetSdkVersion(),
614*795d594fSAndroid Build Coastguard Worker                                                    api_list.GetMaxAllowedSdkVersion());
615*795d594fSAndroid Build Coastguard Worker       }
616*795d594fSAndroid Build Coastguard Worker     }
617*795d594fSAndroid Build Coastguard Worker   }
618*795d594fSAndroid Build Coastguard Worker 
619*795d594fSAndroid Build Coastguard Worker   if (access_method != AccessMethod::kNone) {
620*795d594fSAndroid Build Coastguard Worker     // Warn if blocked signature is being accessed or it is not exempted.
621*795d594fSAndroid Build Coastguard Worker     if (deny_access || !member_signature.DoesPrefixMatchAny(kWarningExemptions)) {
622*795d594fSAndroid Build Coastguard Worker       // Print a log message with information about this class member access.
623*795d594fSAndroid Build Coastguard Worker       // We do this if we're about to deny access, or the app is debuggable.
624*795d594fSAndroid Build Coastguard Worker       if (kLogAllAccesses || deny_access || runtime->IsJavaDebuggable()) {
625*795d594fSAndroid Build Coastguard Worker         member_signature.WarnAboutAccess(access_method, api_list, deny_access);
626*795d594fSAndroid Build Coastguard Worker       }
627*795d594fSAndroid Build Coastguard Worker 
628*795d594fSAndroid Build Coastguard Worker       // If there is a StrictMode listener, notify it about this violation.
629*795d594fSAndroid Build Coastguard Worker       member_signature.NotifyHiddenApiListener(access_method);
630*795d594fSAndroid Build Coastguard Worker     }
631*795d594fSAndroid Build Coastguard Worker 
632*795d594fSAndroid Build Coastguard Worker     // If event log sampling is enabled, report this violation.
633*795d594fSAndroid Build Coastguard Worker     if (kIsTargetBuild && !kIsTargetLinux) {
634*795d594fSAndroid Build Coastguard Worker       uint32_t eventLogSampleRate = runtime->GetHiddenApiEventLogSampleRate();
635*795d594fSAndroid Build Coastguard Worker       // Assert that RAND_MAX is big enough, to ensure sampling below works as expected.
636*795d594fSAndroid Build Coastguard Worker       static_assert(RAND_MAX >= 0xffff, "RAND_MAX too small");
637*795d594fSAndroid Build Coastguard Worker       if (eventLogSampleRate != 0) {
638*795d594fSAndroid Build Coastguard Worker         const uint32_t sampled_value = static_cast<uint32_t>(std::rand()) & 0xffff;
639*795d594fSAndroid Build Coastguard Worker         if (sampled_value <= eventLogSampleRate) {
640*795d594fSAndroid Build Coastguard Worker           member_signature.LogAccessToEventLog(sampled_value, access_method, deny_access);
641*795d594fSAndroid Build Coastguard Worker         }
642*795d594fSAndroid Build Coastguard Worker       }
643*795d594fSAndroid Build Coastguard Worker     }
644*795d594fSAndroid Build Coastguard Worker 
645*795d594fSAndroid Build Coastguard Worker     // If this access was not denied, flag member as SDK and skip
646*795d594fSAndroid Build Coastguard Worker     // the warning the next time the member is accessed. Don't update for
647*795d594fSAndroid Build Coastguard Worker     // non-debuggable apps as this has a memory cost.
648*795d594fSAndroid Build Coastguard Worker     if (!deny_access && runtime->IsJavaDebuggable()) {
649*795d594fSAndroid Build Coastguard Worker       MaybeUpdateAccessFlags(runtime, member, kAccPublicApi);
650*795d594fSAndroid Build Coastguard Worker     }
651*795d594fSAndroid Build Coastguard Worker   }
652*795d594fSAndroid Build Coastguard Worker 
653*795d594fSAndroid Build Coastguard Worker   return deny_access;
654*795d594fSAndroid Build Coastguard Worker }
655*795d594fSAndroid Build Coastguard Worker 
656*795d594fSAndroid Build Coastguard Worker // Need to instantiate these.
657*795d594fSAndroid Build Coastguard Worker template uint32_t GetDexFlags<ArtField>(ArtField* member);
658*795d594fSAndroid Build Coastguard Worker template uint32_t GetDexFlags<ArtMethod>(ArtMethod* member);
659*795d594fSAndroid Build Coastguard Worker template bool HandleCorePlatformApiViolation(ArtField* member,
660*795d594fSAndroid Build Coastguard Worker                                              const AccessContext& caller_context,
661*795d594fSAndroid Build Coastguard Worker                                              AccessMethod access_method,
662*795d594fSAndroid Build Coastguard Worker                                              EnforcementPolicy policy);
663*795d594fSAndroid Build Coastguard Worker template bool HandleCorePlatformApiViolation(ArtMethod* member,
664*795d594fSAndroid Build Coastguard Worker                                              const AccessContext& caller_context,
665*795d594fSAndroid Build Coastguard Worker                                              AccessMethod access_method,
666*795d594fSAndroid Build Coastguard Worker                                              EnforcementPolicy policy);
667*795d594fSAndroid Build Coastguard Worker template bool ShouldDenyAccessToMemberImpl<ArtField>(ArtField* member,
668*795d594fSAndroid Build Coastguard Worker                                                      ApiList api_list,
669*795d594fSAndroid Build Coastguard Worker                                                      AccessMethod access_method);
670*795d594fSAndroid Build Coastguard Worker template bool ShouldDenyAccessToMemberImpl<ArtMethod>(ArtMethod* member,
671*795d594fSAndroid Build Coastguard Worker                                                       ApiList api_list,
672*795d594fSAndroid Build Coastguard Worker                                                       AccessMethod access_method);
673*795d594fSAndroid Build Coastguard Worker }  // namespace detail
674*795d594fSAndroid Build Coastguard Worker 
675*795d594fSAndroid Build Coastguard Worker template <typename T>
ShouldDenyAccessToMember(T * member,const std::function<AccessContext ()> & fn_get_access_context,AccessMethod access_method)676*795d594fSAndroid Build Coastguard Worker bool ShouldDenyAccessToMember(T* member,
677*795d594fSAndroid Build Coastguard Worker                               const std::function<AccessContext()>& fn_get_access_context,
678*795d594fSAndroid Build Coastguard Worker                               AccessMethod access_method) {
679*795d594fSAndroid Build Coastguard Worker   DCHECK(member != nullptr);
680*795d594fSAndroid Build Coastguard Worker 
681*795d594fSAndroid Build Coastguard Worker   // First check if we have an explicit sdk checker installed that should be used to
682*795d594fSAndroid Build Coastguard Worker   // verify access. If so, make the decision based on it.
683*795d594fSAndroid Build Coastguard Worker   //
684*795d594fSAndroid Build Coastguard Worker   // This is used during off-device AOT compilation which may want to generate verification
685*795d594fSAndroid Build Coastguard Worker   // metadata only for a specific list of public SDKs. Note that the check here is made
686*795d594fSAndroid Build Coastguard Worker   // based on descriptor equality and it's aim to further restrict a symbol that would
687*795d594fSAndroid Build Coastguard Worker   // otherwise be resolved.
688*795d594fSAndroid Build Coastguard Worker   //
689*795d594fSAndroid Build Coastguard Worker   // The check only applies to boot classpaths dex files.
690*795d594fSAndroid Build Coastguard Worker   Runtime* runtime = Runtime::Current();
691*795d594fSAndroid Build Coastguard Worker   if (UNLIKELY(runtime->IsAotCompiler())) {
692*795d594fSAndroid Build Coastguard Worker     if (member->GetDeclaringClass()->IsBootStrapClassLoaded() &&
693*795d594fSAndroid Build Coastguard Worker         runtime->GetClassLinker()->DenyAccessBasedOnPublicSdk(member)) {
694*795d594fSAndroid Build Coastguard Worker       return true;
695*795d594fSAndroid Build Coastguard Worker     }
696*795d594fSAndroid Build Coastguard Worker   }
697*795d594fSAndroid Build Coastguard Worker 
698*795d594fSAndroid Build Coastguard Worker   // Get the runtime flags encoded in member's access flags.
699*795d594fSAndroid Build Coastguard Worker   // Note: this works for proxy methods because they inherit access flags from their
700*795d594fSAndroid Build Coastguard Worker   // respective interface methods.
701*795d594fSAndroid Build Coastguard Worker   const uint32_t runtime_flags = GetRuntimeFlags(member);
702*795d594fSAndroid Build Coastguard Worker 
703*795d594fSAndroid Build Coastguard Worker   // Exit early if member is public API. This flag is also set for non-boot class
704*795d594fSAndroid Build Coastguard Worker   // path fields/methods.
705*795d594fSAndroid Build Coastguard Worker   if ((runtime_flags & kAccPublicApi) != 0) {
706*795d594fSAndroid Build Coastguard Worker     return false;
707*795d594fSAndroid Build Coastguard Worker   }
708*795d594fSAndroid Build Coastguard Worker 
709*795d594fSAndroid Build Coastguard Worker   // Determine which domain the caller and callee belong to.
710*795d594fSAndroid Build Coastguard Worker   // This can be *very* expensive. This is why ShouldDenyAccessToMember
711*795d594fSAndroid Build Coastguard Worker   // should not be called on every individual access.
712*795d594fSAndroid Build Coastguard Worker   const AccessContext caller_context = fn_get_access_context();
713*795d594fSAndroid Build Coastguard Worker   const AccessContext callee_context(member->GetDeclaringClass());
714*795d594fSAndroid Build Coastguard Worker 
715*795d594fSAndroid Build Coastguard Worker   // Non-boot classpath callers should have exited early.
716*795d594fSAndroid Build Coastguard Worker   DCHECK(!callee_context.IsApplicationDomain());
717*795d594fSAndroid Build Coastguard Worker 
718*795d594fSAndroid Build Coastguard Worker   // Check if the caller is always allowed to access members in the callee context.
719*795d594fSAndroid Build Coastguard Worker   if (caller_context.CanAlwaysAccess(callee_context)) {
720*795d594fSAndroid Build Coastguard Worker     return false;
721*795d594fSAndroid Build Coastguard Worker   }
722*795d594fSAndroid Build Coastguard Worker 
723*795d594fSAndroid Build Coastguard Worker   // Check if this is platform accessing core platform. We may warn if `member` is
724*795d594fSAndroid Build Coastguard Worker   // not part of core platform API.
725*795d594fSAndroid Build Coastguard Worker   switch (caller_context.GetDomain()) {
726*795d594fSAndroid Build Coastguard Worker     case Domain::kApplication: {
727*795d594fSAndroid Build Coastguard Worker       DCHECK(!callee_context.IsApplicationDomain());
728*795d594fSAndroid Build Coastguard Worker 
729*795d594fSAndroid Build Coastguard Worker       // Exit early if access checks are completely disabled.
730*795d594fSAndroid Build Coastguard Worker       EnforcementPolicy policy = runtime->GetHiddenApiEnforcementPolicy();
731*795d594fSAndroid Build Coastguard Worker       if (policy == EnforcementPolicy::kDisabled) {
732*795d594fSAndroid Build Coastguard Worker         return false;
733*795d594fSAndroid Build Coastguard Worker       }
734*795d594fSAndroid Build Coastguard Worker 
735*795d594fSAndroid Build Coastguard Worker       // If this is a proxy method, look at the interface method instead.
736*795d594fSAndroid Build Coastguard Worker       member = detail::GetInterfaceMemberIfProxy(member);
737*795d594fSAndroid Build Coastguard Worker 
738*795d594fSAndroid Build Coastguard Worker       // Decode hidden API access flags from the dex file.
739*795d594fSAndroid Build Coastguard Worker       // This is an O(N) operation scaling with the number of fields/methods
740*795d594fSAndroid Build Coastguard Worker       // in the class. Only do this on slow path and only do it once.
741*795d594fSAndroid Build Coastguard Worker       ApiList api_list(detail::GetDexFlags(member));
742*795d594fSAndroid Build Coastguard Worker       DCHECK(api_list.IsValid());
743*795d594fSAndroid Build Coastguard Worker 
744*795d594fSAndroid Build Coastguard Worker       // Member is hidden and caller is not exempted. Enter slow path.
745*795d594fSAndroid Build Coastguard Worker       return detail::ShouldDenyAccessToMemberImpl(member, api_list, access_method);
746*795d594fSAndroid Build Coastguard Worker     }
747*795d594fSAndroid Build Coastguard Worker 
748*795d594fSAndroid Build Coastguard Worker     case Domain::kPlatform: {
749*795d594fSAndroid Build Coastguard Worker       DCHECK(callee_context.GetDomain() == Domain::kCorePlatform);
750*795d594fSAndroid Build Coastguard Worker 
751*795d594fSAndroid Build Coastguard Worker       // Member is part of core platform API. Accessing it is allowed.
752*795d594fSAndroid Build Coastguard Worker       if ((runtime_flags & kAccCorePlatformApi) != 0) {
753*795d594fSAndroid Build Coastguard Worker         return false;
754*795d594fSAndroid Build Coastguard Worker       }
755*795d594fSAndroid Build Coastguard Worker 
756*795d594fSAndroid Build Coastguard Worker       // Allow access if access checks are disabled.
757*795d594fSAndroid Build Coastguard Worker       EnforcementPolicy policy = Runtime::Current()->GetCorePlatformApiEnforcementPolicy();
758*795d594fSAndroid Build Coastguard Worker       if (policy == EnforcementPolicy::kDisabled) {
759*795d594fSAndroid Build Coastguard Worker         return false;
760*795d594fSAndroid Build Coastguard Worker       }
761*795d594fSAndroid Build Coastguard Worker 
762*795d594fSAndroid Build Coastguard Worker       // If this is a proxy method, look at the interface method instead.
763*795d594fSAndroid Build Coastguard Worker       member = detail::GetInterfaceMemberIfProxy(member);
764*795d594fSAndroid Build Coastguard Worker 
765*795d594fSAndroid Build Coastguard Worker       // Access checks are not disabled, report the violation.
766*795d594fSAndroid Build Coastguard Worker       // This may also add kAccCorePlatformApi to the access flags of `member`
767*795d594fSAndroid Build Coastguard Worker       // so as to not warn again on next access.
768*795d594fSAndroid Build Coastguard Worker       return detail::HandleCorePlatformApiViolation(member, caller_context, access_method, policy);
769*795d594fSAndroid Build Coastguard Worker     }
770*795d594fSAndroid Build Coastguard Worker 
771*795d594fSAndroid Build Coastguard Worker     case Domain::kCorePlatform: {
772*795d594fSAndroid Build Coastguard Worker       LOG(FATAL) << "CorePlatform domain should be allowed to access all domains";
773*795d594fSAndroid Build Coastguard Worker       UNREACHABLE();
774*795d594fSAndroid Build Coastguard Worker     }
775*795d594fSAndroid Build Coastguard Worker   }
776*795d594fSAndroid Build Coastguard Worker }
777*795d594fSAndroid Build Coastguard Worker 
778*795d594fSAndroid Build Coastguard Worker // Need to instantiate these.
779*795d594fSAndroid Build Coastguard Worker template bool ShouldDenyAccessToMember<ArtField>(
780*795d594fSAndroid Build Coastguard Worker     ArtField* member,
781*795d594fSAndroid Build Coastguard Worker     const std::function<AccessContext()>& fn_get_access_context,
782*795d594fSAndroid Build Coastguard Worker     AccessMethod access_method);
783*795d594fSAndroid Build Coastguard Worker template bool ShouldDenyAccessToMember<ArtMethod>(
784*795d594fSAndroid Build Coastguard Worker     ArtMethod* member,
785*795d594fSAndroid Build Coastguard Worker     const std::function<AccessContext()>& fn_get_access_context,
786*795d594fSAndroid Build Coastguard Worker     AccessMethod access_method);
787*795d594fSAndroid Build Coastguard Worker 
788*795d594fSAndroid Build Coastguard Worker }  // namespace hiddenapi
789*795d594fSAndroid Build Coastguard Worker }  // namespace art
790