Revert "hidden_api: Call back into libcore on hidden api detection"
This reverts commit 757a9d0a2e97d43bafeb8a95cc3c51102be99586.
Reason for revert: Test failures with "art/test.py --host -t test-art-host-run-test-debug-prebuild-interpreter-no-relocate-ntrace-gcstress-checkjni-picimage-pictest-ndebuggable-no-jvmti-cdex-fast-674-hiddenapi64"
Bug: 73896556
Test: art/test.py --host -t test-art-host-run-test-debug-prebuild-interpreter-no-relocate-ntrace-gcstress-checkjni-picimage-pictest-ndebuggable-no-jvmti-cdex-fast-674-hiddenapi64
(cherry picked from commit 9e68ade384abdb15714054feaed06cb38eb5432f)
Merged-In: Ib2ad89c16ad797c37f6212bc7e5c0b6b92ce56b5
Change-Id: I11fa9b76da07162fde8773eb05cfc6a6514e0ca1
diff --git a/runtime/hidden_api.cc b/runtime/hidden_api.cc
index aad3917..f0b36a0 100644
--- a/runtime/hidden_api.cc
+++ b/runtime/hidden_api.cc
@@ -16,11 +16,7 @@
#include "hidden_api.h"
-#include <nativehelper/scoped_local_ref.h>
-
#include "base/dumpable.h"
-#include "thread-current-inl.h"
-#include "well_known_classes.h"
namespace art {
namespace hiddenapi {
@@ -140,35 +136,6 @@
member_signature.WarnAboutAccess(access_method,
HiddenApiAccessFlags::DecodeFromRuntime(member->GetAccessFlags()));
- // We're now not in the boot classpath and have decided to warn, show
- // a toast or deny access. Let strict mode know if a callback is set.
- //
- // For consistency of reasoning, we assume that a callback is never set
- // when running unstarted with dex2oat.
- if (access_method == kReflection && !runtime->IsAotCompiler()) {
- ScopedObjectAccessUnchecked soa(Thread::Current());
-
- ScopedLocalRef<jobject> consumer_object(soa.Env(),
- soa.Env()->GetStaticObjectField(
- WellKnownClasses::dalvik_system_VMRuntime,
- WellKnownClasses::dalvik_system_VMRuntime_nonSdkApiUsageConsumer));
- // If the consumer is non-null, we call back to it to let it know that we
- // have encountered an API that's in one of our lists.
- if (consumer_object != nullptr) {
- std::ostringstream member_signature_str;
- member_signature.Dump(member_signature_str);
-
- ScopedLocalRef<jobject> signature_str(
- soa.Env(),
- soa.Env()->NewStringUTF(member_signature_str.str().c_str()));
-
- // Call through to Consumer.accept(String memberSignature);
- soa.Env()->CallVoidMethod(consumer_object.get(),
- WellKnownClasses::java_util_function_Consumer_accept,
- signature_str.get());
- }
- }
-
if (action == kDeny) {
// Block access
return true;
diff --git a/runtime/native/java_lang_Class.cc b/runtime/native/java_lang_Class.cc
index 1c17806..ad05856 100644
--- a/runtime/native/java_lang_Class.cc
+++ b/runtime/native/java_lang_Class.cc
@@ -535,19 +535,18 @@
static jobject Class_getDeclaredMethodInternal(JNIEnv* env, jobject javaThis,
jstring name, jobjectArray args) {
ScopedFastNativeObjectAccess soa(env);
- StackHandleScope<1> hs(soa.Self());
DCHECK_EQ(Runtime::Current()->GetClassLinker()->GetImagePointerSize(), kRuntimePointerSize);
DCHECK(!Runtime::Current()->IsActiveTransaction());
- Handle<mirror::Method> result = hs.NewHandle(
+ ObjPtr<mirror::Method> result =
mirror::Class::GetDeclaredMethodInternal<kRuntimePointerSize, false>(
soa.Self(),
DecodeClass(soa, javaThis),
soa.Decode<mirror::String>(name),
- soa.Decode<mirror::ObjectArray<mirror::Class>>(args)));
+ soa.Decode<mirror::ObjectArray<mirror::Class>>(args));
if (result == nullptr || ShouldBlockAccessToMember(result->GetArtMethod(), soa.Self())) {
return nullptr;
}
- return soa.AddLocalReference<jobject>(result.Get());
+ return soa.AddLocalReference<jobject>(result);
}
static jobjectArray Class_getDeclaredMethodsUnchecked(JNIEnv* env, jobject javaThis,
diff --git a/runtime/well_known_classes.cc b/runtime/well_known_classes.cc
index 742e713..bf36ccf 100644
--- a/runtime/well_known_classes.cc
+++ b/runtime/well_known_classes.cc
@@ -77,7 +77,6 @@
jclass WellKnownClasses::java_nio_DirectByteBuffer;
jclass WellKnownClasses::java_util_ArrayList;
jclass WellKnownClasses::java_util_Collections;
-jclass WellKnownClasses::java_util_function_Consumer;
jclass WellKnownClasses::libcore_reflect_AnnotationFactory;
jclass WellKnownClasses::libcore_reflect_AnnotationMember;
jclass WellKnownClasses::libcore_util_EmptyArray;
@@ -116,7 +115,6 @@
jmethodID WellKnownClasses::java_lang_ThreadGroup_add;
jmethodID WellKnownClasses::java_lang_ThreadGroup_removeThread;
jmethodID WellKnownClasses::java_nio_DirectByteBuffer_init;
-jmethodID WellKnownClasses::java_util_function_Consumer_accept;
jmethodID WellKnownClasses::libcore_reflect_AnnotationFactory_createAnnotation;
jmethodID WellKnownClasses::libcore_reflect_AnnotationMember_init;
jmethodID WellKnownClasses::org_apache_harmony_dalvik_ddmc_DdmServer_broadcast;
@@ -127,7 +125,6 @@
jfieldID WellKnownClasses::dalvik_system_BaseDexClassLoader_pathList;
jfieldID WellKnownClasses::dalvik_system_DexPathList_dexElements;
jfieldID WellKnownClasses::dalvik_system_DexPathList__Element_dexFile;
-jfieldID WellKnownClasses::dalvik_system_VMRuntime_nonSdkApiUsageConsumer;
jfieldID WellKnownClasses::java_lang_Thread_daemon;
jfieldID WellKnownClasses::java_lang_Thread_group;
jfieldID WellKnownClasses::java_lang_Thread_lock;
@@ -352,7 +349,6 @@
java_nio_DirectByteBuffer = CacheClass(env, "java/nio/DirectByteBuffer");
java_util_ArrayList = CacheClass(env, "java/util/ArrayList");
java_util_Collections = CacheClass(env, "java/util/Collections");
- java_util_function_Consumer = CacheClass(env, "java/util/function/Consumer");
libcore_reflect_AnnotationFactory = CacheClass(env, "libcore/reflect/AnnotationFactory");
libcore_reflect_AnnotationMember = CacheClass(env, "libcore/reflect/AnnotationMember");
libcore_util_EmptyArray = CacheClass(env, "libcore/util/EmptyArray");
@@ -383,7 +379,6 @@
java_lang_ThreadGroup_add = CacheMethod(env, java_lang_ThreadGroup, false, "add", "(Ljava/lang/Thread;)V");
java_lang_ThreadGroup_removeThread = CacheMethod(env, java_lang_ThreadGroup, false, "threadTerminated", "(Ljava/lang/Thread;)V");
java_nio_DirectByteBuffer_init = CacheMethod(env, java_nio_DirectByteBuffer, false, "<init>", "(JI)V");
- java_util_function_Consumer_accept = CacheMethod(env, java_util_function_Consumer, false, "accept", "(Ljava/lang/Object;)V");
libcore_reflect_AnnotationFactory_createAnnotation = CacheMethod(env, libcore_reflect_AnnotationFactory, true, "createAnnotation", "(Ljava/lang/Class;[Llibcore/reflect/AnnotationMember;)Ljava/lang/annotation/Annotation;");
libcore_reflect_AnnotationMember_init = CacheMethod(env, libcore_reflect_AnnotationMember, false, "<init>", "(Ljava/lang/String;Ljava/lang/Object;Ljava/lang/Class;Ljava/lang/reflect/Method;)V");
org_apache_harmony_dalvik_ddmc_DdmServer_broadcast = CacheMethod(env, org_apache_harmony_dalvik_ddmc_DdmServer, true, "broadcast", "(I)V");
@@ -394,7 +389,6 @@
dalvik_system_DexFile_fileName = CacheField(env, dalvik_system_DexFile, false, "mFileName", "Ljava/lang/String;");
dalvik_system_DexPathList_dexElements = CacheField(env, dalvik_system_DexPathList, false, "dexElements", "[Ldalvik/system/DexPathList$Element;");
dalvik_system_DexPathList__Element_dexFile = CacheField(env, dalvik_system_DexPathList__Element, false, "dexFile", "Ldalvik/system/DexFile;");
- dalvik_system_VMRuntime_nonSdkApiUsageConsumer = CacheField(env, dalvik_system_VMRuntime, true, "nonSdkApiUsageConsumer", "Ljava/util/function/Consumer;");
java_lang_Thread_daemon = CacheField(env, java_lang_Thread, false, "daemon", "Z");
java_lang_Thread_group = CacheField(env, java_lang_Thread, false, "group", "Ljava/lang/ThreadGroup;");
java_lang_Thread_lock = CacheField(env, java_lang_Thread, false, "lock", "Ljava/lang/Object;");
diff --git a/runtime/well_known_classes.h b/runtime/well_known_classes.h
index 7b1a294..d5d7033 100644
--- a/runtime/well_known_classes.h
+++ b/runtime/well_known_classes.h
@@ -85,7 +85,6 @@
static jclass java_lang_Throwable;
static jclass java_util_ArrayList;
static jclass java_util_Collections;
- static jclass java_util_function_Consumer;
static jclass java_nio_ByteBuffer;
static jclass java_nio_DirectByteBuffer;
static jclass libcore_reflect_AnnotationFactory;
@@ -126,7 +125,6 @@
static jmethodID java_lang_ThreadGroup_add;
static jmethodID java_lang_ThreadGroup_removeThread;
static jmethodID java_nio_DirectByteBuffer_init;
- static jmethodID java_util_function_Consumer_accept;
static jmethodID libcore_reflect_AnnotationFactory_createAnnotation;
static jmethodID libcore_reflect_AnnotationMember_init;
static jmethodID org_apache_harmony_dalvik_ddmc_DdmServer_broadcast;
@@ -137,7 +135,6 @@
static jfieldID dalvik_system_DexFile_fileName;
static jfieldID dalvik_system_DexPathList_dexElements;
static jfieldID dalvik_system_DexPathList__Element_dexFile;
- static jfieldID dalvik_system_VMRuntime_nonSdkApiUsageConsumer;
static jfieldID java_lang_reflect_Executable_artMethod;
static jfieldID java_lang_reflect_Proxy_h;
static jfieldID java_lang_Thread_daemon;
diff --git a/test/674-hiddenapi/build b/test/674-hiddenapi/build
index 330a6de..9012e8f 100644
--- a/test/674-hiddenapi/build
+++ b/test/674-hiddenapi/build
@@ -16,6 +16,15 @@
set -e
+# Special build logic to handle src-ex .java files which have code that only builds on RI.
+custom_build_logic() {
+ [[ -d ignore.src-ex ]] && mv ignore.src-ex src-ex
+ # src-ex uses code that can only build on RI.
+ ${JAVAC} -source 1.8 -target 1.8 -sourcepath src-ex -sourcepath src -d classes-ex $(find src-ex -name '*.java')
+ # remove src-ex so that default-build doesn't try to build it.
+ [[ -d src-ex ]] && mv src-ex ignore.src-ex
+}
+
# Build the jars twice. First with applying hiddenapi, creating a boot jar, then
# a second time without to create a normal jar. We need to do this because we
# want to load the jar once as an app module and once as a member of the boot
@@ -24,6 +33,7 @@
# class path dex files, so the boot jar loads fine in the latter case.
export USE_HIDDENAPI=true
+custom_build_logic
./default-build "$@"
# Move the jar file into the resource folder to be bundled with the test.
@@ -35,4 +45,5 @@
rm -rf classes*
export USE_HIDDENAPI=false
+custom_build_logic
./default-build "$@"
diff --git a/test/674-hiddenapi/src-ex/ChildClass.java b/test/674-hiddenapi/src-ex/ChildClass.java
index 822224c..582e907 100644
--- a/test/674-hiddenapi/src-ex/ChildClass.java
+++ b/test/674-hiddenapi/src-ex/ChildClass.java
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-import dalvik.system.VMRuntime;
import java.lang.annotation.Annotation;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
@@ -22,7 +21,11 @@
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.List;
-import java.util.function.Consumer;
+
+import javax.lang.model.element.AnnotationMirror;
+import javax.lang.model.type.PrimitiveType;
+import javax.lang.model.type.TypeKind;
+import javax.lang.model.type.TypeVisitor;
public class ChildClass {
enum PrimitiveType {
@@ -133,47 +136,6 @@
}
}
- static final class RecordingConsumer implements Consumer<String> {
- public String recordedValue = null;
-
- @Override
- public void accept(String value) {
- recordedValue = value;
- }
- }
-
- private static void checkMemberCallback(Class<?> klass, String name,
- boolean isPublic, boolean isField) {
- try {
- RecordingConsumer consumer = new RecordingConsumer();
- VMRuntime.setNonSdkApiUsageConsumer(consumer);
- try {
- if (isPublic) {
- if (isField) {
- klass.getField(name);
- } else {
- klass.getMethod(name);
- }
- } else {
- if (isField) {
- klass.getDeclaredField(name);
- } else {
- klass.getDeclaredMethod(name);
- }
- }
- } catch (NoSuchFieldException|NoSuchMethodException ignored) {
- // We're not concerned whether an exception is thrown or not - we're
- // only interested in whether the callback is invoked.
- }
-
- if (consumer.recordedValue == null || !consumer.recordedValue.contains(name)) {
- throw new RuntimeException("No callback for member: " + name);
- }
- } finally {
- VMRuntime.setNonSdkApiUsageConsumer(null);
- }
- }
-
private static void checkField(Class<?> klass, String name, boolean isStatic,
Visibility visibility, Behaviour behaviour) throws Exception {
@@ -212,52 +174,48 @@
// Finish here if we could not discover the field.
- if (canDiscover) {
- // Test that modifiers are unaffected.
-
- if (Reflection.canObserveFieldHiddenAccessFlags(klass, name)) {
- throwModifiersException(klass, name, true);
- }
-
- // Test getters and setters when meaningful.
-
- clearWarning();
- if (!Reflection.canGetField(klass, name)) {
- throwAccessException(klass, name, true, "Field.getInt()");
- }
- if (hasPendingWarning() != setsWarning) {
- throwWarningException(klass, name, true, "Field.getInt()", setsWarning);
- }
-
- clearWarning();
- if (!Reflection.canSetField(klass, name)) {
- throwAccessException(klass, name, true, "Field.setInt()");
- }
- if (hasPendingWarning() != setsWarning) {
- throwWarningException(klass, name, true, "Field.setInt()", setsWarning);
- }
-
- clearWarning();
- if (!JNI.canGetField(klass, name, isStatic)) {
- throwAccessException(klass, name, true, "getIntField");
- }
- if (hasPendingWarning() != setsWarning) {
- throwWarningException(klass, name, true, "getIntField", setsWarning);
- }
-
- clearWarning();
- if (!JNI.canSetField(klass, name, isStatic)) {
- throwAccessException(klass, name, true, "setIntField");
- }
- if (hasPendingWarning() != setsWarning) {
- throwWarningException(klass, name, true, "setIntField", setsWarning);
- }
+ if (!canDiscover) {
+ return;
}
- // Test that callbacks are invoked correctly.
+ // Test that modifiers are unaffected.
+
+ if (Reflection.canObserveFieldHiddenAccessFlags(klass, name)) {
+ throwModifiersException(klass, name, true);
+ }
+
+ // Test getters and setters when meaningful.
+
clearWarning();
- if (setsWarning || !canDiscover) {
- checkMemberCallback(klass, name, isPublic, true /* isField */);
+ if (!Reflection.canGetField(klass, name)) {
+ throwAccessException(klass, name, true, "Field.getInt()");
+ }
+ if (hasPendingWarning() != setsWarning) {
+ throwWarningException(klass, name, true, "Field.getInt()", setsWarning);
+ }
+
+ clearWarning();
+ if (!Reflection.canSetField(klass, name)) {
+ throwAccessException(klass, name, true, "Field.setInt()");
+ }
+ if (hasPendingWarning() != setsWarning) {
+ throwWarningException(klass, name, true, "Field.setInt()", setsWarning);
+ }
+
+ clearWarning();
+ if (!JNI.canGetField(klass, name, isStatic)) {
+ throwAccessException(klass, name, true, "getIntField");
+ }
+ if (hasPendingWarning() != setsWarning) {
+ throwWarningException(klass, name, true, "getIntField", setsWarning);
+ }
+
+ clearWarning();
+ if (!JNI.canSetField(klass, name, isStatic)) {
+ throwAccessException(klass, name, true, "setIntField");
+ }
+ if (hasPendingWarning() != setsWarning) {
+ throwWarningException(klass, name, true, "setIntField", setsWarning);
}
}
@@ -299,46 +257,42 @@
// Finish here if we could not discover the field.
- if (canDiscover) {
- // Test that modifiers are unaffected.
-
- if (Reflection.canObserveMethodHiddenAccessFlags(klass, name)) {
- throwModifiersException(klass, name, false);
- }
-
- // Test whether we can invoke the method. This skips non-static interface methods.
-
- if (!klass.isInterface() || isStatic) {
- clearWarning();
- if (!Reflection.canInvokeMethod(klass, name)) {
- throwAccessException(klass, name, false, "invoke()");
- }
- if (hasPendingWarning() != setsWarning) {
- throwWarningException(klass, name, false, "invoke()", setsWarning);
- }
-
- clearWarning();
- if (!JNI.canInvokeMethodA(klass, name, isStatic)) {
- throwAccessException(klass, name, false, "CallMethodA");
- }
- if (hasPendingWarning() != setsWarning) {
- throwWarningException(klass, name, false, "CallMethodA()", setsWarning);
- }
-
- clearWarning();
- if (!JNI.canInvokeMethodV(klass, name, isStatic)) {
- throwAccessException(klass, name, false, "CallMethodV");
- }
- if (hasPendingWarning() != setsWarning) {
- throwWarningException(klass, name, false, "CallMethodV()", setsWarning);
- }
- }
+ if (!canDiscover) {
+ return;
}
- // Test that callbacks are invoked correctly.
- clearWarning();
- if (setsWarning || !canDiscover) {
- checkMemberCallback(klass, name, isPublic, false /* isField */);
+ // Test that modifiers are unaffected.
+
+ if (Reflection.canObserveMethodHiddenAccessFlags(klass, name)) {
+ throwModifiersException(klass, name, false);
+ }
+
+ // Test whether we can invoke the method. This skips non-static interface methods.
+
+ if (!klass.isInterface() || isStatic) {
+ clearWarning();
+ if (!Reflection.canInvokeMethod(klass, name)) {
+ throwAccessException(klass, name, false, "invoke()");
+ }
+ if (hasPendingWarning() != setsWarning) {
+ throwWarningException(klass, name, false, "invoke()", setsWarning);
+ }
+
+ clearWarning();
+ if (!JNI.canInvokeMethodA(klass, name, isStatic)) {
+ throwAccessException(klass, name, false, "CallMethodA");
+ }
+ if (hasPendingWarning() != setsWarning) {
+ throwWarningException(klass, name, false, "CallMethodA()", setsWarning);
+ }
+
+ clearWarning();
+ if (!JNI.canInvokeMethodV(klass, name, isStatic)) {
+ throwAccessException(klass, name, false, "CallMethodV");
+ }
+ if (hasPendingWarning() != setsWarning) {
+ throwWarningException(klass, name, false, "CallMethodV()", setsWarning);
+ }
}
}