111216907: Private stub annotation classes breaks compilation

This CL updates metalava such that it *only* packages
the @RecentlyNullable and @RecentlyNonNull annotations
as package private stub annotations; the rest of the
annotations are packaged as external annotations (which
was the case prior to P anyway).

It also turns off type-use annotations, since they are
not properly supported anyway; their restoral is tracked
in issue 111253910.

Fixes: 111216907
Test: Unit tests updated

Change-Id: Ia9b85bf75e143ae3dd622300f1731a30df2a16cd
Merged-In: I1d454024aeaee60daa8c717d40e352300ff768cc
diff --git a/src/main/java/com/android/tools/metalava/AnnotationsMerger.kt b/src/main/java/com/android/tools/metalava/AnnotationsMerger.kt
index 11ff5d5..c32c7df 100644
--- a/src/main/java/com/android/tools/metalava/AnnotationsMerger.kt
+++ b/src/main/java/com/android/tools/metalava/AnnotationsMerger.kt
@@ -57,6 +57,7 @@
 import com.android.tools.metalava.model.Item
 import com.android.tools.metalava.model.MethodItem
 import com.android.tools.metalava.model.PackageItem
+import com.android.tools.metalava.model.SUPPORT_TYPE_USE_ANNOTATIONS
 import com.android.tools.metalava.model.psi.PsiAnnotationItem
 import com.android.tools.metalava.model.visitors.ApiVisitor
 import com.android.utils.XmlUtils
@@ -267,7 +268,7 @@
                     null
                 }
                 curr = parameterItem
-            } else if (line.startsWith("type: ")) {
+            } else if (line.startsWith("type: ") && SUPPORT_TYPE_USE_ANNOTATIONS) {
                 val typeAnnotation = line.substring("type: ".length)
                 if (curr != null) {
                     mergeJaifAnnotation(path, curr, typeAnnotation)
@@ -277,7 +278,7 @@
                 if (methodItem != null) {
                     mergeJaifAnnotation(path, methodItem, annotation)
                 }
-            } else if (line.startsWith("inner-type")) {
+            } else if (line.startsWith("inner-type") && SUPPORT_TYPE_USE_ANNOTATIONS) {
                 warning("$path: Skipping inner-type annotations for now ($line)")
             } else if (line.startsWith("int ")) {
                 // warning("Skipping int attribute definitions for annotations now ($line)")
diff --git a/src/main/java/com/android/tools/metalava/Driver.kt b/src/main/java/com/android/tools/metalava/Driver.kt
index e7e5eff..ed27efb 100644
--- a/src/main/java/com/android/tools/metalava/Driver.kt
+++ b/src/main/java/com/android/tools/metalava/Driver.kt
@@ -345,7 +345,9 @@
             // Support pointing to both stub-annotations and stub-annotations/src/main/java
             val src = File(stubAnnotations, "src${File.separator}main${File.separator}java")
             val source = if (src.isDirectory) src else stubAnnotations
-            RewriteAnnotations().copyAnnotations(source, it)
+            source.listFiles()?.forEach { file ->
+                RewriteAnnotations().copyAnnotations(file, File(it, file.name))
+            }
         }
     }
 
diff --git a/src/main/java/com/android/tools/metalava/ExtractAnnotations.kt b/src/main/java/com/android/tools/metalava/ExtractAnnotations.kt
index dd3fb67..b0a7e8b 100644
--- a/src/main/java/com/android/tools/metalava/ExtractAnnotations.kt
+++ b/src/main/java/com/android/tools/metalava/ExtractAnnotations.kt
@@ -101,25 +101,35 @@
 
                     val pairs = packageToAnnotationPairs[pkg] ?: continue
 
+                    // Ensure stable output
+                    if (pairs.size > 1) {
+                        pairs.sortBy { it.first.getExternalAnnotationSignature() }
+                    }
+
                     StringPrintWriter.create().use { writer ->
                         writer.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<root>")
 
+                        var open = false
                         var prev: Item? = null
                         for ((item, annotation) in pairs) {
-                            // that we only do analysis for IntDef/LongDef
-                            assert(item != prev) // should be only one annotation per element now
+                            if (item != prev) {
+                                if (open) {
+                                    writer.print("  </item>")
+                                    writer.println()
+                                }
+                                writer.print("  <item name=\"")
+                                writer.print(item.getExternalAnnotationSignature())
+                                writer.println("\">")
+                                open = true
+                            }
                             prev = item
 
-                            writer.print("  <item name=\"")
-                            writer.print(item.getExternalAnnotationSignature())
-                            writer.println("\">")
-
                             writeAnnotation(writer, item, annotation)
-
+                        }
+                        if (open) {
                             writer.print("  </item>")
                             writer.println()
                         }
-
                         writer.println("</root>\n")
                         writer.close()
                         val bytes = writer.contents.toByteArray(Charsets.UTF_8)
@@ -131,15 +141,7 @@
         }
     }
 
