summaryrefslogtreecommitdiff
path: root/test/690-hiddenapi-same-name-methods/src/Main.java
diff options
context:
space:
mode:
Diffstat (limited to 'test/690-hiddenapi-same-name-methods/src/Main.java')
-rw-r--r--test/690-hiddenapi-same-name-methods/src/Main.java106
1 files changed, 106 insertions, 0 deletions
diff --git a/test/690-hiddenapi-same-name-methods/src/Main.java b/test/690-hiddenapi-same-name-methods/src/Main.java
new file mode 100644
index 0000000000..12cfdd702b
--- /dev/null
+++ b/test/690-hiddenapi-same-name-methods/src/Main.java
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) 2019 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import java.io.File;
+import java.lang.reflect.Method;
+import java.util.Base64;
+
+public class Main {
+ public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException {
+ System.loadLibrary(args[0]);
+
+ // Run the initialization routine. This will enable hidden API checks in
+ // the runtime, in case they are not enabled by default.
+ init();
+
+ // Load the '-ex' APK and attach it to the boot class path.
+ appendToBootClassLoader(DEX_EXTRA, /* isCorePlatform */ false);
+
+ // All test classes contain just methods named "foo" with different return types
+ // and access flags. Check that:
+ // (a) only the non-hidden ones are returned from getDeclaredMethods
+ // (they have return types Number and Double), and
+ // (b) getDeclaredMethod picks virtual/non-synthetic methods over direct/synthetic
+ // (the right one always has return type Number).
+ Class<?> covariantClass = Class.forName(JAVA_CLASS_NAME, true, BOOT_CLASS_LOADER);
+ checkMethodList(covariantClass, /* expectedLength= */ 1);
+ checkMethod(covariantClass);
+
+ String[] classes = new String[] {
+ "VirtualMethods",
+ "DirectMethods",
+ "SyntheticMethods",
+ "NonSyntheticMethods"
+ };
+ for (String className : classes) {
+ Class<?> klass = Class.forName(className, true, BOOT_CLASS_LOADER);
+ checkMethodList(klass, /* expectedLength= */ 2);
+ checkMethod(klass);
+ }
+ }
+
+ private static void checkMethodList(Class<?> klass, int expectedLength) {
+ String className = klass.getName();
+ Method[] methods = klass.getDeclaredMethods();
+ if (methods.length != expectedLength) {
+ throw new RuntimeException(className + ": expected " + expectedLength +
+ " declared method(s), got " + methods.length);
+ }
+ boolean hasNumberReturnType = false;
+ boolean hasDoubleReturnType = false;
+ for (Method method : methods) {
+ if (!METHOD_NAME.equals(method.getName())) {
+ throw new RuntimeException(className + ": expected declared method name: \"" + METHOD_NAME +
+ "\", got: \"" + method.getName() + "\"");
+ }
+ if (Number.class == method.getReturnType()) {
+ hasNumberReturnType = true;
+ } else if (Double.class == method.getReturnType()) {
+ hasDoubleReturnType = true;
+ }
+ }
+ if (methods.length >= 1 && !hasNumberReturnType) {
+ throw new RuntimeException(className + ": expected a method with return type \"Number\"");
+ }
+ if (methods.length >= 2 && !hasDoubleReturnType) {
+ throw new RuntimeException(className + ": expected a method with return type \"Double\"");
+ }
+ }
+
+ private static void checkMethod(Class<?> klass) throws NoSuchMethodException {
+ String className = klass.getName();
+ Method method = klass.getDeclaredMethod(METHOD_NAME);
+ if (!METHOD_NAME.equals(method.getName())) {
+ throw new RuntimeException(className + ": expected declared method name: \"" + METHOD_NAME +
+ "\", got: \"" + method.getName() + "\"");
+ } else if (Number.class != method.getReturnType()) {
+ throw new RuntimeException(className + ": expected method return type: \"Number\", got \"" +
+ method.getReturnType().toString() + "\"");
+ }
+ }
+
+ private static final String DEX_EXTRA = new File(System.getenv("DEX_LOCATION"),
+ "690-hiddenapi-same-name-methods-ex.jar").getAbsolutePath();
+
+ private static ClassLoader BOOT_CLASS_LOADER = Object.class.getClassLoader();
+
+ private static final String JAVA_CLASS_NAME = "SpecificClass";
+ private static final String METHOD_NAME = "foo";
+
+ // Native functions. Note that these are implemented in 674-hiddenapi/hiddenapi.cc.
+ private static native void appendToBootClassLoader(String dexPath, boolean isCorePlatform);
+ private static native void init();
+}