Adding Class.getDeclaredFields to unstarted runtime
As part of the update of java.util.concurrent to 11+28, it is
needed to have Class.getDeclaredFields() called from the
unstarted runtime.
Test: m
Bug: 188889082
Change-Id: I0ad4629ba1f55165c6c4a14cad823735c9f8cd02
diff --git a/runtime/hidden_api.cc b/runtime/hidden_api.cc
index 9e2ad92..365bace 100644
--- a/runtime/hidden_api.cc
+++ b/runtime/hidden_api.cc
@@ -21,14 +21,17 @@
#include "art_field-inl.h"
#include "art_method-inl.h"
+#include "class_root-inl.h"
#include "compat_framework.h"
#include "base/dumpable.h"
#include "base/file_utils.h"
#include "dex/class_accessor-inl.h"
#include "dex/dex_file_loader.h"
#include "mirror/class_ext.h"
+#include "mirror/proxy.h"
#include "oat_file.h"
#include "scoped_thread_state_change.h"
+#include "stack.h"
#include "thread-inl.h"
#include "well_known_classes.h"
@@ -45,6 +48,10 @@
static constexpr uint64_t kMaxLogWarnings = 100;
+// Should be the same as dalvik.system.VMRuntime.PREVENT_META_REFLECTION_BLOCKLIST_ACCESS.
+// Corresponds to a bug id.
+static constexpr uint64_t kPreventMetaReflectionBlocklistAccess = 142365358;
+
// Set to true if we should always print a warning in logcat for all hidden API accesses, not just
// conditionally and unconditionally blocked. This can be set to true for developer preview / beta
// builds, but should be false for public release builds.
@@ -160,6 +167,75 @@
}
}
+hiddenapi::AccessContext GetReflectionCallerAccessContext(Thread* self)
+ REQUIRES_SHARED(Locks::mutator_lock_) {
+ // Walk the stack and find the first frame not from java.lang.Class,
+ // java.lang.invoke or java.lang.reflect. This is very expensive.
+ // Save this till the last.
+ struct FirstExternalCallerVisitor : public StackVisitor {
+ explicit FirstExternalCallerVisitor(Thread* thread)
+ : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
+ caller(nullptr) {
+ }
+
+ bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
+ ArtMethod *m = GetMethod();
+ if (m == nullptr) {
+ // Attached native thread. Assume this is *not* boot class path.
+ caller = nullptr;
+ return false;
+ } else if (m->IsRuntimeMethod()) {
+ // Internal runtime method, continue walking the stack.
+ return true;
+ }
+
+ ObjPtr<mirror::Class> declaring_class = m->GetDeclaringClass();
+ if (declaring_class->IsBootStrapClassLoaded()) {
+ if (declaring_class->IsClassClass()) {
+ return true;
+ }
+ // Check classes in the java.lang.invoke package. At the time of writing, the
+ // classes of interest are MethodHandles and MethodHandles.Lookup, but this
+ // is subject to change so conservatively cover the entire package.
+ // NB Static initializers within java.lang.invoke are permitted and do not
+ // need further stack inspection.
+ ObjPtr<mirror::Class> lookup_class = GetClassRoot<mirror::MethodHandlesLookup>();
+ if ((declaring_class == lookup_class || declaring_class->IsInSamePackage(lookup_class))
+ && !m->IsClassInitializer()) {
+ return true;
+ }
+ // Check for classes in the java.lang.reflect package, except for java.lang.reflect.Proxy.
+ // java.lang.reflect.Proxy does its own hidden api checks (https://r.android.com/915496),
+ // and walking over this frame would cause a null pointer dereference
+ // (e.g. in 691-hiddenapi-proxy).
+ ObjPtr<mirror::Class> proxy_class = GetClassRoot<mirror::Proxy>();
+ CompatFramework& compat_framework = Runtime::Current()->GetCompatFramework();
+ if (declaring_class->IsInSamePackage(proxy_class) && declaring_class != proxy_class) {
+ if (compat_framework.IsChangeEnabled(kPreventMetaReflectionBlocklistAccess)) {
+ return true;
+ }
+ }
+ }
+
+ caller = m;
+ return false;
+ }
+
+ ArtMethod* caller;
+ };
+
+ FirstExternalCallerVisitor visitor(self);
+ visitor.WalkStack();
+
+ // Construct AccessContext from the calling class found on the stack.
+ // If the calling class cannot be determined, e.g. unattached threads,
+ // we conservatively assume the caller is trusted.
+ ObjPtr<mirror::Class> caller = (visitor.caller == nullptr)
+ ? nullptr : visitor.caller->GetDeclaringClass();
+ return caller.IsNull() ? AccessContext(/* is_trusted= */ true)
+ : AccessContext(caller);
+}
+
namespace detail {
// Do not change the values of items in this enum, as they are written to the
diff --git a/runtime/hidden_api.h b/runtime/hidden_api.h
index 11c058c..66e81c4 100644
--- a/runtime/hidden_api.h
+++ b/runtime/hidden_api.h
@@ -162,6 +162,10 @@
void InitializeCorePlatformApiPrivateFields() REQUIRES(!Locks::mutator_lock_);
+// Walks the stack, finds the caller of this reflective call and returns
+// a hiddenapi AccessContext formed from its declaring class.
+AccessContext GetReflectionCallerAccessContext(Thread* self) REQUIRES_SHARED(Locks::mutator_lock_);
+
// Implementation details. DO NOT ACCESS DIRECTLY.
namespace detail {
diff --git a/runtime/interpreter/unstarted_runtime.cc b/runtime/interpreter/unstarted_runtime.cc
index b8fb5b8..135b6b4 100644
--- a/runtime/interpreter/unstarted_runtime.cc
+++ b/runtime/interpreter/unstarted_runtime.cc
@@ -369,6 +369,19 @@
result->SetL(field);
}
+void UnstartedRuntime::UnstartedClassGetDeclaredFields(
+ Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
+ // Special managed code cut-out to allow field lookup in a un-started runtime that'd fail
+ // going the reflective Dex way.
+ ObjPtr<mirror::Class> klass = shadow_frame->GetVRegReference(arg_offset)->AsClass();
+ auto object_array = klass->GetDeclaredFields(self,
+ /*public_only=*/ false,
+ /*force_resolve=*/ true);
+ if (object_array != nullptr) {
+ result->SetL(object_array);
+ }
+}
+
// This is required for Enum(Set) code, as that uses reflection to inspect enum classes.
void UnstartedRuntime::UnstartedClassGetDeclaredMethod(
Thread* self, ShadowFrame* shadow_frame, JValue* result, size_t arg_offset) {
diff --git a/runtime/interpreter/unstarted_runtime_list.h b/runtime/interpreter/unstarted_runtime_list.h
index 498aeb6..16d29b8 100644
--- a/runtime/interpreter/unstarted_runtime_list.h
+++ b/runtime/interpreter/unstarted_runtime_list.h
@@ -27,6 +27,7 @@
V(ClassClassForName, "Ljava/lang/Class;", "classForName", "(Ljava/lang/String;ZLjava/lang/ClassLoader;)Ljava/lang/Class;") \
V(ClassNewInstance, "Ljava/lang/Class;", "newInstance", "()Ljava/lang/Object;") \
V(ClassGetDeclaredField, "Ljava/lang/Class;", "getDeclaredField", "(Ljava/lang/String;)Ljava/lang/reflect/Field;") \
+ V(ClassGetDeclaredFields, "Ljava/lang/Class;", "getDeclaredFields", "()[Ljava/lang/reflect/Field;") \
V(ClassGetDeclaredMethod, "Ljava/lang/Class;", "getDeclaredMethodInternal", "(Ljava/lang/String;[Ljava/lang/Class;)Ljava/lang/reflect/Method;") \
V(ClassGetDeclaredConstructor, "Ljava/lang/Class;", "getDeclaredConstructorInternal", "([Ljava/lang/Class;)Ljava/lang/reflect/Constructor;") \
V(ClassGetDeclaringClass, "Ljava/lang/Class;", "getDeclaringClass", "()Ljava/lang/Class;") \
diff --git a/runtime/mirror/class-inl.h b/runtime/mirror/class-inl.h
index b59dc18..84f117f 100644
--- a/runtime/mirror/class-inl.h
+++ b/runtime/mirror/class-inl.h
@@ -32,10 +32,10 @@
#include "dex/dex_file-inl.h"
#include "dex/invoke_type.h"
#include "dex_cache.h"
+#include "hidden_api.h"
#include "iftable-inl.h"
#include "imtable.h"
#include "object-inl.h"
-#include "object_array.h"
#include "read_barrier-inl.h"
#include "runtime.h"
#include "string.h"
@@ -412,6 +412,18 @@
return SetField32<false>(OFFSET_OF_OBJECT_MEMBER(Class, object_size_), new_object_size);
}
+template<typename T>
+inline bool Class::IsDiscoverable(bool public_only,
+ const hiddenapi::AccessContext& access_context,
+ T* member) {
+ if (public_only && ((member->GetAccessFlags() & kAccPublic) == 0)) {
+ return false;
+ }
+
+ return !hiddenapi::ShouldDenyAccessToMember(
+ member, access_context, hiddenapi::AccessMethod::kNone);
+}
+
// Determine whether "this" is assignable from "src", where both of these
// are array classes.
//
diff --git a/runtime/mirror/class.cc b/runtime/mirror/class.cc
index 4828ca2..40ff7c0 100644
--- a/runtime/mirror/class.cc
+++ b/runtime/mirror/class.cc
@@ -38,6 +38,7 @@
#include "dex/dex_file_annotations.h"
#include "dex/signature-inl.h"
#include "dex_cache-inl.h"
+#include "field.h"
#include "gc/accounting/card_table-inl.h"
#include "gc/heap-inl.h"
#include "handle_scope-inl.h"
@@ -47,6 +48,7 @@
#include "method.h"
#include "object-inl.h"
#include "object-refvisitor-inl.h"
+#include "object_array-alloc-inl.h"
#include "object_array-inl.h"
#include "object_lock.h"
#include "string-inl.h"
@@ -1165,6 +1167,75 @@
return nullptr;
}
+ObjPtr<mirror::ObjectArray<mirror::Field>> Class::GetDeclaredFields(
+ Thread* self,
+ bool public_only,
+ bool force_resolve) REQUIRES_SHARED(Locks::mutator_lock_) {
+ if (UNLIKELY(IsObsoleteObject())) {
+ ThrowRuntimeException("Obsolete Object!");
+ return nullptr;
+ }
+ StackHandleScope<1> hs(self);
+ IterationRange<StrideIterator<ArtField>> ifields = GetIFields();
+ IterationRange<StrideIterator<ArtField>> sfields = GetSFields();
+ size_t array_size = NumInstanceFields() + NumStaticFields();
+ auto hiddenapi_context = hiddenapi::GetReflectionCallerAccessContext(self);
+ // Lets go subtract all the non discoverable fields.
+ for (ArtField& field : ifields) {
+ if (!IsDiscoverable(public_only, hiddenapi_context, &field)) {
+ --array_size;
+ }
+ }
+ for (ArtField& field : sfields) {
+ if (!IsDiscoverable(public_only, hiddenapi_context, &field)) {
+ --array_size;
+ }
+ }
+ size_t array_idx = 0;
+ auto object_array = hs.NewHandle(mirror::ObjectArray<mirror::Field>::Alloc(
+ self, GetClassRoot<mirror::ObjectArray<mirror::Field>>(), array_size));
+ if (object_array == nullptr) {
+ return nullptr;
+ }
+ for (ArtField& field : ifields) {
+ if (IsDiscoverable(public_only, hiddenapi_context, &field)) {
+ ObjPtr<mirror::Field> reflect_field =
+ mirror::Field::CreateFromArtField(self, &field, force_resolve);
+ if (reflect_field == nullptr) {
+ if (kIsDebugBuild) {
+ self->AssertPendingException();
+ }
+ // Maybe null due to OOME or type resolving exception.
+ return nullptr;
+ }
+ // We're initializing a newly allocated object, so we do not need to record that under
+ // a transaction. If the transaction is aborted, the whole object shall be unreachable.
+ object_array->SetWithoutChecks</*kTransactionActive=*/ false,
+ /*kCheckTransaction=*/ false>(
+ array_idx++, reflect_field);
+ }
+ }
+ for (ArtField& field : sfields) {
+ if (IsDiscoverable(public_only, hiddenapi_context, &field)) {
+ ObjPtr<mirror::Field> reflect_field =
+ mirror::Field::CreateFromArtField(self, &field, force_resolve);
+ if (reflect_field == nullptr) {
+ if (kIsDebugBuild) {
+ self->AssertPendingException();
+ }
+ return nullptr;
+ }
+ // We're initializing a newly allocated object, so we do not need to record that under
+ // a transaction. If the transaction is aborted, the whole object shall be unreachable.
+ object_array->SetWithoutChecks</*kTransactionActive=*/ false,
+ /*kCheckTransaction=*/ false>(
+ array_idx++, reflect_field);
+ }
+ }
+ DCHECK_EQ(array_idx, array_size);
+ return object_array.Get();
+}
+
ArtField* Class::FindStaticField(std::string_view name, std::string_view type) {
ScopedAssertNoThreadSuspension ants(__FUNCTION__);
// Is the field in this class (or its interfaces), or any of its
diff --git a/runtime/mirror/class.h b/runtime/mirror/class.h
index 9a97fcf..6c839ca 100644
--- a/runtime/mirror/class.h
+++ b/runtime/mirror/class.h
@@ -71,6 +71,7 @@
class ClassLoader;
class Constructor;
class DexCache;
+class Field;
class IfTable;
class Method;
template <typename T> struct PACKED(8) DexCachePair;
@@ -589,6 +590,16 @@
static bool IsInSamePackage(std::string_view descriptor1, std::string_view descriptor2);
+ // Returns true if a class member should be discoverable with reflection given
+ // the criteria. Some reflection calls only return public members
+ // (public_only == true), some members should be hidden from non-boot class path
+ // callers (hiddenapi_context).
+ template<typename T>
+ ALWAYS_INLINE static bool IsDiscoverable(bool public_only,
+ const hiddenapi::AccessContext& access_context,
+ T* member)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
// Returns true if this class can access that class.
bool CanAccess(ObjPtr<Class> that) REQUIRES_SHARED(Locks::mutator_lock_);
@@ -1109,6 +1120,12 @@
ArtField* FindDeclaredStaticField(ObjPtr<DexCache> dex_cache, uint32_t dex_field_idx)
REQUIRES_SHARED(Locks::mutator_lock_);
+ ObjPtr<mirror::ObjectArray<mirror::Field>> GetDeclaredFields(Thread* self,
+ bool public_only,
+ bool force_resolve)
+ REQUIRES_SHARED(Locks::mutator_lock_);
+
+
pid_t GetClinitThreadId() REQUIRES_SHARED(Locks::mutator_lock_) {
DCHECK(IsIdxLoaded() || IsErroneous()) << PrettyClass();
return GetField32(OFFSET_OF_OBJECT_MEMBER(Class, clinit_thread_id_));
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index 776b14f..da42e61 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -57,83 +57,10 @@
namespace art {
-// Should be the same as dalvik.system.VMRuntime.PREVENT_META_REFLECTION_BLOCKLIST_ACCESS.
-// Corresponds to a bug id.
-static constexpr uint64_t kPreventMetaReflectionBlocklistAccess = 142365358;
-
-// Walks the stack, finds the caller of this reflective call and returns
-// a hiddenapi AccessContext formed from its declaring class.
-static hiddenapi::AccessContext GetReflectionCaller(Thread* self)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- // Walk the stack and find the first frame not from java.lang.Class,
- // java.lang.invoke or java.lang.reflect. This is very expensive.
- // Save this till the last.
- struct FirstExternalCallerVisitor : public StackVisitor {
- explicit FirstExternalCallerVisitor(Thread* thread)
- : StackVisitor(thread, nullptr, StackVisitor::StackWalkKind::kIncludeInlinedFrames),
- caller(nullptr) {
- }
-
- bool VisitFrame() override REQUIRES_SHARED(Locks::mutator_lock_) {
- ArtMethod *m = GetMethod();
- if (m == nullptr) {
- // Attached native thread. Assume this is *not* boot class path.
- caller = nullptr;
- return false;
- } else if (m->IsRuntimeMethod()) {
- // Internal runtime method, continue walking the stack.
- return true;
- }
-
- ObjPtr<mirror::Class> declaring_class = m->GetDeclaringClass();
- if (declaring_class->IsBootStrapClassLoaded()) {
- if (declaring_class->IsClassClass()) {
- return true;
- }
- // Check classes in the java.lang.invoke package. At the time of writing, the
- // classes of interest are MethodHandles and MethodHandles.Lookup, but this
- // is subject to change so conservatively cover the entire package.
- // NB Static initializers within java.lang.invoke are permitted and do not
- // need further stack inspection.
- ObjPtr<mirror::Class> lookup_class = GetClassRoot<mirror::MethodHandlesLookup>();
- if ((declaring_class == lookup_class || declaring_class->IsInSamePackage(lookup_class))
- && !m->IsClassInitializer()) {
- return true;
- }
- // Check for classes in the java.lang.reflect package, except for java.lang.reflect.Proxy.
- // java.lang.reflect.Proxy does its own hidden api checks (https://r.android.com/915496),
- // and walking over this frame would cause a null pointer dereference
- // (e.g. in 691-hiddenapi-proxy).
- ObjPtr<mirror::Class> proxy_class = GetClassRoot<mirror::Proxy>();
- CompatFramework& compat_framework = Runtime::Current()->GetCompatFramework();
- if (declaring_class->IsInSamePackage(proxy_class) && declaring_class != proxy_class) {
- if (compat_framework.IsChangeEnabled(kPreventMetaReflectionBlocklistAccess)) {
- return true;
- }
- }
- }
-
- caller = m;
- return false;
- }
-
- ArtMethod* caller;
- };
-
- FirstExternalCallerVisitor visitor(self);
- visitor.WalkStack();
-
- // Construct AccessContext from the calling class found on the stack.
- // If the calling class cannot be determined, e.g. unattached threads,
- // we conservatively assume the caller is trusted.
- ObjPtr<mirror::Class> caller = (visitor.caller == nullptr)
- ? nullptr : visitor.caller->GetDeclaringClass();
- return caller.IsNull() ? hiddenapi::AccessContext(/* is_trusted= */ true)
- : hiddenapi::AccessContext(caller);
-}
-
static std::function<hiddenapi::AccessContext()> GetHiddenapiAccessContextFunction(Thread* self) {
- return [=]() REQUIRES_SHARED(Locks::mutator_lock_) { return GetReflectionCaller(self); };
+ return [=]() REQUIRES_SHARED(Locks::mutator_lock_) {
+ return hiddenapi::GetReflectionCallerAccessContext(self);
+ };
}
// Returns true if the first non-ClassClass caller up the stack should not be
@@ -146,23 +73,6 @@
hiddenapi::AccessMethod::kReflection);
}
-// Returns true if a class member should be discoverable with reflection given
-// the criteria. Some reflection calls only return public members
-// (public_only == true), some members should be hidden from non-boot class path
-// callers (hiddenapi_context).
-template<typename T>
-ALWAYS_INLINE static bool IsDiscoverable(bool public_only,
- const hiddenapi::AccessContext& access_context,
- T* member)
- REQUIRES_SHARED(Locks::mutator_lock_) {
- if (public_only && ((member->GetAccessFlags() & kAccPublic) == 0)) {
- return false;
- }
-
- return !hiddenapi::ShouldDenyAccessToMember(
- member, access_context, hiddenapi::AccessMethod::kNone);
-}
-
ALWAYS_INLINE static inline ObjPtr<mirror::Class> DecodeClass(
const ScopedFastNativeObjectAccess& soa, jobject java_class)
REQUIRES_SHARED(Locks::mutator_lock_) {
@@ -280,85 +190,32 @@
return soa.AddLocalReference<jobjectArray>(ifaces);
}
-static ObjPtr<mirror::ObjectArray<mirror::Field>> GetDeclaredFields(
- Thread* self,
- ObjPtr<mirror::Class> klass,
- bool public_only,
- bool force_resolve) REQUIRES_SHARED(Locks::mutator_lock_) {
- if (UNLIKELY(klass->IsObsoleteObject())) {
- ThrowRuntimeException("Obsolete Object!");
- return nullptr;
- }
- StackHandleScope<1> hs(self);
- IterationRange<StrideIterator<ArtField>> ifields = klass->GetIFields();
- IterationRange<StrideIterator<ArtField>> sfields = klass->GetSFields();
- size_t array_size = klass->NumInstanceFields() + klass->NumStaticFields();
- hiddenapi::AccessContext hiddenapi_context = GetReflectionCaller(self);
- // Lets go subtract all the non discoverable fields.
- for (ArtField& field : ifields) {
- if (!IsDiscoverable(public_only, hiddenapi_context, &field)) {
- --array_size;
- }
- }
- for (ArtField& field : sfields) {
- if (!IsDiscoverable(public_only, hiddenapi_context, &field)) {
- --array_size;
- }
- }
- size_t array_idx = 0;
- auto object_array = hs.NewHandle(mirror::ObjectArray<mirror::Field>::Alloc(
- self, GetClassRoot<mirror::ObjectArray<mirror::Field>>(), array_size));
- if (object_array == nullptr) {
- return nullptr;
- }
- for (ArtField& field : ifields) {
- if (IsDiscoverable(public_only, hiddenapi_context, &field)) {
- ObjPtr<mirror::Field> reflect_field =
- mirror::Field::CreateFromArtField(self, &field, force_resolve);
- if (reflect_field == nullptr) {
- if (kIsDebugBuild) {
- self->AssertPendingException();
- }
- // Maybe null due to OOME or type resolving exception.
- return nullptr;
- }
- object_array->SetWithoutChecks<false>(array_idx++, reflect_field);
- }
- }
- for (ArtField& field : sfields) {
- if (IsDiscoverable(public_only, hiddenapi_context, &field)) {
- ObjPtr<mirror::Field> reflect_field =
- mirror::Field::CreateFromArtField(self, &field, force_resolve);
- if (reflect_field == nullptr) {
- if (kIsDebugBuild) {
- self->AssertPendingException();
- }
- return nullptr;
- }
- object_array->SetWithoutChecks<false>(array_idx++, reflect_field);
- }
- }
- DCHECK_EQ(array_idx, array_size);
- return object_array.Get();
-}
-
static jobjectArray Class_getDeclaredFieldsUnchecked(JNIEnv* env, jobject javaThis,
jboolean publicOnly) {
ScopedFastNativeObjectAccess soa(env);
+ ObjPtr<mirror::Class> klass = DecodeClass(soa, javaThis);
return soa.AddLocalReference<jobjectArray>(
- GetDeclaredFields(soa.Self(), DecodeClass(soa, javaThis), publicOnly != JNI_FALSE, false));
+ klass->GetDeclaredFields(soa.Self(),
+ publicOnly != JNI_FALSE,
+ /*force_resolve=*/ false));
}
static jobjectArray Class_getDeclaredFields(JNIEnv* env, jobject javaThis) {
ScopedFastNativeObjectAccess soa(env);
+ ObjPtr<mirror::Class> klass = DecodeClass(soa, javaThis);
return soa.AddLocalReference<jobjectArray>(
- GetDeclaredFields(soa.Self(), DecodeClass(soa, javaThis), false, true));
+ klass->GetDeclaredFields(soa.Self(),
+ /*public_only=*/ false,
+ /*force_resolve=*/ true));
}
static jobjectArray Class_getPublicDeclaredFields(JNIEnv* env, jobject javaThis) {
ScopedFastNativeObjectAccess soa(env);
+ ObjPtr<mirror::Class> klass = DecodeClass(soa, javaThis);
return soa.AddLocalReference<jobjectArray>(
- GetDeclaredFields(soa.Self(), DecodeClass(soa, javaThis), true, true));
+ klass->GetDeclaredFields(soa.Self(),
+ /*public_only=*/ true,
+ /*force_resolve=*/ true));
}
// Performs a binary search through an array of fields, TODO: Is this fast enough if we don't use
@@ -559,7 +416,7 @@
DCHECK(m != nullptr);
return m->IsConstructor() &&
!m->IsStatic() &&
- IsDiscoverable(public_only, hiddenapi_context, m);
+ mirror::Class::IsDiscoverable(public_only, hiddenapi_context, m);
}
static jobjectArray Class_getDeclaredConstructorsInternal(
@@ -567,7 +424,7 @@
ScopedFastNativeObjectAccess soa(env);
StackHandleScope<2> hs(soa.Self());
bool public_only = (publicOnly != JNI_FALSE);
- hiddenapi::AccessContext hiddenapi_context = GetReflectionCaller(soa.Self());
+ auto hiddenapi_context = hiddenapi::GetReflectionCallerAccessContext(soa.Self());
Handle<mirror::Class> h_klass = hs.NewHandle(DecodeClass(soa, javaThis));
if (UNLIKELY(h_klass->IsObsoleteObject())) {
ThrowRuntimeException("Obsolete Object!");
@@ -630,7 +487,7 @@
ScopedFastNativeObjectAccess soa(env);
StackHandleScope<2> hs(soa.Self());
- hiddenapi::AccessContext hiddenapi_context = GetReflectionCaller(soa.Self());
+ auto hiddenapi_context = hiddenapi::GetReflectionCallerAccessContext(soa.Self());
bool public_only = (publicOnly != JNI_FALSE);
Handle<mirror::Class> klass = hs.NewHandle(DecodeClass(soa, javaThis));
@@ -643,7 +500,7 @@
uint32_t modifiers = m.GetAccessFlags();
// Add non-constructor declared methods.
if ((modifiers & kAccConstructor) == 0 &&
- IsDiscoverable(public_only, hiddenapi_context, &m)) {
+ mirror::Class::IsDiscoverable(public_only, hiddenapi_context, &m)) {
++num_methods;
}
}
@@ -657,7 +514,7 @@
for (ArtMethod& m : klass->GetDeclaredMethods(kRuntimePointerSize)) {
uint32_t modifiers = m.GetAccessFlags();
if ((modifiers & kAccConstructor) == 0 &&
- IsDiscoverable(public_only, hiddenapi_context, &m)) {
+ mirror::Class::IsDiscoverable(public_only, hiddenapi_context, &m)) {
DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
DCHECK(!Runtime::Current()->IsActiveTransaction());
ObjPtr<mirror::Method> method =