-    /** For a given item, extract the relevant annotations for that item.
-     *
-     * Currently, we're only extracting typedef annotations. Everything else
-     * has class retention.
-     */
-    private fun checkItem(item: Item) {
-        // field, method or parameter
-        val typedef = findTypeDef(item) ?: return
-
+    private fun addItem(item: Item, annotation: AnnotationHolder) {
         val pkg = when (item) {
             is MemberItem -> item.containingClass().containingPackage()
             is ParameterItem -> item.containingMethod().containingClass().containingPackage()
@@ -152,7 +154,7 @@
             packageToAnnotationPairs[pkg] = new
             new
         }
-        list.add(Pair(item, typedef))
+        list.add(Pair(item, annotation))
     }
 
     override fun visitField(field: FieldItem) {
@@ -167,7 +169,8 @@
         checkItem(parameter)
     }
 
-    private fun findTypeDef(item: Item): AnnotationHolder? {
+    /** For a given item, extract the relevant annotations for that item */
+    private fun checkItem(item: Item) {
         for (annotation in item.modifiers.annotations()) {
             val qualifiedName = annotation.qualifiedName() ?: continue
             if (qualifiedName.startsWith(JAVA_LANG_PREFIX) ||
@@ -177,7 +180,11 @@
             ) {
                 if (annotation.isTypeDefAnnotation()) {
                     // Imported typedef
-                    return AnnotationHolder(null, annotation, null)
+                    addItem(item, AnnotationHolder(null, annotation, null))
+                } else if (annotation.isSignificant() && !annotation.hasClassRetention() &&
+                    !options.includeSourceRetentionAnnotations
+                ) {
+                    addItem(item, AnnotationHolder(null, annotation, null))
                 }
 
                 continue
@@ -188,7 +195,8 @@
             if (typeDefClass.isAnnotationType()) {
                 val cached = classToAnnotationHolder[className]
                 if (cached != null) {
-                    return cached
+                    addItem(item, cached)
+                    continue
                 }
 
                 val typeDefAnnotation = typeDefClass.modifiers.annotations().firstOrNull {
@@ -220,12 +228,12 @@
                             )
                         )
                         classToAnnotationHolder[className] = result
-                        return result
+                        addItem(item, result)
+                        continue
                     }
                 }
             }
         }
-        return null
     }
 
     private fun hasSourceRetention(annotationClass: ClassItem): Boolean {
@@ -374,112 +382,115 @@
         annotationHolder: AnnotationHolder
     ) {
         val annotationItem = annotationHolder.annotationItem
+        val uAnnotation = annotationHolder.uAnnotation
+            ?: if (annotationItem is PsiAnnotationItem) {
+                // Imported annotation
+                JavaUAnnotation.wrap(annotationItem.psiAnnotation)
+            } else {
+                return
+            }
         val qualifiedName = annotationItem.qualifiedName()
 
         writer.mark()
         writer.print("    <annotation name=\"")
         writer.print(qualifiedName)
 
+        var attributes = uAnnotation.attributeValues
+        if (attributes.isEmpty()) {
+            writer.print("\"/>")
+            writer.println()
+            return
+        }
+
         writer.print("\">")
         writer.println()
 
-        val uAnnotation = annotationHolder.uAnnotation
-            ?: if (annotationItem is PsiAnnotationItem) {
-                // Imported annotation
-                JavaUAnnotation.wrap(annotationItem.psiAnnotation)
-            } else {
-                null
-            }
-        if (uAnnotation != null) {
-            var attributes = uAnnotation.attributeValues
+        // noinspection PointlessBooleanExpression,ConstantConditions
+        if (attributes.size > 1 && sortAnnotations) {
+            // Ensure mutable
+            attributes = ArrayList(attributes)
 
-            // noinspection PointlessBooleanExpression,ConstantConditions
-            if (attributes.size > 1 && sortAnnotations) {
-                // Ensure mutable
-                attributes = ArrayList(attributes)
+            // Ensure that the value attribute is written first
+            attributes.sortedWith(object : Comparator<UNamedExpression> {
+                private fun getName(pair: UNamedExpression): String {
+                    val name = pair.name
+                    return name ?: SdkConstants.ATTR_VALUE
+                }
 
-                // Ensure that the value attribute is written first
-                attributes.sortedWith(object : Comparator<UNamedExpression> {
-                    private fun getName(pair: UNamedExpression): String {
-                        val name = pair.name
-                        return name ?: SdkConstants.ATTR_VALUE
-                    }
+                private fun rank(pair: UNamedExpression): Int {
+                    return if (SdkConstants.ATTR_VALUE == getName(pair)) -1 else 0
+                }
 
-                    private fun rank(pair: UNamedExpression): Int {
-                        return if (SdkConstants.ATTR_VALUE == getName(pair)) -1 else 0
-                    }
+                override fun compare(o1: UNamedExpression, o2: UNamedExpression): Int {
+                    val r1 = rank(o1)
+                    val r2 = rank(o2)
+                    val delta = r1 - r2
+                    return if (delta != 0) {
+                        delta
+                    } else getName(o1).compareTo(getName(o2))
+                }
+            })
+        }
 
-                    override fun compare(o1: UNamedExpression, o2: UNamedExpression): Int {
-                        val r1 = rank(o1)
-                        val r2 = rank(o2)
-                        val delta = r1 - r2
-                        return if (delta != 0) {
-                            delta
-                        } else getName(o1).compareTo(getName(o2))
-                    }
-                })
-            }
-
-            if (attributes.size == 1 && Extractor.REQUIRES_PERMISSION.isPrefix(qualifiedName, true)) {
-                val expression = attributes[0].expression
-                if (expression is UAnnotation) {
-                    // The external annotations format does not allow for nested/complex annotations.
-                    // However, these special annotations (@RequiresPermission.Read,
-                    // @RequiresPermission.Write, etc) are known to only be simple containers with a
-                    // single permission child, so instead we "inline" the content:
-                    //  @Read(@RequiresPermission(allOf={P1,P2},conditional=true)
-                    //     =>
-                    //      @RequiresPermission.Read(allOf({P1,P2},conditional=true)
-                    // That's setting attributes that don't actually exist on the container permission,
-                    // but we'll counteract that on the read-annotations side.
-                    val annotation = expression as UAnnotation
+        if (attributes.size == 1 && Extractor.REQUIRES_PERMISSION.isPrefix(qualifiedName, true)) {
+            val expression = attributes[0].expression
+            if (expression is UAnnotation) {
+                // The external annotations format does not allow for nested/complex annotations.
+                // However, these special annotations (@RequiresPermission.Read,
+                // @RequiresPermission.Write, etc) are known to only be simple containers with a
+                // single permission child, so instead we "inline" the content:
+                //  @Read(@RequiresPermission(allOf={P1,P2},conditional=true)
+                //     =>
+                //      @RequiresPermission.Read(allOf({P1,P2},conditional=true)
+                // That's setting attributes that don't actually exist on the container permission,
+                // but we'll counteract that on the read-annotations side.
+                val annotation = expression as UAnnotation
+                attributes = annotation.attributeValues
+            } else if (expression is JavaUAnnotationCallExpression) {
+                val annotation = expression.uAnnotation
+                attributes = annotation.attributeValues
+            } else if (expression is UastEmptyExpression && attributes[0].sourcePsi is PsiNameValuePair) {
+                val memberValue = (attributes[0].sourcePsi as PsiNameValuePair).value
+                if (memberValue is PsiAnnotation) {
+                    val annotation = JavaUAnnotation.wrap(memberValue)
                     attributes = annotation.attributeValues
-                } else if (expression is JavaUAnnotationCallExpression) {
-                    val annotation = expression.uAnnotation
-                    attributes = annotation.attributeValues
-                } else if (expression is UastEmptyExpression && attributes[0].sourcePsi is PsiNameValuePair) {
-                    val memberValue = (attributes[0].sourcePsi as PsiNameValuePair).value
-                    if (memberValue is PsiAnnotation) {
-                        val annotation = JavaUAnnotation.wrap(memberValue)
-                        attributes = annotation.attributeValues
-                    }
                 }
             }
+        }
 
-            val inlineConstants = isInlinedConstant(annotationItem)
-            var empty = true
-            for (pair in attributes) {
-                val expression = pair.expression
-                val value = attributeString(expression, inlineConstants) ?: continue
-                empty = false
-                var name = pair.name
-                if (name == null) {
-                    name = SdkConstants.ATTR_VALUE // default name
-                }
-
-                // Platform typedef annotations now declare a prefix attribute for
-                // documentation generation purposes; this should not be part of the
-                // extracted metadata.
-                if (("prefix" == name || "suffix" == name) && annotationItem.isTypeDefAnnotation()) {
-                    reporter.report(
-                        Errors.SUPERFLUOUS_PREFIX, item,
-                        "Superfluous $name attribute on typedef"
-                    )
-                    continue
-                }
-
-                writer.print("      <val name=\"")
-                writer.print(name)
-                writer.print("\" val=\"")
-                writer.print(escapeXml(value))
-                writer.println("\" />")
+        val inlineConstants = isInlinedConstant(annotationItem)
+        var empty = true
+        for (pair in attributes) {
+            val expression = pair.expression
+            val value = attributeString(expression, inlineConstants) ?: continue
+            empty = false
+            var name = pair.name
+            if (name == null) {
+                name = SdkConstants.ATTR_VALUE // default name
             }
 
-            if (empty) {
-                // All items were filtered out: don't write the annotation at all
-                writer.reset()
-                return
+            // Platform typedef annotations now declare a prefix attribute for
+            // documentation generation purposes; this should not be part of the
+            // extracted metadata.
+            if (("prefix" == name || "suffix" == name) && annotationItem.isTypeDefAnnotation()) {
+                reporter.report(
+                    Errors.SUPERFLUOUS_PREFIX, item,
+                    "Superfluous $name attribute on typedef"
+                )
+                continue
             }
+
+            writer.print("      <val name=\"")
+            writer.print(name)
+            writer.print("\" val=\"")
+            writer.print(escapeXml(value))
+            writer.println("\" />")
+        }
+
+        if (empty && attributes.isNotEmpty()) {
+            // All items were filtered out: don't write the annotation at all
+            writer.reset()
+            return
         }
 
         writer.println("    </annotation>")
diff --git a/src/main/java/com/android/tools/metalava/Options.kt b/src/main/java/com/android/tools/metalava/Options.kt
index ed177f5..5bd8415 100644
--- a/src/main/java/com/android/tools/metalava/Options.kt
+++ b/src/main/java/com/android/tools/metalava/Options.kt
@@ -110,6 +110,7 @@
 private const val ARG_COPY_ANNOTATIONS = "--copy-annotations"
 private const val ARG_INCLUDE_ANNOTATION_CLASSES = "--include-annotation-classes"
 private const val ARG_REWRITE_ANNOTATIONS = "--rewrite-annotations"
+private const val ARG_INCLUDE_SOURCE_RETENTION = "--include-source-retention"
 
 class Options(
     args: Array<String>,
@@ -267,10 +268,19 @@
     /** For [ARG_COPY_ANNOTATIONS], the target directory to write converted stub annotations from */
     var privateAnnotationsTarget: File? = null
 
-    /** For [ARG_INCLUDE_ANNOTATION_CLASSES], the directory to copy stub annotation source files into the
-     * stubs folder from */
+    /**
+     * For [ARG_INCLUDE_ANNOTATION_CLASSES], the directory to copy stub annotation source files into the
+     * stubs folder from
+     */
     var copyStubAnnotationsFrom: File? = null
 
+    /**
+     * For [ARG_INCLUDE_SOURCE_RETENTION], true if we want to include source-retention annotations
+     * both in the set of files emitted by [ARG_INCLUDE_ANNOTATION_CLASSES] and into the stubs
+     * themselves
+     */
+    var includeSourceRetentionAnnotations = false
+
     /** For [ARG_REWRITE_ANNOTATIONS], the jar or bytecode folder to rewrite annotations in */
     var rewriteAnnotations: List<File>? = null
 
@@ -545,6 +555,7 @@
                 }
                 ARG_REWRITE_ANNOTATIONS -> rewriteAnnotations = stringToExistingDirsOrJars(getValue(args, ++index))
                 ARG_INCLUDE_ANNOTATION_CLASSES -> copyStubAnnotationsFrom = stringToExistingDir(getValue(args, ++index))
+                ARG_INCLUDE_SOURCE_RETENTION -> includeSourceRetentionAnnotations = true
 
                 ARG_PREVIOUS_API -> previousApi = stringToExistingFile(getValue(args, ++index))
                 ARG_CURRENT_API -> currentApi = stringToExistingFile(getValue(args, ++index))
@@ -1315,7 +1326,9 @@
 //                "sources, generates corresponding package private versions of the same annotations.",
             "$ARG_REWRITE_ANNOTATIONS <dir/jar>", "For a bytecode folder or output jar, rewrites the " +
                 "androidx annotations to be package private",
-
+            ARG_INCLUDE_SOURCE_RETENTION, "If true, include source-retention annotations in the stub files. Does " +
+                "not apply to signature files. Source retention annotations are extracted into the external " +
+                "annotations files instead.",
             "", "\nInjecting API Levels:",
             "$ARG_APPLY_API_LEVELS <api-versions.xml>", "Reads an XML file containing API level descriptions " +
                 "and merges the information into the documentation",
diff --git a/src/main/java/com/android/tools/metalava/RewriteAnnotations.kt b/src/main/java/com/android/tools/metalava/RewriteAnnotations.kt
index 283ac7d..78117c1 100644
--- a/src/main/java/com/android/tools/metalava/RewriteAnnotations.kt
+++ b/src/main/java/com/android/tools/metalava/RewriteAnnotations.kt
@@ -19,6 +19,7 @@
 import com.android.SdkConstants
 import com.android.SdkConstants.DOT_CLASS
 import com.android.SdkConstants.DOT_JAR
+import com.android.tools.metalava.model.AnnotationItem
 import com.google.common.io.Closer
 import org.objectweb.asm.ClassReader
 import org.objectweb.asm.ClassVisitor
@@ -46,14 +47,24 @@
 
 class RewriteAnnotations {
     /** Copies annotation source files from [source] to [target] */
-    fun copyAnnotations(source: File, target: File) {
-        if (source.name.endsWith(SdkConstants.DOT_JAVA)) {
+    fun copyAnnotations(source: File, target: File, pkg: String = "") {
+        val fileName = source.name
+        if (fileName.endsWith(SdkConstants.DOT_JAVA)) {
+            if (!options.includeSourceRetentionAnnotations) {
+                // Only copy non-source retention annotation classes
+                val qualifiedName = pkg + "." + fileName.substring(0, fileName.indexOf('.'))
+                if (!AnnotationItem.hasClassRetention(qualifiedName)) {
+                    return
+                }
+            }
+
             // Copy and convert
             target.parentFile.mkdirs()
             source.copyTo(target)
         } else if (source.isDirectory) {
+            val newPackage = if (pkg.isEmpty()) fileName else "$pkg.$fileName"
             source.listFiles()?.forEach {
-                copyAnnotations(it, File(target, it.name))
+                copyAnnotations(it, File(target, it.name), newPackage)
             }
         }
     }
diff --git a/src/main/java/com/android/tools/metalava/SignatureWriter.kt b/src/main/java/com/android/tools/metalava/SignatureWriter.kt
index ad4f947..5577234 100644
--- a/src/main/java/com/android/tools/metalava/SignatureWriter.kt
+++ b/src/main/java/com/android/tools/metalava/SignatureWriter.kt
@@ -150,7 +150,8 @@
             includeAnnotations = compatibility.annotationsInSignatures,
             skipNullnessAnnotations = options.outputKotlinStyleNulls,
             omitCommonPackages = options.omitCommonPackages,
-            onlyIncludeSignatureAnnotations = true
+            onlyIncludeSignatureAnnotations = true,
+            onlyIncludeClassRetentionAnnotations = false
         )
     }
 
diff --git a/src/main/java/com/android/tools/metalava/StubWriter.kt b/src/main/java/com/android/tools/metalava/StubWriter.kt
index 40a6a5a..06d5221 100644
--- a/src/main/java/com/android/tools/metalava/StubWriter.kt
+++ b/src/main/java/com/android/tools/metalava/StubWriter.kt
@@ -141,6 +141,7 @@
                 // here; make sure the are filtered out
                 filterDuplicates = true,
                 onlyIncludeSignatureAnnotations = true,
+                onlyIncludeClassRetentionAnnotations = true,
                 writer = writer
             )
             writer.println("package ${pkg.qualifiedName()};")
@@ -302,7 +303,8 @@
         ModifierList.write(
             writer, modifiers, item, removeAbstract = removeAbstract, removeFinal = removeFinal,
             addPublic = addPublic, includeAnnotations = generateAnnotations,
-            onlyIncludeSignatureAnnotations = true
+            onlyIncludeSignatureAnnotations = true,
+            onlyIncludeClassRetentionAnnotations = true
         )
     }
 
diff --git a/src/main/java/com/android/tools/metalava/model/AnnotationItem.kt b/src/main/java/com/android/tools/metalava/model/AnnotationItem.kt
index aa1acba..52743fd 100644
--- a/src/main/java/com/android/tools/metalava/model/AnnotationItem.kt
+++ b/src/main/java/com/android/tools/metalava/model/AnnotationItem.kt
@@ -57,6 +57,14 @@
         return includeInSignatures(qualifiedName() ?: return false)
     }
 
+    /**
+     * Whether this annotation has class retention. Only class retention annotations are
+     * inserted into the stubs, the rest are extracted into the separate external annotations file.
+     */
+    fun hasClassRetention(): Boolean {
+        return hasClassRetention(qualifiedName())
+    }
+
     /** Attributes of the annotation (may be empty) */
     fun attributes(): List<AnnotationAttribute>
 
@@ -250,6 +258,8 @@
                 "android.annotation.CheckResult" -> return "androidx.annotation.CheckResult"
                 "android.support.annotation.RequiresPermission",
                 "android.annotation.RequiresPermission" -> return "androidx.annotation.RequiresPermission"
+                "android.annotation.RequiresPermission.Read" -> return "androidx.annotation.RequiresPermission.Read"
+                "android.annotation.RequiresPermission.Write" -> return "androidx.annotation.RequiresPermission.Write"
 
             // These aren't support annotations, but could/should be:
                 "android.annotation.CurrentTimeMillisLong",
@@ -388,6 +398,21 @@
                 }
             }
         }
+
+        fun hasClassRetention(qualifiedName: String?): Boolean {
+            // For now, we treat everything except the recently nullable annotations
+            // as source retention; this works around the bug that we don't want to
+            // reference (from the .class files) annotations that aren't part of the SDK
+            // except for those that we include with the stubs
+
+            qualifiedName ?: return false
+
+            return when (qualifiedName) {
+                "androidx.annotation.RecentlyNullable",
+                "androidx.annotation.RecentlyNonNull" -> true
+                else -> false
+            }
+        }
     }
 }
 
