167f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao/*
267f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao * Copyright (C) 2015 The Android Open Source Project
367f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao *
467f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao * Licensed under the Apache License, Version 2.0 (the "License");
567f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao * you may not use this file except in compliance with the License.
667f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao * You may obtain a copy of the License at
767f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao *
867f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao *      http://www.apache.org/licenses/LICENSE-2.0
967f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao *
1067f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao * Unless required by applicable law or agreed to in writing, software
1167f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao * distributed under the License is distributed on an "AS IS" BASIS,
1267f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1367f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao * See the License for the specific language governing permissions and
1467f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao * limitations under the License.
1567f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao */
1667f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao
175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaopackage android.test.anno;
185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.annotation.Annotation;
205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.Constructor;
215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.Field;
225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.Method;
2375d505305be25f9d4e35bfe883b2faa8f7a7f8e3Hiroshi Yamauchiimport java.lang.reflect.Proxy;
245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.util.TreeMap;
255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaopublic class TestAnnotations {
275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Print the annotations in sorted order, so as to avoid
295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * any (legitimate) non-determinism with regard to the iteration order.
305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static private void printAnnotationArray(String prefix, Annotation[] arr) {
325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        TreeMap<String, Annotation> sorted =
335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            new TreeMap<String, Annotation>();
345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        for (Annotation a : arr) {
365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            sorted.put(a.annotationType().getName(), a);
375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        for (Annotation a : sorted.values()) {
405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println(prefix + "  " + a);
415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println(prefix + "    " + a.annotationType());
425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    static void printAnnotations(Class clazz) {
465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Annotation[] annos;
475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Annotation[][] parAnnos;
485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        annos = clazz.getAnnotations();
505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("annotations on TYPE " + clazz +
515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            "(" + annos.length + "):");
525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        printAnnotationArray("", annos);
535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println();
545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        for (Constructor c: clazz.getDeclaredConstructors()) {
565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            annos = c.getDeclaredAnnotations();
575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("  annotations on CTOR " + c + ":");
585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            printAnnotationArray("  ", annos);
595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("    constructor parameter annotations:");
615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            for (Annotation[] pannos: c.getParameterAnnotations()) {
625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                printAnnotationArray("    ", pannos);
635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        for (Method m: clazz.getDeclaredMethods()) {
675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            annos = m.getDeclaredAnnotations();
685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("  annotations on METH " + m + ":");
695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            printAnnotationArray("  ", annos);
705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("    method parameter annotations:");
725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            for (Annotation[] pannos: m.getParameterAnnotations()) {
735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                printAnnotationArray("    ", pannos);
745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        for (Field f: clazz.getDeclaredFields()) {
785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            annos = f.getDeclaredAnnotations();
795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("  annotations on FIELD " + f + ":");
805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            printAnnotationArray("  ", annos);
815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            AnnoFancyField aff;
835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            aff = (AnnoFancyField) f.getAnnotation(AnnoFancyField.class);
845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            if (aff != null) {
8575d505305be25f9d4e35bfe883b2faa8f7a7f8e3Hiroshi Yamauchi                System.out.println("    aff: " + aff + " / " + Proxy.isProxyClass(aff.getClass()));
865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.out.println("    --> nombre is '" + aff.nombre() + "'");
875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println();
905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    @ExportedProperty(mapping = {
945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        @IntToString(from = 0, to = "NORMAL_FOCUS"),
955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        @IntToString(from = 2, to = "WEAK_FOCUS")
965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    })
975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public int getFocusType() {
985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        return 2;
995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    @AnnoArrayField
1035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    String thing1;
1045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    @AnnoArrayField(
1065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            zz = {true,false,true},
1075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            bb = {-1,0,1},
1085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            cc = {'Q'},
1095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            ss = {12,13,14,15,16,17},
1105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            ii = {1,2,3,4},
1115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            ff = {1.1f,1.2f,1.3f},
1125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            jj = {-5,0,5},
1135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            dd = {0.3,0.6,0.9},
1145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            str = {"hickory","dickory","dock"}
1155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            )
1165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    String thing2;
1175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public static void testArrays() {
1195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        TestAnnotations ta = new TestAnnotations();
1205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Field field;
1215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Annotation[] annotations;
1225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
1245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            field = TestAnnotations.class.getDeclaredField("thing1");
1255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            annotations = field.getAnnotations();
1265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println(field + ": " + annotations[0].toString());
1275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            field = TestAnnotations.class.getDeclaredField("thing2");
1295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            annotations = field.getAnnotations();
1305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println(field + ": " + annotations[0].toString());
1315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (NoSuchFieldException nsfe) {
1325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            throw new RuntimeException(nsfe);
1335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public static void testArrayProblem() {
1375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Method meth;
1385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        ExportedProperty property;
1395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        final IntToString[] mapping;
1405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        try {
1425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            meth = TestAnnotations.class.getMethod("getFocusType",
1435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                    (Class[])null);
1445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        } catch (NoSuchMethodException nsme) {
1455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            throw new RuntimeException(nsme);
1465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
1475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        property = meth.getAnnotation(ExportedProperty.class);
1485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        mapping = property.mapping();
1495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("mapping is " + mapping.getClass() +
1515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            "\n  0='" + mapping[0] + "'\n  1='" + mapping[1] + "'");
1525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /* while we're here, check isAnnotationPresent on Method */
1545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("present(getFocusType, ExportedProperty): " +
1555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            meth.isAnnotationPresent(ExportedProperty.class));
1565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("present(getFocusType, AnnoSimpleType): " +
1575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            meth.isAnnotationPresent(AnnoSimpleType.class));
1585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("");
1605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1627e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao    public static void testVisibilityCompatibility() throws Exception {
1637e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        if (!VMRuntime.isAndroid()) {
1647e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao            return;
1657e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        }
1667e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        Object runtime = VMRuntime.getRuntime();
1677e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        int currentSdkVersion = VMRuntime.getTargetSdkVersion(runtime);
1687e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        // SDK version 23 is M.
1697e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        int oldSdkVersion = 23;
1707e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        VMRuntime.setTargetSdkVersion(runtime, oldSdkVersion);
1717e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        // This annotation has CLASS retention, but is visible to the runtime in M and earlier.
1727e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        Annotation anno = SimplyNoted.class.getAnnotation(AnnoSimpleTypeInvis.class);
1737e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        if (anno == null) {
1747e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao            System.out.println("testVisibilityCompatibility failed: " +
1757e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao                    "SimplyNoted.get(AnnoSimpleTypeInvis) should not be null");
1767e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        }
1777e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        VMRuntime.setTargetSdkVersion(runtime, currentSdkVersion);
1787e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao    }
1795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public static void main(String[] args) {
1815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("TestAnnotations...");
1825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testArrays();
1845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        testArrayProblem();
1855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println(
1875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            "AnnoSimpleField " + AnnoSimpleField.class.isAnnotation() +
1885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            ", SimplyNoted " + SimplyNoted.class.isAnnotation());
1895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
19001afdbab72f5e8c230f3d73a3a61d630670db9abBrian Carlstrom        printAnnotations(SimplyNoted.class);
19101afdbab72f5e8c230f3d73a3a61d630670db9abBrian Carlstrom        printAnnotations(INoted.class);
19201afdbab72f5e8c230f3d73a3a61d630670db9abBrian Carlstrom        printAnnotations(SubNoted.class);
19301afdbab72f5e8c230f3d73a3a61d630670db9abBrian Carlstrom        printAnnotations(FullyNoted.class);
1945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
19501afdbab72f5e8c230f3d73a3a61d630670db9abBrian Carlstrom        try {
19601afdbab72f5e8c230f3d73a3a61d630670db9abBrian Carlstrom            ClassWithInnerAnnotationClass.class.getDeclaredClasses();
19701afdbab72f5e8c230f3d73a3a61d630670db9abBrian Carlstrom            throw new AssertionError();
19801afdbab72f5e8c230f3d73a3a61d630670db9abBrian Carlstrom        } catch (NoClassDefFoundError expected) {
19901afdbab72f5e8c230f3d73a3a61d630670db9abBrian Carlstrom        }
2005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        // this is expected to be non-null
20201afdbab72f5e8c230f3d73a3a61d630670db9abBrian Carlstrom        Annotation anno = SimplyNoted.class.getAnnotation(AnnoSimpleType.class);
2035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("SimplyNoted.get(AnnoSimpleType) = " + anno);
20408305325d3468d5ef413eb0b36b1ea1b3746a6c4Jeff Hao        // this is expected to be null
20508305325d3468d5ef413eb0b36b1ea1b3746a6c4Jeff Hao        anno = SimplyNoted.class.getAnnotation(AnnoSimpleTypeInvis.class);
20608305325d3468d5ef413eb0b36b1ea1b3746a6c4Jeff Hao        System.out.println("SimplyNoted.get(AnnoSimpleTypeInvis) = " + anno);
2075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        // this is non-null if the @Inherited tag is present
2085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        anno = SubNoted.class.getAnnotation(AnnoSimpleType.class);
2095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.out.println("SubNoted.get(AnnoSimpleType) = " + anno);
210db1e390acea08b4afc280711b4aa9b39f44ecfb0Elliott Hughes
211db1e390acea08b4afc280711b4aa9b39f44ecfb0Elliott Hughes        System.out.println();
212db1e390acea08b4afc280711b4aa9b39f44ecfb0Elliott Hughes
213db1e390acea08b4afc280711b4aa9b39f44ecfb0Elliott Hughes        // Package annotations aren't inherited, so getAnnotations and getDeclaredAnnotations are
214db1e390acea08b4afc280711b4aa9b39f44ecfb0Elliott Hughes        // the same.
215db1e390acea08b4afc280711b4aa9b39f44ecfb0Elliott Hughes        System.out.println("Package annotations:");
216db1e390acea08b4afc280711b4aa9b39f44ecfb0Elliott Hughes        printAnnotationArray("    ", TestAnnotations.class.getPackage().getAnnotations());
217db1e390acea08b4afc280711b4aa9b39f44ecfb0Elliott Hughes        System.out.println("Package declared annotations:");
218db1e390acea08b4afc280711b4aa9b39f44ecfb0Elliott Hughes        printAnnotationArray("    ", TestAnnotations.class.getPackage().getDeclaredAnnotations());
219fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao
220fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao        System.out.println();
221fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao
222fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao        // Test inner classes.
223fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao        System.out.println("Inner Classes:");
224fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao        new ClassWithInnerClasses().print();
225fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao
226fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao        System.out.println();
227fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao
228fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao        // Test TypeNotPresentException.
229fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao        try {
230fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao            AnnoMissingClass missingAnno =
231fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao                ClassWithMissingAnnotation.class.getAnnotation(AnnoMissingClass.class);
232fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao            System.out.println("Get annotation with missing class should not throw");
233fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao            System.out.println(missingAnno.value());
234fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao            System.out.println("Getting value of missing annotaton should have thrown");
235fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao        } catch (TypeNotPresentException expected) {
236fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao            System.out.println("Got expected TypeNotPresentException");
237fc8d247275d06047c652abbdd368fe784bf85e67Jeff Hao        }
23867f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao
23967f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao        // Test renamed enums.
24067f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao        try {
24167f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao            for (Method m: RenamedNoted.class.getDeclaredMethods()) {
24267f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao                Annotation[] annos = m.getDeclaredAnnotations();
24367f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao                System.out.println("  annotations on METH " + m + ":");
24467f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao            }
24567f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao        } catch (NoSuchFieldError expected) {
24667f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao            System.out.println("Got expected NoSuchFieldError");
24767f0261f6fcbcac7747e58278c32f449d59fac98Jeff Hao        }
2487e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao
2497e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        // Test if annotations marked VISIBILITY_BUILD are visible to runtime in M and earlier.
2507e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        try {
2517e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao            testVisibilityCompatibility();
2527e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        } catch (Exception e) {
2537e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao            System.out.println("testVisibilityCompatibility failed: " + e);
2547e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        }
2557e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao    }
2567e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao
2577e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao    private static class VMRuntime {
2587e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        private static Class vmRuntimeClass;
2597e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        private static Method getRuntimeMethod;
2607e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        private static Method getTargetSdkVersionMethod;
2617e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        private static Method setTargetSdkVersionMethod;
2627e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        static {
2637e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao            init();
2647e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        }
2657e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao
2667e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        private static void init() {
2677e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao            try {
2687e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao                vmRuntimeClass = Class.forName("dalvik.system.VMRuntime");
2697e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao            } catch (Exception e) {
2707e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao                return;
2717e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao            }
2727e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao            try {
2737e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao                getRuntimeMethod = vmRuntimeClass.getDeclaredMethod("getRuntime");
2747e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao                getTargetSdkVersionMethod =
2757e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao                        vmRuntimeClass.getDeclaredMethod("getTargetSdkVersion");
2767e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao                setTargetSdkVersionMethod =
2777e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao                        vmRuntimeClass.getDeclaredMethod("setTargetSdkVersion", Integer.TYPE);
2787e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao            } catch (Exception e) {
2797e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao                throw new RuntimeException(e);
2807e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao            }
2817e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        }
2827e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao
2837e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        public static boolean isAndroid() {
2847e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao            return vmRuntimeClass != null;
2857e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        }
2867e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao
2877e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        public static Object getRuntime() throws Exception {
2887e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao            return getRuntimeMethod.invoke(null);
2897e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        }
2907e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao
2917e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        public static int getTargetSdkVersion(Object runtime) throws Exception {
2927e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao            return (int) getTargetSdkVersionMethod.invoke(runtime);
2937e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        }
2947e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao
2957e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        public static void setTargetSdkVersion(Object runtime, int version) throws Exception {
2967e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao            setTargetSdkVersionMethod.invoke(runtime, version);
2977e50a7a5a1ad947e84c425efb2e97c442f91b155Jeff Hao        }
2985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
300