diff --git a/src/main/java/com/android/tools/metalava/model/Codebase.kt b/src/main/java/com/android/tools/metalava/model/Codebase.kt
index 41ce549..3c86e61 100644
--- a/src/main/java/com/android/tools/metalava/model/Codebase.kt
+++ b/src/main/java/com/android/tools/metalava/model/Codebase.kt
@@ -155,7 +155,7 @@
     override var manifest: File? = null
     private var permissions: Map<String, String>? = null
     override var original: Codebase? = null
-    override var supportsStagedNullability: Boolean = false
+    override var supportsStagedNullability: Boolean = true
     override var units: List<PsiFile> = emptyList()
     override var apiLevel: Int = -1
 
diff --git a/src/main/java/com/android/tools/metalava/model/ModifierList.kt b/src/main/java/com/android/tools/metalava/model/ModifierList.kt
index 435baf8..d192cd3 100644
--- a/src/main/java/com/android/tools/metalava/model/ModifierList.kt
+++ b/src/main/java/com/android/tools/metalava/model/ModifierList.kt
@@ -184,8 +184,8 @@
             removeAbstract: Boolean = false,
             removeFinal: Boolean = false,
             addPublic: Boolean = false,
-            onlyIncludeSignatureAnnotations: Boolean = true
-
+            onlyIncludeSignatureAnnotations: Boolean = true,
+            onlyIncludeClassRetentionAnnotations: Boolean = false
         ) {
 
             val list = if (removeAbstract || removeFinal || addPublic) {
@@ -214,7 +214,8 @@
                     omitCommonPackages = omitCommonPackages,
                     separateLines = false,
                     writer = writer,
-                    onlyIncludeSignatureAnnotations = onlyIncludeSignatureAnnotations
+                    onlyIncludeSignatureAnnotations = onlyIncludeSignatureAnnotations,
+                    onlyIncludeClassRetentionAnnotations = onlyIncludeClassRetentionAnnotations
                 )
             }
 
@@ -387,19 +388,23 @@
             separateLines: Boolean = false,
             filterDuplicates: Boolean = false,
             writer: Writer,
-            onlyIncludeSignatureAnnotations: Boolean = true
+            onlyIncludeSignatureAnnotations: Boolean = true,
+            onlyIncludeClassRetentionAnnotations: Boolean = false
         ) {
             val annotations = list.annotations()
             if (annotations.isNotEmpty()) {
                 var index = -1
                 for (annotation in annotations) {
                     index++
-                    if ((annotation.isNonNull() || annotation.isNullable())) {
+                    if (onlyIncludeSignatureAnnotations && !annotation.isSignificant()) {
+                        continue
+                    } else if (onlyIncludeClassRetentionAnnotations && !annotation.hasClassRetention() &&
+                        !options.includeSourceRetentionAnnotations) {
+                        continue
+                    } else if ((annotation.isNonNull() || annotation.isNullable())) {
                         if (skipNullnessAnnotations) {
                             continue
                         }
-                    } else if (onlyIncludeSignatureAnnotations && !annotation.isSignificant()) {
-                        continue
                     }
 
                     // Optionally filter out duplicates
diff --git a/src/main/java/com/android/tools/metalava/model/TypeItem.kt b/src/main/java/com/android/tools/metalava/model/TypeItem.kt
index 5d1eaa8..b1ac351 100644
--- a/src/main/java/com/android/tools/metalava/model/TypeItem.kt
+++ b/src/main/java/com/android/tools/metalava/model/TypeItem.kt
@@ -23,6 +23,14 @@
 import com.android.tools.metalava.options
 import java.util.function.Predicate
 
+/**
+ * Whether metalava supports type use annotations.
+ * Note that you can't just turn this flag back on; you have to
+ * also add TYPE_USE back to the handful of nullness
+ * annotations in stub-annotations/src/main/java/.
+ */
+const val SUPPORT_TYPE_USE_ANNOTATIONS = false
+
 /** Represents a type */
 interface TypeItem {
     /**
diff --git a/src/main/java/com/android/tools/metalava/model/psi/PsiMethodItem.kt b/src/main/java/com/android/tools/metalava/model/psi/PsiMethodItem.kt
index a54dc24..bbcae2a 100644
--- a/src/main/java/com/android/tools/metalava/model/psi/PsiMethodItem.kt
+++ b/src/main/java/com/android/tools/metalava/model/psi/PsiMethodItem.kt
@@ -250,7 +250,8 @@
         ModifierList.write(
             modifierString, method.modifiers, method, removeAbstract = false,
             removeFinal = false, addPublic = true,
-            onlyIncludeSignatureAnnotations = true
+            onlyIncludeSignatureAnnotations = true,
+            onlyIncludeClassRetentionAnnotations = true
         )
         sb.append(modifierString.toString())
 
diff --git a/src/main/java/com/android/tools/metalava/model/psi/PsiTypeItem.kt b/src/main/java/com/android/tools/metalava/model/psi/PsiTypeItem.kt
index 248d047..be0d36c 100644
--- a/src/main/java/com/android/tools/metalava/model/psi/PsiTypeItem.kt
+++ b/src/main/java/com/android/tools/metalava/model/psi/PsiTypeItem.kt
@@ -24,6 +24,7 @@
 import com.android.tools.metalava.model.Codebase
 import com.android.tools.metalava.model.Item
 import com.android.tools.metalava.model.MemberItem
+import com.android.tools.metalava.model.SUPPORT_TYPE_USE_ANNOTATIONS
 import com.android.tools.metalava.model.TypeItem
 import com.android.tools.metalava.model.TypeParameterItem
 import com.android.tools.metalava.model.text.TextTypeItem
@@ -73,7 +74,7 @@
         assert(innerAnnotations || !outerAnnotations) // Can't supply outer=true,inner=false
 
         return if (erased) {
-            if (innerAnnotations || outerAnnotations) {
+            if (SUPPORT_TYPE_USE_ANNOTATIONS && (innerAnnotations || outerAnnotations)) {
                 // Not cached: Not common
                 toTypeString(codebase, psiType, outerAnnotations, innerAnnotations, erased)
             } else {
@@ -84,7 +85,7 @@
             }
         } else {
             when {
-                outerAnnotations -> {
+                SUPPORT_TYPE_USE_ANNOTATIONS && outerAnnotations -> {
                     if (toAnnotatedString == null) {
                         toAnnotatedString = TypeItem.formatType(
                             toTypeString(
@@ -98,7 +99,7 @@
                     }
                     toAnnotatedString!!
                 }
-                innerAnnotations -> {
+                SUPPORT_TYPE_USE_ANNOTATIONS && innerAnnotations -> {
                     if (toInnerAnnotatedString == null) {
                         toInnerAnnotatedString = TypeItem.formatType(
                             toTypeString(
@@ -339,7 +340,7 @@
                 )
             }
 
-            if (outerAnnotations || innerAnnotations) {
+            if (SUPPORT_TYPE_USE_ANNOTATIONS && (innerAnnotations || outerAnnotations)) {
                 val typeString = mapAnnotations(codebase, getCanonicalText(type, true))
                 if (!outerAnnotations && typeString.contains("@")) {
                     // Temporary hack: should use PSI type visitor instead
@@ -404,8 +405,8 @@
         }
 
         private fun getCanonicalText(type: PsiType, annotated: Boolean): String {
-            val typeString = type.getCanonicalText(annotated)
-            if (!annotated) {
+            val typeString = type.getCanonicalText(annotated && SUPPORT_TYPE_USE_ANNOTATIONS)
+            if (!annotated || !SUPPORT_TYPE_USE_ANNOTATIONS) {
                 return typeString
             }
 
@@ -764,4 +765,4 @@
             }
         }
     }
-}
\ No newline at end of file
+}
diff --git a/src/main/resources/version.properties b/src/main/resources/version.properties
index dd2d971..ab0e374 100644
--- a/src/main/resources/version.properties
+++ b/src/main/resources/version.properties
@@ -1,4 +1,4 @@
 # Version definition
 # This file is read by gradle build scripts, but also packaged with metalava
 # as a resource for the Version classes to read.
-metalavaVersion=0.9.12
+metalavaVersion=1.0.0
diff --git a/src/test/java/com/android/tools/metalava/AnnotationStatisticsTest.kt b/src/test/java/com/android/tools/metalava/AnnotationStatisticsTest.kt
index f62c805..4a1cf39 100644
--- a/src/test/java/com/android/tools/metalava/AnnotationStatisticsTest.kt
+++ b/src/test/java/com/android/tools/metalava/AnnotationStatisticsTest.kt
@@ -163,8 +163,8 @@
                     }
                     """
                 ),
-                supportNonNullSource,
-                supportNullableSource
+                androidxNonNullSource,
+                androidxNullableSource
             ),
             expectedOutput = """
                 6 methods and fields were missing nullness annotations out of 8 total API references.
diff --git a/src/test/java/com/android/tools/metalava/AnnotationsMergerTest.kt b/src/test/java/com/android/tools/metalava/AnnotationsMergerTest.kt
index 654ed1a..003e7ba 100644
--- a/src/test/java/com/android/tools/metalava/AnnotationsMergerTest.kt
+++ b/src/test/java/com/android/tools/metalava/AnnotationsMergerTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.tools.metalava
 
+import com.android.tools.metalava.model.SUPPORT_TYPE_USE_ANNOTATIONS
 import org.junit.Test
 
 class AnnotationsMergerTest : DriverTest() {
@@ -50,8 +51,8 @@
                 ),
                 uiThreadSource,
                 intRangeAnnotationSource,
-                supportNonNullSource,
-                supportNullableSource
+                androidxNonNullSource,
+                androidxNullableSource
             ),
             // Skip the annotations themselves from the output
             extraArguments = arrayOf(
@@ -162,14 +163,25 @@
                         // Is expected to return self
                         return: @libcore.util.NonNull
                 """,
-            api = """
-                package test.pkg {
-                  public interface Appendable {
-                    method @androidx.annotation.NonNull public test.pkg.Appendable append(@androidx.annotation.Nullable java.lang.CharSequence);
-                    method public java.lang.String reverse(java.lang.String);
-                  }
-                }
+            api = if (SUPPORT_TYPE_USE_ANNOTATIONS) {
                 """
+                    package test.pkg {
+                      public interface Appendable {
+                        method @androidx.annotation.NonNull public test.pkg.Appendable append(@androidx.annotation.Nullable java.lang.CharSequence);
+                        method public java.lang.String reverse(java.lang.String);
+                      }
+                    }
+                   """
+            } else {
+                """
+                    package test.pkg {
+                      public interface Appendable {
+                        method @androidx.annotation.NonNull public test.pkg.Appendable append(java.lang.CharSequence);
+                        method public java.lang.String reverse(java.lang.String);
+                      }
+                    }
+                   """
+            }
         )
     }
 
diff --git a/src/test/java/com/android/tools/metalava/ApiFileTest.kt b/src/test/java/com/android/tools/metalava/ApiFileTest.kt
index 5c66e1c..387c24e 100644
--- a/src/test/java/com/android/tools/metalava/ApiFileTest.kt
+++ b/src/test/java/com/android/tools/metalava/ApiFileTest.kt
@@ -381,8 +381,8 @@
                     inline operator fun <F, S> PlatformJavaPair<F, S>.component1() = first
                     """
                 ),
-                supportNonNullSource,
-                supportNullableSource
+                androidxNonNullSource,
+                androidxNullableSource
             ),
             api = """
                 package androidx.util {
diff --git a/src/test/java/com/android/tools/metalava/DriverTest.kt b/src/test/java/com/android/tools/metalava/DriverTest.kt
index 13ad8cd..1449791 100644
--- a/src/test/java/com/android/tools/metalava/DriverTest.kt
+++ b/src/test/java/com/android/tools/metalava/DriverTest.kt
@@ -219,7 +219,12 @@
         /** Map from artifact id to artifact descriptor */
         artifacts: Map<String, String>? = null,
         /** Extract annotations and check that the given packages contain the given extracted XML files */
-        extractAnnotations: Map<String, String>? = null
+        extractAnnotations: Map<String, String>? = null,
+        /**
+         * Whether to include source retention annotations in the stubs (in that case they do not
+         * go into the extracted annotations zip file)
+         */
+        includeSourceRetentionAnnotations: Boolean = true
     ) {
         System.setProperty("METALAVA_TESTS_RUNNING", VALUE_TRUE)
 
@@ -407,7 +412,14 @@
             if (showUnannotated) {
                 arrayOf("--show-unannotated")
             } else {
-                emptyArray<String>()
+                emptyArray()
+            }
+
+        val includeSourceRetentionAnnotationArgs =
+            if (includeSourceRetentionAnnotations) {
+                arrayOf("--include-source-retention")
+            } else {
+                emptyArray()
             }
 
         var removedApiFile: File? = null
@@ -606,6 +618,7 @@
             *applyApiLevelsXmlArgs,
             *showAnnotationArguments,
             *showUnannotatedArgs,
+            *includeSourceRetentionAnnotationArgs,
             *sdkFilesArgs,
             *importedPackageArgs.toTypedArray(),
             *skipEmitPackagesArgs.toTypedArray(),
@@ -1310,8 +1323,16 @@
         String[] allOf() default {};
         String[] anyOf() default {};
         boolean conditional() default false;
+        @Target({FIELD, METHOD, PARAMETER})
+        @interface Read {
+            RequiresPermission value() default @RequiresPermission;
+        }
+        @Target({FIELD, METHOD, PARAMETER})
+        @interface Write {
+            RequiresPermission value() default @RequiresPermission;
+        }
     }
-                    """
+    """
 ).indented()
 
 val requiresFeatureSource: TestFile = java(
@@ -1325,7 +1346,7 @@
     public @interface RequiresFeature {
         String value();
     }
-            """
+    """
 ).indented()
 
 val requiresApiSource: TestFile = java(
@@ -1340,7 +1361,7 @@
         int value() default 1;
         int api() default 1;
     }
-            """
+    """
 ).indented()
 
 val sdkConstantSource: TestFile = java(
@@ -1355,23 +1376,23 @@
         }
         SdkConstantType value();
     }
-        """
+    """
 ).indented()
 
 val broadcastBehaviorSource: TestFile = java(
     """
-        package android.annotation;
-        import java.lang.annotation.*;
-        /** @hide */
-        @Target({ ElementType.FIELD })
-        @Retention(RetentionPolicy.SOURCE)
-        public @interface BroadcastBehavior {
-            boolean explicitOnly() default false;
-            boolean registeredOnly() default false;
-            boolean includeBackground() default false;
-            boolean protectedBroadcast() default false;
-        }
-        """
+    package android.annotation;
+    import java.lang.annotation.*;
+    /** @hide */
+    @Target({ ElementType.FIELD })
+    @Retention(RetentionPolicy.SOURCE)
+    public @interface BroadcastBehavior {
+        boolean explicitOnly() default false;
+        boolean registeredOnly() default false;
+        boolean includeBackground() default false;
+        boolean protectedBroadcast() default false;
+    }
+    """
 ).indented()
 
 val nullableSource: TestFile = java(
@@ -1396,7 +1417,7 @@
 
 val supportNonNullSource: TestFile = java(
     """
-    package androidx.annotation;
+    package android.support.annotation;
     import java.lang.annotation.*;
     import static java.lang.annotation.ElementType.*;
     import static java.lang.annotation.RetentionPolicy.SOURCE;
@@ -1410,17 +1431,17 @@
 
 val supportNullableSource: TestFile = java(
     """
-package androidx.annotation;
-import java.lang.annotation.*;
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-@SuppressWarnings("WeakerAccess")
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD, TYPE_USE})
-public @interface Nullable {
-}
-                """
-)
+    package android.support.annotation;
+    import java.lang.annotation.*;
+    import static java.lang.annotation.ElementType.*;
+    import static java.lang.annotation.RetentionPolicy.SOURCE;
+    @SuppressWarnings("WeakerAccess")
+    @Retention(SOURCE)
+    @Target({METHOD, PARAMETER, FIELD, TYPE_USE})
+    public @interface Nullable {
+    }
+    """
+).indented()
 
 val androidxNonNullSource: TestFile = java(
     """
@@ -1438,17 +1459,45 @@
 
 val androidxNullableSource: TestFile = java(
     """
-package androidx.annotation;
-import java.lang.annotation.*;
-import static java.lang.annotation.ElementType.*;
-import static java.lang.annotation.RetentionPolicy.SOURCE;
-@SuppressWarnings("WeakerAccess")
-@Retention(SOURCE)
-@Target({METHOD, PARAMETER, FIELD, TYPE_USE})
-public @interface Nullable {
-}
-                """
-)
+    package androidx.annotation;
+    import java.lang.annotation.*;
+    import static java.lang.annotation.ElementType.*;
+    import static java.lang.annotation.RetentionPolicy.SOURCE;
+    @SuppressWarnings("WeakerAccess")
+    @Retention(SOURCE)
+    @Target({METHOD, PARAMETER, FIELD, TYPE_USE})
+    public @interface Nullable {
+    }
+    """
+).indented()
+
+val recentlyNonNullSource: TestFile = java(
+    """
+    package androidx.annotation;
+    import java.lang.annotation.*;
+    import static java.lang.annotation.ElementType.*;
+    import static java.lang.annotation.RetentionPolicy.SOURCE;
+    @SuppressWarnings("WeakerAccess")
+    @Retention(SOURCE)
+    @Target({METHOD, PARAMETER, FIELD, TYPE_USE})
+    public @interface RecentlyNonNull {
+    }
+    """
+).indented()
+
+val recentlyNullableSource: TestFile = java(
+    """
+    package androidx.annotation;
+    import java.lang.annotation.*;
+    import static java.lang.annotation.ElementType.*;
+    import static java.lang.annotation.RetentionPolicy.SOURCE;
+    @SuppressWarnings("WeakerAccess")
+    @Retention(SOURCE)
+    @Target({METHOD, PARAMETER, FIELD, TYPE_USE})
+    public @interface RecentlyNullable {
+    }
+    """
+).indented()
 
 val supportParameterName: TestFile = java(
     """
@@ -1527,17 +1576,17 @@
 
 val suppressLintSource: TestFile = java(
     """
-package android.annotation;
+    package android.annotation;
 
-import static java.lang.annotation.ElementType.*;
-import java.lang.annotation.*;
-@Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
-@Retention(RetentionPolicy.CLASS)
-public @interface SuppressLint {
-    String[] value();
-}
-                """
-)
+    import static java.lang.annotation.ElementType.*;
+    import java.lang.annotation.*;
+    @Target({TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE})
+    @Retention(RetentionPolicy.CLASS)
+    public @interface SuppressLint {
+        String[] value();
+    }
+    """
+).indented()
 
 val systemServiceSource: TestFile = java(
     """
diff --git a/src/test/java/com/android/tools/metalava/ExtractAnnotationsTest.kt b/src/test/java/com/android/tools/metalava/ExtractAnnotationsTest.kt
index 427e41d..5a8ee6f 100644
--- a/src/test/java/com/android/tools/metalava/ExtractAnnotationsTest.kt
+++ b/src/test/java/com/android/tools/metalava/ExtractAnnotationsTest.kt
@@ -25,9 +25,10 @@
     @Test
     fun `Check java typedef extraction and warning about non-source retention of typedefs`() {
         check(
+            includeSourceRetentionAnnotations = false,
             sourceFiles = *arrayOf(
                 java(
-            """
+                    """
                     package test.pkg;
 
                     import android.annotation.IntDef;
@@ -75,7 +76,8 @@
                 intRangeAnnotationSource
             ),
             warnings = "src/test/pkg/IntDefTest.java:11: error: This typedef annotation class should have @Retention(RetentionPolicy.SOURCE) [AnnotationExtraction:146]",
-            extractAnnotations = mapOf("test.pkg" to """
+            extractAnnotations = mapOf(
+                "test.pkg" to """
                 <?xml version="1.0" encoding="UTF-8"?>
                 <root>
                   <item name="test.pkg.IntDefTest void setFlags(java.lang.Object, int) 1">
@@ -104,6 +106,7 @@
     @Test
     fun `Check Kotlin and referencing hidden constants from typedef`() {
         check(
+            includeSourceRetentionAnnotations = false,
             sourceFiles = *arrayOf(
                 kotlin(
                     """
@@ -151,24 +154,187 @@
                 longDefAnnotationSource
             ),
             warnings = "src/test/pkg/LongDefTest.kt:12: error: Typedef class references hidden field field LongDefTestKt.HIDDEN: removed from typedef metadata [HiddenTypedefConstant:148]",
-            extractAnnotations = mapOf("test.pkg" to """
+            extractAnnotations = mapOf(
+                "test.pkg" to """
+                    <?xml version="1.0" encoding="UTF-8"?>
+                    <root>
+                      <item name="test.pkg.LongDefTest void setFlags(java.lang.Object, int) 0">
+                        <annotation name="androidx.annotation.NonNull"/>
+                      </item>
+                      <item name="test.pkg.LongDefTest void setFlags(java.lang.Object, int) 1">
+                        <annotation name="androidx.annotation.LongDef">
+                          <val name="flag" val="true" />
+                          <val name="value" val="{test.pkg.LongDefTestKt.STYLE_NORMAL, test.pkg.LongDefTestKt.STYLE_NO_TITLE, test.pkg.LongDefTestKt.STYLE_NO_FRAME, test.pkg.LongDefTestKt.STYLE_NO_INPUT, 3, 4}" />
+                        </annotation>
+                      </item>
+                      <item name="test.pkg.LongDefTest void setStyle(int, int) 0">
+                        <annotation name="androidx.annotation.LongDef">
+                          <val name="value" val="{test.pkg.LongDefTestKt.STYLE_NORMAL, test.pkg.LongDefTestKt.STYLE_NO_TITLE, test.pkg.LongDefTestKt.STYLE_NO_FRAME, test.pkg.LongDefTestKt.STYLE_NO_INPUT}" />
+                        </annotation>
+                      </item>
+                      <item name="test.pkg.LongDefTest.Inner boolean isNull(java.lang.String) 0">
+                        <annotation name="androidx.annotation.Nullable"/>
+                      </item>
+                      <item name="test.pkg.LongDefTest.Inner void setInner(int) 0">
+                        <annotation name="androidx.annotation.LongDef">
+                          <val name="flag" val="true" />
+                          <val name="value" val="{test.pkg.LongDefTestKt.STYLE_NORMAL, test.pkg.LongDefTestKt.STYLE_NO_TITLE, test.pkg.LongDefTestKt.STYLE_NO_FRAME, test.pkg.LongDefTestKt.STYLE_NO_INPUT, 3, 4}" />
+                        </annotation>
+                      </item>
+                      <item name="test.pkg.LongDefTestKt TYPE_1">
+                        <annotation name="androidx.annotation.NonNull"/>
+                      </item>
+                      <item name="test.pkg.LongDefTestKt TYPE_2">
+                        <annotation name="androidx.annotation.NonNull"/>
+                      </item>
+                      <item name="test.pkg.LongDefTestKt UNRELATED_TYPE">
+                        <annotation name="androidx.annotation.NonNull"/>
+                      </item>
+                    </root>
+                """
+            )
+        )
+    }
+
+    @Test
+    fun `Check including only class retention annotations other than typedefs`() {
+        check(
+            includeSourceRetentionAnnotations = true,
+            sourceFiles = *arrayOf(
+                kotlin(
+                    """
+                    @file:Suppress("unused", "UseExpressionBody")
+
+                    package test.pkg
+
+                    import android.annotation.LongDef
+
+                    const val STYLE_NORMAL = 0L
+                    const val STYLE_NO_TITLE = 1L
+                    const val STYLE_NO_FRAME = 2L
+                    const val STYLE_NO_INPUT = 3L
+                    const val UNRELATED = 3L
+                    private const val HIDDEN = 4
+
+                    const val TYPE_1 = "type1"
+                    const val TYPE_2 = "type2"
+                    const val UNRELATED_TYPE = "other"
+
+                    class LongDefTest {
+
+                        /** @hide */
+                        @LongDef(STYLE_NORMAL, STYLE_NO_TITLE, STYLE_NO_FRAME, STYLE_NO_INPUT, HIDDEN)
+                        @Retention(AnnotationRetention.SOURCE)
+                        private annotation class DialogStyle
+
+                        fun setStyle(@DialogStyle style: Int, theme: Int) {}
+
+                        fun testLongDef(arg: Int) {
+                        }
+
+                        @LongDef(STYLE_NORMAL, STYLE_NO_TITLE, STYLE_NO_FRAME, STYLE_NO_INPUT, 3L, 3L + 1L, flag = true)
+                        @Retention(AnnotationRetention.SOURCE)
+                        private annotation class DialogFlags
+
+                        fun setFlags(first: Any, @DialogFlags flags: Int) {}
+
+                        class Inner {
+                            fun setInner(@DialogFlags flags: Int) {}
+                            fun isNull(value: String?): Boolean
+                        }
+                    }"""
+                ).indented(),
+                longDefAnnotationSource
+            ),
+            warnings = "src/test/pkg/LongDefTest.kt:12: error: Typedef class references hidden field field LongDefTestKt.HIDDEN: removed from typedef metadata [HiddenTypedefConstant:148]",
+            extractAnnotations = mapOf(
+                "test.pkg" to """
+                    <?xml version="1.0" encoding="UTF-8"?>
+                    <root>
+                      <item name="test.pkg.LongDefTest void setFlags(java.lang.Object, int) 1">
+                        <annotation name="androidx.annotation.LongDef">
+                          <val name="flag" val="true" />
+                          <val name="value" val="{test.pkg.LongDefTestKt.STYLE_NORMAL, test.pkg.LongDefTestKt.STYLE_NO_TITLE, test.pkg.LongDefTestKt.STYLE_NO_FRAME, test.pkg.LongDefTestKt.STYLE_NO_INPUT, 3, 4}" />
+                        </annotation>
+                      </item>
+                      <item name="test.pkg.LongDefTest void setStyle(int, int) 0">
+                        <annotation name="androidx.annotation.LongDef">
+                          <val name="value" val="{test.pkg.LongDefTestKt.STYLE_NORMAL, test.pkg.LongDefTestKt.STYLE_NO_TITLE, test.pkg.LongDefTestKt.STYLE_NO_FRAME, test.pkg.LongDefTestKt.STYLE_NO_INPUT}" />
+                        </annotation>
+                      </item>
+                      <item name="test.pkg.LongDefTest.Inner void setInner(int) 0">
+                        <annotation name="androidx.annotation.LongDef">
+                          <val name="flag" val="true" />
+                          <val name="value" val="{test.pkg.LongDefTestKt.STYLE_NORMAL, test.pkg.LongDefTestKt.STYLE_NO_TITLE, test.pkg.LongDefTestKt.STYLE_NO_FRAME, test.pkg.LongDefTestKt.STYLE_NO_INPUT, 3, 4}" />
+                        </annotation>
+                      </item>
+                    </root>
+                """
+            )
+        )
+    }
+
+    @Test
+    fun `Extract permission annotations`() {
+        check(
+            includeSourceRetentionAnnotations = false,
+            sourceFiles = *arrayOf(
+                java(
+                    """
+                    package test.pkg;
+
+                    import android.annotation.RequiresPermission;
+
+                    public class PermissionsTest {
+                        @RequiresPermission(Manifest.permission.MY_PERMISSION)
+                        public void myMethod() {
+                        }
+                        @RequiresPermission(anyOf={Manifest.permission.MY_PERMISSION,Manifest.permission.MY_PERMISSION2})
+                        public void myMethod2() {
+                        }
+
+                        @RequiresPermission.Read(@RequiresPermission(Manifest.permission.MY_READ_PERMISSION))
+                        @RequiresPermission.Write(@RequiresPermission(Manifest.permission.MY_WRITE_PERMISSION))
+                        public static final String CONTENT_URI = "";
+                    }
+                    """
+                ).indented(),
+                java(
+                    """
+                    package test.pkg;
+
+                    public class Manifest {
+                        public static final class permission {
+                            public static final String MY_PERMISSION = "android.permission.MY_PERMISSION_STRING";
+                            public static final String MY_PERMISSION2 = "android.permission.MY_PERMISSION_STRING2";
+                            public static final String MY_READ_PERMISSION = "android.permission.MY_READ_PERMISSION_STRING";
+                            public static final String MY_WRITE_PERMISSION = "android.permission.MY_WRITE_PERMISSION_STRING";
+                        }
+                    }
+                    """
+                ).indented(),
+                requiresPermissionSource
+            ),
+            extractAnnotations = mapOf(
+                "test.pkg" to """
                 <?xml version="1.0" encoding="UTF-8"?>
                 <root>
-                  <item name="test.pkg.LongDefTest void setFlags(java.lang.Object, int) 1">
-                    <annotation name="androidx.annotation.LongDef">
-                      <val name="flag" val="true" />
-                      <val name="value" val="{test.pkg.LongDefTestKt.STYLE_NORMAL, test.pkg.LongDefTestKt.STYLE_NO_TITLE, test.pkg.LongDefTestKt.STYLE_NO_FRAME, test.pkg.LongDefTestKt.STYLE_NO_INPUT, 3, 4}" />
+                  <item name="test.pkg.PermissionsTest CONTENT_URI">
+                    <annotation name="androidx.annotation.RequiresPermission.Read">
+                      <val name="value" val="&quot;android.permission.MY_READ_PERMISSION_STRING&quot;" />
+                    </annotation>
+                    <annotation name="androidx.annotation.RequiresPermission.Write">
+                      <val name="value" val="&quot;android.permission.MY_WRITE_PERMISSION_STRING&quot;" />
                     </annotation>
                   </item>
-                  <item name="test.pkg.LongDefTest void setStyle(int, int) 0">
-                    <annotation name="androidx.annotation.LongDef">
-                      <val name="value" val="{test.pkg.LongDefTestKt.STYLE_NORMAL, test.pkg.LongDefTestKt.STYLE_NO_TITLE, test.pkg.LongDefTestKt.STYLE_NO_FRAME, test.pkg.LongDefTestKt.STYLE_NO_INPUT}" />
+                  <item name="test.pkg.PermissionsTest void myMethod()">
+                    <annotation name="androidx.annotation.RequiresPermission">
+                      <val name="value" val="&quot;android.permission.MY_PERMISSION_STRING&quot;" />
                     </annotation>
                   </item>
-                  <item name="test.pkg.LongDefTest.Inner void setInner(int) 0">
-                    <annotation name="androidx.annotation.LongDef">
-                      <val name="flag" val="true" />
-                      <val name="value" val="{test.pkg.LongDefTestKt.STYLE_NORMAL, test.pkg.LongDefTestKt.STYLE_NO_TITLE, test.pkg.LongDefTestKt.STYLE_NO_FRAME, test.pkg.LongDefTestKt.STYLE_NO_INPUT, 3, 4}" />
+                  <item name="test.pkg.PermissionsTest void myMethod2()">
+                    <annotation name="androidx.annotation.RequiresPermission">
+                      <val name="anyOf" val="{&quot;android.permission.MY_PERMISSION_STRING&quot;, &quot;android.permission.MY_PERMISSION_STRING2&quot;}" />
                     </annotation>
                   </item>
                 </root>
@@ -181,6 +347,7 @@
     @Test
     fun `Include merged annotations in exported source annotations`() {
         check(
+            includeSourceRetentionAnnotations = true,
             compatibilityMode = false,
             outputKotlinStyleNulls = false,
             includeSystemApiAnnotations = false,
@@ -205,7 +372,8 @@
                   </item>
                 </root>
                 """,
-            extractAnnotations = mapOf("test.pkg" to """
+            extractAnnotations = mapOf(
+                "test.pkg" to """
                 <?xml version="1.0" encoding="UTF-8"?>
                 <root>
                   <item name="test.pkg.MyTest void test(int) 0">
@@ -218,4 +386,43 @@
             )
         )
     }
+
+    @Test
+    fun `Only including class retention annotations in stubs`() {
+        check(
+            includeSourceRetentionAnnotations = false,
+            compatibilityMode = false,
+            outputKotlinStyleNulls = false,
+            includeSystemApiAnnotations = false,
+            omitCommonPackages = false,
+            sourceFiles =
+            *arrayOf(
+                java(
+                    """
+                    package test.pkg;
+                    import android.annotation.IntRange;
+                    import androidx.annotation.RecentlyNullable;
+                    public class Test {
+                        @RecentlyNullable
+                        public static String sayHello(@IntRange(from = 10) int value) { return "hello " + value; }
+                    }
+                    """
+                ),
+                intRangeAnnotationSource,
+                recentlyNullableSource
+            ),
+            extractAnnotations = mapOf(
+                "test.pkg" to """
+                    <?xml version="1.0" encoding="UTF-8"?>
+                    <root>
+                      <item name="test.pkg.Test java.lang.String sayHello(int) 0">
+                        <annotation name="androidx.annotation.IntRange">
+                          <val name="from" val="10" />
+                        </annotation>
+                      </item>
+                    </root>
+                """
+            )
+        )
+    }
 }
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/metalava/NullnessMigrationTest.kt b/src/test/java/com/android/tools/metalava/NullnessMigrationTest.kt
index 0557168..ed328ae 100644
--- a/src/test/java/com/android/tools/metalava/NullnessMigrationTest.kt
+++ b/src/test/java/com/android/tools/metalava/NullnessMigrationTest.kt
@@ -16,6 +16,7 @@
 
 package com.android.tools.metalava
 
+import com.android.tools.metalava.model.SUPPORT_TYPE_USE_ANNOTATIONS
 import org.junit.Test
 
 class NullnessMigrationTest : DriverTest() {
@@ -273,11 +274,12 @@
                     }
                     """
                 ),
-                supportNonNullSource,
-                supportNullableSource
+                androidxNonNullSource,
+                androidxNullableSource
             ),
             extraArguments = arrayOf("--hide-package", "androidx.annotation"),
-            api = """
+            api = if (SUPPORT_TYPE_USE_ANNOTATIONS) {
+                """
                 package test.pkg {
                   public class Test {
                     ctor public Test();
@@ -286,6 +288,17 @@
                   }
                 }
                 """
+            } else {
+                """
+                package test.pkg {
+                  public class Test {
+                    ctor public Test();
+                    method @Nullable public Integer compute1(@Nullable java.util.List<java.lang.String>);
+                    method @Nullable public Integer compute2(@Nullable java.util.List<java.util.List<?>>);
+                  }
+                }
+                """
+            }
         )
     }
 
@@ -315,7 +328,8 @@
                 androidxNullableSource
             ),
             extraArguments = arrayOf("--hide-package", "androidx.annotation"),
-            api = """
+            api = if (SUPPORT_TYPE_USE_ANNOTATIONS) {
+                """
                 package test.pkg {
                   public class Test {
                     ctor public Test();
@@ -324,6 +338,17 @@
                   }
                 }
                 """
+            } else {
+                """
+                package test.pkg {
+                  public class Test {
+                    ctor public Test();
+                    method @Nullable public Integer compute1(@Nullable java.util.List<java.lang.String>);
+                    method @Nullable public Integer compute2(@NonNull java.util.List<java.util.List<?>>);
+                  }
+                }
+                """
+            }
         )
     }
 
@@ -362,18 +387,33 @@
                   }
                 }
                 """,
-            stubs = arrayOf(
-                """
-                package test.pkg;
-                @SuppressWarnings({"unchecked", "deprecation", "all"})
-                public class Foo {
-                public Foo() { throw new RuntimeException("Stub!"); }
-                public static char @androidx.annotation.RecentlyNonNull [] toChars(int codePoint) { throw new RuntimeException("Stub!"); }
-                public static int codePointAt(char @androidx.annotation.RecentlyNonNull [] a, int index) { throw new RuntimeException("Stub!"); }
-                public <T> T @androidx.annotation.RecentlyNonNull [] toArray(T @androidx.annotation.RecentlyNonNull [] a) { throw new RuntimeException("Stub!"); }
-                }
-                """
-            )
+            stubs = if (SUPPORT_TYPE_USE_ANNOTATIONS) {
+                arrayOf(
+                    """
+                    package test.pkg;
+                    @SuppressWarnings({"unchecked", "deprecation", "all"})
+                    public class Foo {
+                    public Foo() { throw new RuntimeException("Stub!"); }
+                    public static char @androidx.annotation.RecentlyNonNull [] toChars(int codePoint) { throw new RuntimeException("Stub!"); }
+                    public static int codePointAt(char @androidx.annotation.RecentlyNonNull [] a, int index) { throw new RuntimeException("Stub!"); }
+                    public <T> T @androidx.annotation.RecentlyNonNull [] toArray(T @androidx.annotation.RecentlyNonNull [] a) { throw new RuntimeException("Stub!"); }
+                    }
+                    """
+                )
+            } else {
+                arrayOf(
+                    """
+                    package test.pkg;
+                    @SuppressWarnings({"unchecked", "deprecation", "all"})
+                    public class Foo {
+                    public Foo() { throw new RuntimeException("Stub!"); }
+                    public static char[] toChars(int codePoint) { throw new RuntimeException("Stub!"); }
+                    public static int codePointAt(char[] a, int index) { throw new RuntimeException("Stub!"); }
+                    public <T> T[] toArray(T[] a) { throw new RuntimeException("Stub!"); }
+                    }
+                    """
+                )
+            }
         )
     }
 
@@ -412,18 +452,33 @@
                   }
                 }
                 """,
-            stubs = arrayOf(
-                """
-                package test.pkg;
-                @SuppressWarnings({"unchecked", "deprecation", "all"})
-                public class Foo {
-                public Foo() { throw new RuntimeException("Stub!"); }
-                public static char @androidx.annotation.RecentlyNonNull [] toChars(int codePoint) { throw new RuntimeException("Stub!"); }
-                public static int codePointAt(char @androidx.annotation.RecentlyNonNull [] a, int index) { throw new RuntimeException("Stub!"); }
-                public <T> T @androidx.annotation.RecentlyNonNull [] toArray(T @androidx.annotation.RecentlyNonNull [] a) { throw new RuntimeException("Stub!"); }
-                }
-                """
-            )
+            stubs = if (SUPPORT_TYPE_USE_ANNOTATIONS) {
+                arrayOf(
+                    """
+                    package test.pkg;
+                    @SuppressWarnings({"unchecked", "deprecation", "all"})
+                    public class Foo {
+                    public Foo() { throw new RuntimeException("Stub!"); }
+                    public static char @androidx.annotation.RecentlyNonNull [] toChars(int codePoint) { throw new RuntimeException("Stub!"); }
+                    public static int codePointAt(char @androidx.annotation.RecentlyNonNull [] a, int index) { throw new RuntimeException("Stub!"); }
+                    public <T> T @androidx.annotation.RecentlyNonNull [] toArray(T @androidx.annotation.RecentlyNonNull [] a) { throw new RuntimeException("Stub!"); }
+                    }
+                    """
+                )
+            } else {
+                arrayOf(
+                    """
+                    package test.pkg;
+                    @SuppressWarnings({"unchecked", "deprecation", "all"})
+                    public class Foo {
+                    public Foo() { throw new RuntimeException("Stub!"); }
+                    public static char[] toChars(int codePoint) { throw new RuntimeException("Stub!"); }
+                    public static int codePointAt(char[] a, int index) { throw new RuntimeException("Stub!"); }
+                    public <T> T[] toArray(T[] a) { throw new RuntimeException("Stub!"); }
+                    }
+                    """
+                )
+            }
         )
     }
 }
\ No newline at end of file
diff --git a/src/test/java/com/android/tools/metalava/OptionsTest.kt b/src/test/java/com/android/tools/metalava/OptionsTest.kt
index 9da7caa..5497e8a 100644
--- a/src/test/java/com/android/tools/metalava/OptionsTest.kt
+++ b/src/test/java/com/android/tools/metalava/OptionsTest.kt
@@ -181,6 +181,10 @@
                                        metalava/stub-annotations/src/main/java/.
 --rewrite-annotations <dir/jar>        For a bytecode folder or output jar, rewrites the
                                        androidx annotations to be package private
+--include-source-retention             If true, include source-retention annotations in
+                                       the stub files. Does not apply to signature files.
+                                       Source retention annotations are extracted into the
+                                       external annotations files instead.
 
 Injecting API Levels:
 --apply-api-levels <api-versions.xml>  Reads an XML file containing API level descriptions
diff --git a/src/test/java/com/android/tools/metalava/StubsTest.kt b/src/test/java/com/android/tools/metalava/StubsTest.kt
index 5d7f7df..f42d4bb 100644
--- a/src/test/java/com/android/tools/metalava/StubsTest.kt
+++ b/src/test/java/com/android/tools/metalava/StubsTest.kt
@@ -19,6 +19,7 @@
 package com.android.tools.metalava
 
 import com.android.tools.lint.checks.infrastructure.TestFile
+import com.android.tools.metalava.model.SUPPORT_TYPE_USE_ANNOTATIONS
 import org.intellij.lang.annotations.Language
 import org.junit.Test
 
@@ -1345,16 +1346,28 @@
                     """
                 )
             ),
-            api = """
+            api = if (SUPPORT_TYPE_USE_ANNOTATIONS) {
+                """
                 package test.pkg {
                   public class Foo {
                     ctor public Foo();
                     method public void foo(int, java.util.Map<java.lang.String, java.lang.String>!);
                   }
                 }
-                """,
+                """
+            } else {
+                """
+                package test.pkg {
+                  public class Foo {
+                    ctor public Foo();
+                    method public void foo(int, java.util.Map<java.lang.String,java.lang.String>!);
+                  }
+                }
+                """
+            },
 
-            source = """
+            source = if (SUPPORT_TYPE_USE_ANNOTATIONS) {
+                """
                 package test.pkg;
                 @SuppressWarnings({"unchecked", "deprecation", "all"})
                 public class Foo {
@@ -1362,6 +1375,16 @@
                 public void foo(int p1, java.util.Map<java.lang.String, java.lang.String> p2) { throw new RuntimeException("Stub!"); }
                 }
                 """
+            } else {
+                """
+                package test.pkg;
+                @SuppressWarnings({"unchecked", "deprecation", "all"})
+                public class Foo {
+                public Foo() { throw new RuntimeException("Stub!"); }
+                public void foo(int p1, java.util.Map<java.lang.String,java.lang.String> p2) { throw new RuntimeException("Stub!"); }
+                }
+                """
+            }
         )
     }
 
@@ -1764,40 +1787,52 @@
                       }
                     }
                     """,
-            stubs = arrayOf(
-                """
-                package my.pkg;
-                @SuppressWarnings({"unchecked", "deprecation", "all"})
-                public class String {
-                public String(char @androidx.annotation.NonNull [] value) { throw new RuntimeException("Stub!"); }
-                }
-                """
-            )
+            stubs = if (SUPPORT_TYPE_USE_ANNOTATIONS) {
+                arrayOf(
+                    """
+                    package my.pkg;
+                    @SuppressWarnings({"unchecked", "deprecation", "all"})
+                    public class String {
+                    public String(char @androidx.annotation.NonNull [] value) { throw new RuntimeException("Stub!"); }
+                    }
+                    """
+                )
+            } else {
+                arrayOf(
+                    """
+                    package my.pkg;
+                    @SuppressWarnings({"unchecked", "deprecation", "all"})
+                    public class String {
+                    public String(char[] value) { throw new RuntimeException("Stub!"); }
+                    }
+                    """
+                )
+            }
         )
     }
 
-    @Test
-    fun `Test inaccessible constructors`() {
-        // If the constructors of a class are not visible, and the class has subclasses,
-        // those subclass stubs will need to reference these inaccessible constructors.
-        // This generally only happens when the constructors are package private (and
-        // therefore hidden) but the subclass using it is also in the same package.
+@Test
+fun `Test inaccessible constructors`() {
+    // If the constructors of a class are not visible, and the class has subclasses,
+    // those subclass stubs will need to reference these inaccessible constructors.
+    // This generally only happens when the constructors are package private (and
+    // therefore hidden) but the subclass using it is also in the same package.
 
-        check(
-            checkDoclava1 = false,
-            checkCompilation = true,
-            sourceFiles =
-            *arrayOf(
-                java(
-                    """
+    check(
+        checkDoclava1 = false,
+        checkCompilation = true,
+        sourceFiles =
+        *arrayOf(
+            java(
+                """
                     package test.pkg;
                     public class MyClass1 {
                         MyClass1(int myVar) { }
                     }
                     """
-                ),
-                java(
-                    """
+            ),
+            java(
+                """
                     package test.pkg;
                     import java.io.IOException;
                     @SuppressWarnings("RedundantThrows")
@@ -1805,27 +1840,27 @@
                         MySubClass1(int myVar) throws IOException { super(myVar); }
                     }
                     """
-                ),
-                java(
-                    """
+            ),
+            java(
+                """
                     package test.pkg;
                     public class MyClass2 {
                         /** @hide */
                         public MyClass2(int myVar) { }
                     }
                     """
-                ),
-                java(
-                    """
+            ),
+            java(
+                """
                     package test.pkg;
                     public class MySubClass2 extends MyClass2 {
                         public MySubClass2() { super(5); }
                     }
                     """
-                )
-            ),
-            warnings = "",
-            api = """
+            )
+        ),
+        warnings = "",
+        api = """
                     package test.pkg {
                       public class MyClass1 {
                       }
@@ -1838,22 +1873,22 @@
                       }
                     }
                     """,
-            stubs = arrayOf(
-                """
+        stubs = arrayOf(
+            """
                 package test.pkg;
                 @SuppressWarnings({"unchecked", "deprecation", "all"})
                 public class MyClass1 {
                 MyClass1(int myVar) { throw new RuntimeException("Stub!"); }
                 }
                 """,
-                """
+            """
                 package test.pkg;
                 @SuppressWarnings({"unchecked", "deprecation", "all"})
                 public class MySubClass1 extends test.pkg.MyClass1 {
                 MySubClass1(int myVar) throws java.io.IOException { super(0); throw new RuntimeException("Stub!"); }
                 }
                 """,
-                """
+            """
                 package test.pkg;
                 @SuppressWarnings({"unchecked", "deprecation", "all"})
                 public class MyClass2 {
@@ -1861,32 +1896,32 @@
                 MyClass2(int myVar) { throw new RuntimeException("Stub!"); }
                 }
                 """,
-                """
+            """
                 package test.pkg;
                 @SuppressWarnings({"unchecked", "deprecation", "all"})
                 public class MySubClass2 extends test.pkg.MyClass2 {
                 public MySubClass2() { super(0); throw new RuntimeException("Stub!"); }
                 }
                 """
-            )
         )
-    }
+    )
+}
 
-    @Test
-    fun `Generics Variable Rewriting`() {
-        // When we move methods from hidden superclasses into the subclass since they
-        // provide the implementation for a required method, it's possible that the
-        // method we copied in is referencing generics with a different variable than
-        // in the current class, so we need to handle this
+@Test
+fun `Generics Variable Rewriting`() {
+    // When we move methods from hidden superclasses into the subclass since they
+    // provide the implementation for a required method, it's possible that the
+    // method we copied in is referencing generics with a different variable than
+    // in the current class, so we need to handle this
 
-        checkStubs(
-            checkDoclava1 = false,
-            sourceFiles =
-            *arrayOf(
-                // TODO: Try using prefixes like "A", and "AA" to make sure my generics
-                // variable renaming doesn't do something really dumb
-                java(
-                    """
+    checkStubs(
+        checkDoclava1 = false,
+        sourceFiles =
+        *arrayOf(
+            // TODO: Try using prefixes like "A", and "AA" to make sure my generics
+            // variable renaming doesn't do something really dumb
+            java(
+                """
                     package test.pkg;
 
                     import java.util.List;
@@ -1916,10 +1951,10 @@
                         }
                     }
                     """
-                )
-            ),
-            warnings = "",
-            source = """
+            )
+        ),
+        warnings = "",
+        source = """
                     package test.pkg;
                     @SuppressWarnings({"unchecked", "deprecation", "all"})
                     public class Generics {
@@ -1945,18 +1980,18 @@
                     }
                     }
                     """
-        )
-    }
+    )
+}
 
-    @Test
-    fun `Rewriting type parameters in interfaces from hidden super classes and in throws lists`() {
-        checkStubs(
-            extraArguments = arrayOf("--skip-inherited-methods=false"),
-            checkDoclava1 = false,
-            sourceFiles =
-            *arrayOf(
-                java(
-                    """
+@Test
+fun `Rewriting type parameters in interfaces from hidden super classes and in throws lists`() {
+    checkStubs(
+        extraArguments = arrayOf("--skip-inherited-methods=false"),
+        checkDoclava1 = false,
+        sourceFiles =
+        *arrayOf(
+            java(
+                """
                     package test.pkg;
 
                     import java.io.IOException;
@@ -1991,10 +2026,10 @@
                         }
                     }
                     """
-                )
-            ),
-            warnings = "",
-            api = """
+            )
+        ),
+        warnings = "",
+        api = """
                     package test.pkg {
                       public class Generics {
                         ctor public Generics();
@@ -2013,41 +2048,66 @@
                       }
                     }
                     """,
-            source = """
-                    package test.pkg;
-                    @SuppressWarnings({"unchecked", "deprecation", "all"})
-                    public class Generics {
-                    public Generics() { throw new RuntimeException("Stub!"); }
-                    @SuppressWarnings({"unchecked", "deprecation", "all"})
-                    public class MyClass<X, Y extends java.lang.Number> extends test.pkg.Generics.PublicParent<X,Y> implements test.pkg.Generics.PublicInterface<X,Y> {
-                    public MyClass() { throw new RuntimeException("Stub!"); }
-                    public java.util.List<X> foo() { throw new RuntimeException("Stub!"); }
-                    public java.util.Map<X,java.util.Map<Y,java.lang.String>> createMap(java.util.List<X> list) throws java.io.IOException { throw new RuntimeException("Stub!"); }
-                    }
-                    @SuppressWarnings({"unchecked", "deprecation", "all"})
-                    public static interface PublicInterface<A, B> {
-                    public java.util.Map<A,java.util.Map<B,java.lang.String>> createMap(java.util.List<A> list) throws java.io.IOException;
-                    }
-                    @SuppressWarnings({"unchecked", "deprecation", "all"})
-                    public abstract class PublicParent<A, B extends java.lang.Number> {
-                    public PublicParent() { throw new RuntimeException("Stub!"); }
-                    protected abstract java.util.List<A> foo();
-                    }
-                    }
-                    """
-        )
-    }
+        source = if (SUPPORT_TYPE_USE_ANNOTATIONS) {
+            """
+            package test.pkg;
+            @SuppressWarnings({"unchecked", "deprecation", "all"})
+            public class Generics {
+            public Generics() { throw new RuntimeException("Stub!"); }
+            @SuppressWarnings({"unchecked", "deprecation", "all"})
+            public class MyClass<X, Y extends java.lang.Number> extends test.pkg.Generics.PublicParent<X,Y> implements test.pkg.Generics.PublicInterface<X,Y> {
+            public MyClass() { throw new RuntimeException("Stub!"); }
+            public java.util.List<X> foo() { throw new RuntimeException("Stub!"); }
+            public java.util.Map<X,java.util.Map<Y,java.lang.String>> createMap(java.util.List<X> list) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+            }
+            @SuppressWarnings({"unchecked", "deprecation", "all"})
+            public static interface PublicInterface<A, B> {
+            public java.util.Map<A,java.util.Map<B,java.lang.String>> createMap(java.util.List<A> list) throws java.io.IOException;
+            }
+            @SuppressWarnings({"unchecked", "deprecation", "all"})
+            public abstract class PublicParent<A, B extends java.lang.Number> {
+            public PublicParent() { throw new RuntimeException("Stub!"); }
+            protected abstract java.util.List<A> foo();
+            }
+            }
+            """
+        } else {
+            """
+            package test.pkg;
+            @SuppressWarnings({"unchecked", "deprecation", "all"})
+            public class Generics {
+            public Generics() { throw new RuntimeException("Stub!"); }
+            @SuppressWarnings({"unchecked", "deprecation", "all"})
+            public class MyClass<X, Y extends java.lang.Number> extends test.pkg.Generics.PublicParent<X,Y> implements test.pkg.Generics.PublicInterface<X,Y> {
+            public MyClass() { throw new RuntimeException("Stub!"); }
+            public java.util.List<X> foo() { throw new RuntimeException("Stub!"); }
+            public java.util.Map<X, java.util.Map<Y, java.lang.String>> createMap(java.util.List<X> list) throws java.io.IOException { throw new RuntimeException("Stub!"); }
+            }
+            @SuppressWarnings({"unchecked", "deprecation", "all"})
+            public static interface PublicInterface<A, B> {
+            public java.util.Map<A, java.util.Map<B, java.lang.String>> createMap(java.util.List<A> list) throws java.io.IOException;
+            }
+            @SuppressWarnings({"unchecked", "deprecation", "all"})
+            public abstract class PublicParent<A, B extends java.lang.Number> {
+            public PublicParent() { throw new RuntimeException("Stub!"); }
+            protected abstract java.util.List<A> foo();
+            }
+            }
+            """
+        }
+    )
+}
 
-    @Test
-    fun `Picking super class throwables`() {
-        // Like previous test, but without compatibility mode: ensures that we
-        // use super classes of filtered throwables
-        checkStubs(
-            compatibilityMode = false,
-            sourceFiles =
-            *arrayOf(
-                java(
-                    """
+@Test
+fun `Picking super class throwables`() {
+    // Like previous test, but without compatibility mode: ensures that we
+    // use super classes of filtered throwables
+    checkStubs(
+        compatibilityMode = false,
+        sourceFiles =
+        *arrayOf(
+            java(
+                """
                     package test.pkg;
 
                     import java.io.IOException;
@@ -2082,10 +2142,10 @@
                         }
                     }
                     """
-                )
-            ),
-            warnings = "",
-            api = """
+            )
+        ),
+        warnings = "",
+        api = """
                 package test.pkg {
                   public class Generics {
                     ctor public Generics();
@@ -2104,7 +2164,7 @@
                   }
                 }
                     """,
-            source = """
+        source = """
                     package test.pkg;
                     @SuppressWarnings({"unchecked", "deprecation", "all"})
                     public class Generics {
@@ -2126,19 +2186,19 @@
                     }
                     }
                     """
-        )
-    }
+    )
+}
 
-    @Test
-    fun `Rewriting implements class references`() {
-        // Checks some more subtle bugs around generics type variable renaming
-        checkStubs(
-            extraArguments = arrayOf("--skip-inherited-methods=false"),
-            checkDoclava1 = false,
-            sourceFiles =
-            *arrayOf(
-                java(
-                    """
+@Test
+fun `Rewriting implements class references`() {
+    // Checks some more subtle bugs around generics type variable renaming
+    checkStubs(
+        extraArguments = arrayOf("--skip-inherited-methods=false"),
+        checkDoclava1 = false,
+        sourceFiles =
+        *arrayOf(
+            java(
+                """
                     package test.pkg;
 
                     import java.util.Collection;
@@ -2165,10 +2225,10 @@
                         }
                     }
                     """
-                )
-            ),
-            warnings = "",
-            api = """
+            )
+        ),
+        warnings = "",
+        api = """
                     package test.pkg {
                       public class ConcurrentHashMap<K, V> {
                         ctor public ConcurrentHashMap();
@@ -2181,7 +2241,7 @@
                       }
                     }
                     """,
-            source = """
+        source = """
                     package test.pkg;
                     @SuppressWarnings({"unchecked", "deprecation", "all"})
                     public class ConcurrentHashMap<K, V> {
@@ -2195,17 +2255,17 @@
                     }
                     }
                     """
-        )
-    }
+    )
+}
 
-    @Test
-    fun `Arrays in type arguments`() {
-        checkStubs(
-            checkDoclava1 = false,
-            sourceFiles =
-            *arrayOf(
-                java(
-                    """
+@Test
+fun `Arrays in type arguments`() {
+    checkStubs(
+        checkDoclava1 = false,
+        sourceFiles =
+        *arrayOf(
+            java(
+                """
                     package test.pkg;
 
                     public class Generics2 {
@@ -2217,10 +2277,10 @@
                         }
                     }
                     """
-                )
-            ),
-            warnings = "",
-            source = """
+            )
+        ),
+        warnings = "",
+        source = """
                     package test.pkg;
                     @SuppressWarnings({"unchecked", "deprecation", "all"})
                     public class Generics2 {
@@ -2234,20 +2294,20 @@
                     }
                     }
                     """
-        )
-    }
+    )
+}
 
-    @Test
-    fun `Interface extending multiple interfaces`() {
-        // Ensure that we handle sorting correctly where we're mixing super classes and implementing
-        // interfaces
-        // Real-world example: XmlResourceParser
-        check(
-            checkDoclava1 = false,
-            checkCompilation = true,
-            sourceFiles = *arrayOf(
-                java(
-                    """
+@Test
+fun `Interface extending multiple interfaces`() {
+    // Ensure that we handle sorting correctly where we're mixing super classes and implementing
+    // interfaces
+    // Real-world example: XmlResourceParser
+    check(
+        checkDoclava1 = false,
+        checkCompilation = true,
+        sourceFiles = *arrayOf(
+            java(
+                """
                     package android.content.res;
                     import android.util.AttributeSet;
                     import org.xmlpull.v1.XmlPullParser;
@@ -2257,52 +2317,52 @@
                         public void close();
                     }
                     """
-                ),
-                java(
-                    """
+            ),
+            java(
+                """
                     package android.util;
                     public interface AttributeSet {
                     }
                     """
-                ),
-                java(
-                    """
+            ),
+            java(
+                """
                     package java.lang;
                     public interface AutoCloseable {
                     }
                     """
-                ),
-                java(
-                    """
+            ),
+            java(
+                """
                     package org.xmlpull.v1;
                     public interface XmlPullParser {
                     }
                     """
-                )
-            ),
-            stubs = arrayOf(
-                """
+            )
+        ),
+        stubs = arrayOf(
+            """
                 package android.content.res;
                 @SuppressWarnings({"unchecked", "deprecation", "all"})
                 public interface XmlResourceParser extends org.xmlpull.v1.XmlPullParser,  android.util.AttributeSet, java.lang.AutoCloseable {
                 public void close();
                 }
                 """
-            )
         )
-    }
+    )
+}
 
-    // TODO: Add a protected constructor too to make sure my code to make non-public constructors package private
-    // don't accidentally demote protected constructors to package private!
+// TODO: Add a protected constructor too to make sure my code to make non-public constructors package private
+// don't accidentally demote protected constructors to package private!
 
-    @Test
-    fun `Picking Super Constructors`() {
-        checkStubs(
-            checkDoclava1 = false,
-            sourceFiles =
-            *arrayOf(
-                java(
-                    """
+@Test
+fun `Picking Super Constructors`() {
+    checkStubs(
+        checkDoclava1 = false,
+        sourceFiles =
+        *arrayOf(
+            java(
+                """
                     package test.pkg;
 
                     import java.io.IOException;
@@ -2374,10 +2434,10 @@
                         }
                     }
                     """
-                )
-            ),
-            warnings = "",
-            api = """
+            )
+        ),
+        warnings = "",
+        api = """
                     package test.pkg {
                       public class PickConstructors {
                         ctor public PickConstructors();
@@ -2418,7 +2478,7 @@
                       }
                     }
                 """,
-            source = """
+        source = """
                     package test.pkg;
                     @SuppressWarnings({"unchecked", "deprecation", "all"})
                     public class PickConstructors {
@@ -2470,17 +2530,17 @@
                     }
                     }
                     """
-        )
-    }
+    )
+}
 
-    @Test
-    fun `Picking Constructors`() {
-        checkStubs(
-            checkDoclava1 = false,
-            sourceFiles =
-            *arrayOf(
-                java(
-                    """
+@Test
+fun `Picking Constructors`() {
+    checkStubs(
+        checkDoclava1 = false,
+        sourceFiles =
+        *arrayOf(
+            java(
+                """
                     package test.pkg;
 
                     @SuppressWarnings({"WeakerAccess", "unused"})
@@ -2557,10 +2617,10 @@
                         }
                     }
                     """
-                )
-            ),
-            warnings = "",
-            source = """
+            )
+        ),
+        warnings = "",
+        source = """
                     package test.pkg;
                     @SuppressWarnings({"unchecked", "deprecation", "all"})
                     public class Constructors2 {
@@ -2604,18 +2664,18 @@
                     }
                     }
                     """
-        )
-    }
+    )
+}
 
-    @Test
-    fun `Another Constructor Test`() {
-        // A specific scenario triggered in the API where the right super class detector was not chosen
-        checkStubs(
-            checkDoclava1 = false,
-            sourceFiles =
-            *arrayOf(
-                java(
-                    """
+@Test
+fun `Another Constructor Test`() {
+    // A specific scenario triggered in the API where the right super class detector was not chosen
+    checkStubs(
+        checkDoclava1 = false,
+        sourceFiles =
+        *arrayOf(
+            java(
+                """
                     package test.pkg;
 
                     @SuppressWarnings({"RedundantThrows", "JavaDoc", "WeakerAccess"})
@@ -2641,10 +2701,10 @@
                         }
                     }
                     """
-                )
-            ),
-            warnings = "",
-            source = """
+            )
+        ),
+        warnings = "",
+        source = """
                     package test.pkg;
                     @SuppressWarnings({"unchecked", "deprecation", "all"})
                     public class PickConstructors2 {
@@ -2665,18 +2725,18 @@
                     }
                     }
                     """
-        )
-    }
+    )
+}
 
-    @Test
-    fun `Overriding protected methods`() {
-        // Checks a scenario where the stubs were missing overrides
-        checkStubs(
-            checkDoclava1 = false,
-            sourceFiles =
-            *arrayOf(
-                java(
-                    """
+@Test
+fun `Overriding protected methods`() {
+    // Checks a scenario where the stubs were missing overrides
+    checkStubs(
+        checkDoclava1 = false,
+        sourceFiles =
+        *arrayOf(
+            java(
+                """
                     package test.pkg;
 
                     @SuppressWarnings("all")
@@ -2699,10 +2759,10 @@
                         }
                     }
                     """
-                )
-            ),
-            warnings = "",
-            api = """
+            )
+        ),
+        warnings = "",
+        api = """
                     package test.pkg {
                       public class Layouts {
                         ctor public Layouts();
@@ -2720,7 +2780,7 @@
                       }
                     }
                     """,
-            source = """
+        source = """
                     package test.pkg;
                     @SuppressWarnings({"unchecked", "deprecation", "all"})
                     public class Layouts {
@@ -2742,18 +2802,18 @@
                     }
                     }
                     """
-        )
-    }
+    )
+}
 
-    @Test
-    fun `Missing overridden method`() {
-        // Another special case where overridden methods were missing
-        checkStubs(
-            checkDoclava1 = false,
-            sourceFiles =
-            *arrayOf(
-                java(
-                    """
+@Test
+fun `Missing overridden method`() {
+    // Another special case where overridden methods were missing
+    checkStubs(
+        checkDoclava1 = false,
+        sourceFiles =
+        *arrayOf(
+            java(
+                """
                     package test.pkg;
 
                     import java.util.Collection;
@@ -2780,10 +2840,10 @@
                         }
                     }
                     """
-                )
-            ),
-            warnings = "",
-            source = """
+            )
+        ),
+        warnings = "",
+        source = """
                     package test.pkg;
                     @SuppressWarnings({"unchecked", "deprecation", "all"})
                     public class SpanTest {
@@ -2805,18 +2865,18 @@
                     }
                     }
                     """
-        )
-    }
+    )
+}
 
-    @Test
-    fun `Skip type variables in casts`() {
-        // When generating casts in super constructor calls, use raw types
-        checkStubs(
-            checkDoclava1 = false,
-            sourceFiles =
-            *arrayOf(
-                java(
-                    """
+@Test
+fun `Skip type variables in casts`() {
+    // When generating casts in super constructor calls, use raw types
+    checkStubs(
+        checkDoclava1 = false,
+        sourceFiles =
+        *arrayOf(
+            java(
+                """
                     package test.pkg;
 
                     @SuppressWarnings("all")
@@ -2836,10 +2896,10 @@
                         }
                     }
                     """
-                )
-            ),
-            warnings = "",
-            source = """
+            )
+        ),
+        warnings = "",
+        source = """
                     package test.pkg;
                     @SuppressWarnings({"unchecked", "deprecation", "all"})
                     public class Properties {
@@ -2855,18 +2915,18 @@
                     }
                     }
                     """
-        )
-    }
+    )
+}
 
-    @Test
-    fun `Rewrite relative documentation links`() {
-        // When generating casts in super constructor calls, use raw types
-        checkStubs(
-            checkDoclava1 = false,
-            sourceFiles =
-            *arrayOf(
-                java(
-                    """
+@Test
+fun `Rewrite relative documentation links`() {
+    // When generating casts in super constructor calls, use raw types
+    checkStubs(
+        checkDoclava1 = false,
+        sourceFiles =
+        *arrayOf(
+            java(
+                """
                     package test.pkg1;
                     import java.io.IOException;
                     import test.pkg2.OtherClass;
@@ -2898,9 +2958,9 @@
                        public boolean importance;
                     }
                     """
-                ),
-                java(
-                    """
+            ),
+            java(
+                """
                     package test.pkg2;
 
                     @SuppressWarnings("all")
@@ -2911,19 +2971,19 @@
                         public void bar(int baz, boolean bar);
                     }
                     """
-                ),
-                java(
-                    """
+            ),
+            java(
+                """
                     package test.pkg1;
 
                     @SuppressWarnings("all")
                     public class LocalClass {
                     }
                     """
-                )
-            ),
-            warnings = "",
-            source = """
+            )
+        ),
+        warnings = "",
+        source = """
                     package test.pkg1;
                     import test.pkg2.OtherClass;
                     import java.io.IOException;
@@ -2955,52 +3015,52 @@
                     public boolean importance;
                     }
                     """
-        )
-    }
+    )
+}
 
-    @Test
-    fun `Check writing package info file`() {
-        checkStubs(
-            sourceFiles =
-            *arrayOf(
-                java(
-                    """
+@Test
+fun `Check writing package info file`() {
+    checkStubs(
+        sourceFiles =
+        *arrayOf(
+            java(
+                """
                     @androidx.annotation.Nullable
                     package test.pkg;
                     """
-                ),
-                java(
-                    """
+            ),
+            java(
+                """
                     package test.pkg;
 
                     @SuppressWarnings("all")
                     public class Test {
                     }
                     """
-                ),
-
-                supportNullableSource
             ),
-            warnings = "",
-            api = """
+
+            androidxNullableSource
+        ),
+        warnings = "",
+        api = """
                 package test.pkg {
                   public class Test {
                     ctor public Test();
                   }
                 }
             """, // WRONG: I should include package annotations!
-            source = """
+        source = """
                 @androidx.annotation.Nullable
                 package test.pkg;
                 """,
-            extraArguments = arrayOf("--hide-package", "androidx.annotation")
-        )
-    }
+        extraArguments = arrayOf("--hide-package", "androidx.annotation")
+    )
+}
 
-    // TODO: Add in some type variables in method signatures and constructors!
-    // TODO: Test what happens when a class extends a hidden extends a public in separate packages,
-    // and the hidden has a @hide constructor so the stub in the leaf class doesn't compile -- I should
-    // check for this and fail build.
+// TODO: Add in some type variables in method signatures and constructors!
+// TODO: Test what happens when a class extends a hidden extends a public in separate packages,
+// and the hidden has a @hide constructor so the stub in the leaf class doesn't compile -- I should
+// check for this and fail build.
 
-    // TODO: Test -stubPackages
+// TODO: Test -stubPackages
 }
\ No newline at end of file
diff --git a/stub-annotations/src/main/java/androidx/annotation/NonNull.java b/stub-annotations/src/main/java/androidx/annotation/NonNull.java
index 3b41cc8..647ee60 100644
--- a/stub-annotations/src/main/java/androidx/annotation/NonNull.java
+++ b/stub-annotations/src/main/java/androidx/annotation/NonNull.java
@@ -28,5 +28,5 @@
 
 /** Stub only annotation. Do not use directly. */
 @Retention(CLASS)
-@Target({METHOD, PARAMETER, FIELD, PACKAGE, TYPE_PARAMETER, TYPE_USE})
+@Target({METHOD, PARAMETER, FIELD, PACKAGE, TYPE_PARAMETER})
 public @interface NonNull {}
diff --git a/stub-annotations/src/main/java/androidx/annotation/Nullable.java b/stub-annotations/src/main/java/androidx/annotation/Nullable.java
index 0e6abce..b9c630f 100644
--- a/stub-annotations/src/main/java/androidx/annotation/Nullable.java
+++ b/stub-annotations/src/main/java/androidx/annotation/Nullable.java
@@ -28,5 +28,5 @@
 
 /** Stub only annotation. Do not use directly. */
 @Retention(CLASS)
-@Target({METHOD, PARAMETER, FIELD, PACKAGE, TYPE_PARAMETER, TYPE_USE})
+@Target({METHOD, PARAMETER, FIELD, PACKAGE, TYPE_PARAMETER})
 public @interface Nullable {}
diff --git a/stub-annotations/src/main/java/androidx/annotation/RecentlyNonNull.java b/stub-annotations/src/main/java/androidx/annotation/RecentlyNonNull.java
index 575b3eb..9ad4f5e 100644
--- a/stub-annotations/src/main/java/androidx/annotation/RecentlyNonNull.java
+++ b/stub-annotations/src/main/java/androidx/annotation/RecentlyNonNull.java
@@ -26,5 +26,5 @@
 
 /** Stub only annotation. Do not use directly. */
 @Retention(CLASS)
-@Target({METHOD, PARAMETER, FIELD, TYPE_USE})
+@Target({METHOD, PARAMETER, FIELD})
 public @interface RecentlyNonNull {}
diff --git a/stub-annotations/src/main/java/androidx/annotation/RecentlyNullable.java b/stub-annotations/src/main/java/androidx/annotation/RecentlyNullable.java
index 8a9141e..8ad2a2d 100644
--- a/stub-annotations/src/main/java/androidx/annotation/RecentlyNullable.java
+++ b/stub-annotations/src/main/java/androidx/annotation/RecentlyNullable.java
@@ -26,5 +26,5 @@
 
 /** Stub only annotation. Do not use directly. */
 @Retention(CLASS)
-@Target({METHOD, PARAMETER, FIELD, TYPE_USE})
+@Target({METHOD, PARAMETER, FIELD})
 public @interface RecentlyNullable {}