Snap for 10406761 from 840699e770d4a4c57a871a0d51790df8918e433c to studio-giraffe-release

Change-Id: I0d091b84c28f4f8b06507dab99809159179923dc
diff --git a/build-system/gradle-core/src/main/java/com/android/build/api/variant/impl/FlatSourceDirectoriesImpl.kt b/build-system/gradle-core/src/main/java/com/android/build/api/variant/impl/FlatSourceDirectoriesImpl.kt
index eb3abfc..f736236 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/api/variant/impl/FlatSourceDirectoriesImpl.kt
+++ b/build-system/gradle-core/src/main/java/com/android/build/api/variant/impl/FlatSourceDirectoriesImpl.kt
@@ -20,6 +20,7 @@
 import com.android.build.gradle.internal.services.VariantServices
 import org.gradle.api.file.ConfigurableFileTree
 import org.gradle.api.file.Directory
+import org.gradle.api.file.FileCollection
 import org.gradle.api.provider.Provider
 import org.gradle.api.tasks.util.PatternFilterable
 import java.io.File
@@ -101,24 +102,29 @@
     /*
      * Internal API that can only be used by the model.
      */
-    override fun variantSourcesForModel(filter: (DirectoryEntry) -> Boolean ): List<File> {
-        val files = mutableListOf<File>()
+    override fun variantSourcesForModel(filter: (DirectoryEntry) -> Boolean ): List<File> =
+        variantSourcesFileCollectionForModel(filter).files.toList()
+
+    internal fun variantSourcesFileCollectionForModel(
+        filter: (DirectoryEntry) -> Boolean
+    ): FileCollection {
+        val fileCollection = variantServices.fileCollection()
         variantSources.get()
             .filter { filter.invoke(it) }
             .forEach {
                 if (it is TaskProviderBasedDirectoryEntryImpl) {
-                    files.add(it.directoryProvider.get().asFile)
+                    fileCollection.from(it.directoryProvider)
                 } else {
-                    val asDirectoryProperties = it.asFiles(
-                      variantServices.provider {
-                          variantServices.projectInfo.projectDirectory
-                      }
+                    fileCollection.from(
+                        it.asFiles(
+                            variantServices.provider {
+                                variantServices.projectInfo.projectDirectory
+                            }
+                        )
                     )
-                    asDirectoryProperties.get().forEach { directory ->
-                        files.add(directory.asFile)
-                    }
                 }
             }
-        return files
+        fileCollection.disallowChanges()
+        return fileCollection
     }
 }
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ide/ModelBuilder.java b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ide/ModelBuilder.java
index e504101..113bb48 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ide/ModelBuilder.java
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/ide/ModelBuilder.java
@@ -1178,7 +1178,7 @@
                 .java(
                         javaSources -> {
                             fileCollection.from(
-                                    javaSources.variantSourcesForModel$gradle_core(
+                                    javaSources.variantSourcesFileCollectionForModel$gradle_core(
                                             directoryEntry ->
                                                     directoryEntry.isGenerated()
                                                             && directoryEntry
diff --git a/build-system/gradle-core/src/test/java/com/android/build/api/variant/impl/SourceDirectoriesImplTest.kt b/build-system/gradle-core/src/test/java/com/android/build/api/variant/impl/SourceDirectoriesImplTest.kt
index 73fe41e..a6f9e9f 100644
--- a/build-system/gradle-core/src/test/java/com/android/build/api/variant/impl/SourceDirectoriesImplTest.kt
+++ b/build-system/gradle-core/src/test/java/com/android/build/api/variant/impl/SourceDirectoriesImplTest.kt
@@ -72,7 +72,6 @@
             .thenReturn(project.objects.listProperty(DirectoryEntry::class.java))
         Mockito.`when`(variantServices.newListPropertyForInternalUse(Directory::class.java))
             .thenReturn(project.objects.listProperty(Directory::class.java))
-
     }
 
     @Test
@@ -94,6 +93,8 @@
 
     @Test
     fun testVariantSourcesForModel() {
+        Mockito.`when`(variantServices.fileCollection())
+            .thenReturn(project.objects.fileCollection())
         val addedSourceFromTask = project.layout.buildDirectory.dir("generated/_for_test/srcAddingTask").get().asFile
         val addedSrcDir = temporaryFolder.newFolder("somewhere/safe")
         val testTarget = createTestTarget(addedSrcDir)
@@ -107,6 +108,8 @@
 
     @Test
     fun testVariantSourcesWithFilteringForModel() {
+        Mockito.`when`(variantServices.fileCollection())
+            .thenReturn(project.objects.fileCollection())
         val addedSourceFromTask = project.layout.buildDirectory.dir("generated/_for_test/srcAddingTask").get().asFile
         val addedSrcDir = temporaryFolder.newFolder("somewhere/safe")
         val testTarget = createTestTarget(addedSrcDir)
diff --git a/build-system/integration-test/application/src/test/java/com/android/build/gradle/integration/application/LocaleConfigGenerationTest.kt b/build-system/integration-test/application/src/test/java/com/android/build/gradle/integration/application/LocaleConfigGenerationTest.kt
index f52a654..4ee2d3d 100644
--- a/build-system/integration-test/application/src/test/java/com/android/build/gradle/integration/application/LocaleConfigGenerationTest.kt
+++ b/build-system/integration-test/application/src/test/java/com/android/build/gradle/integration/application/LocaleConfigGenerationTest.kt
@@ -313,14 +313,14 @@
         ).execute("assembleDebug")
 
         assertLocaleList("app", "debug")
-            .containsExactly("de-DE", "es-ES","zh-Hans-SG","en-GB")
+            .isEqualTo(listOf("de-DE", "es-ES", "zh-Hans-SG", "en-GB"))
         assertLocaleList("lib1", "debug")
             .containsExactly("ru-RU")
         assertLocaleList("lib2", "debug")
             .containsExactly("pt-BR")
         // Final xml adds default locale (de-DE)
         assertLocaleConfig("debug")
-            .containsExactly("de-DE", "es-ES","zh-Hans-SG","en-GB", "ru-RU", "pt-BR")
+            .isEqualTo(listOf("de-DE", "es-ES", "zh-Hans-SG", "en-GB", "ru-RU", "pt-BR"))
     }
 
     @Test
@@ -334,13 +334,13 @@
         ).execute("assembleDebug")
 
         assertLocaleList("app", "debug")
-            .containsExactly("en-US", "es-ES","zh-Hans-SG","en-GB")
+            .isEqualTo(listOf("en-US", "es-ES", "zh-Hans-SG", "en-GB"))
         assertLocaleList("lib1", "debug")
             .containsExactly("es-ES", "ru-RU")
         assertLocaleList("lib2", "debug")
             .containsExactly("pt-BR", "en-US")
         assertLocaleConfig("debug")
-            .containsExactly("en-US", "es-ES", "zh-Hans-SG","en-GB", "ru-RU", "pt-BR")
+            .isEqualTo(listOf("en-US", "es-ES", "zh-Hans-SG", "en-GB", "ru-RU", "pt-BR"))
     }
 
     @Test
@@ -491,8 +491,8 @@
         ).execute("assembleDebug")
 
         // london flavor res should not be included
-        assertLocaleList("app", "tokyoDebug").containsExactly("en-US", "jp-JP")
-        assertLocaleConfig("tokyo/debug").containsExactly("en-US", "es-ES", "pt-BR", "jp-JP")
+        assertLocaleList("app", "tokyoDebug").isEqualTo(listOf("en-US", "jp-JP"))
+        assertLocaleConfig("tokyo/debug").isEqualTo(listOf("en-US", "jp-JP", "es-ES", "pt-BR"))
     }
 
     @Test
diff --git a/build-system/integration-test/lint/src/test/java/com/android/build/gradle/integration/lint/LintConfigurationCacheTest.kt b/build-system/integration-test/lint/src/test/java/com/android/build/gradle/integration/lint/LintConfigurationCacheTest.kt
new file mode 100644
index 0000000..ee38cc1
--- /dev/null
+++ b/build-system/integration-test/lint/src/test/java/com/android/build/gradle/integration/lint/LintConfigurationCacheTest.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.build.gradle.integration.lint
+
+import com.android.build.gradle.integration.common.fixture.GradleTestProject
+import com.android.build.gradle.integration.common.fixture.app.MinimalSubProject
+import com.android.build.gradle.integration.common.truth.ScannerSubject.Companion.assertThat
+import org.junit.Rule
+import org.junit.Test
+
+class LintConfigurationCacheTest {
+
+    @get:Rule
+    val project: GradleTestProject =
+        GradleTestProject.builder()
+            .fromTestApp(
+                MinimalSubProject.lib("com.example.lib")
+                    .appendToBuild(
+                        """
+                            android {
+                                libraryVariants.all { variant ->
+                                    if (variant.name == "debug") {
+                                        FileTree cTree =
+                                            project.fileTree(
+                                                new File(
+                                                    project.buildDir,
+                                                    "generated/source/kapt/debug"
+                                                )
+                                            )
+                                        cTree.builtBy(tasks.findByName("generateSrcs"))
+                                        cTree.include("**/*.java")
+                                        registerExternalAptJavaOutput(cTree)
+                                    }
+                                }
+                            }
+
+                            tasks.register("generateSrcs") {
+                                File myOutputDir =
+                                    new File(project.buildDir, "generated/source/kapt/debug")
+                                doFirst {
+                                    myOutputDir.deleteDir()
+                                    myOutputDir.mkdirs()
+                                    new File(myOutputDir, "Foo.java").text = "public class Foo {}"
+                                }
+                            }
+
+                        """.trimIndent()
+                    )
+            )
+            .create()
+
+    /** Regression test for b/285320724. */
+    @Test
+    fun testLintConfigurationCache() {
+        project.executor().run("generateDebugLintModel")
+        project.executor().run("generateDebugLintModel").stdout.use {
+            assertThat(it).doesNotContain("configuration cache cannot be reused")
+        }
+    }
+}
diff --git a/common/release_version.bzl b/common/release_version.bzl
index 59ccc3d..d71fab5 100644
--- a/common/release_version.bzl
+++ b/common/release_version.bzl
@@ -1,3 +1,3 @@
-BASE_VERSION = "31.1.0-rc01"
-BUILD_VERSION = "8.1.0-rc01"
-COMMANDLINE_TOOLS_VERSION = "11.0-rc01"
\ No newline at end of file
+BASE_VERSION = "31.1.0"
+BUILD_VERSION = "8.1.0"
+COMMANDLINE_TOOLS_VERSION = "11.0"
\ No newline at end of file
diff --git a/sdk-common/src/main/java/com/android/ide/common/resources/LocaleConfigGenerator.kt b/sdk-common/src/main/java/com/android/ide/common/resources/LocaleConfigGenerator.kt
index ca47916..565f9e5 100644
--- a/sdk-common/src/main/java/com/android/ide/common/resources/LocaleConfigGenerator.kt
+++ b/sdk-common/src/main/java/com/android/ide/common/resources/LocaleConfigGenerator.kt
@@ -38,7 +38,9 @@
     // Fold all root resource directories into a one-dimensional
     // list of qualified resource directories (main/res -> main/res/values-en-rUS, etc.)
     val allResources = resources.fold(mutableListOf<File>()) { acc, it ->
-        acc.addAll(it.listFiles()?.toList() ?: listOf())
+        if (it.isDirectory()) {
+          acc.addAll(it.listFiles()!!.sortedBy { file -> file.invariantSeparatorsPath })
+        }
         acc
     }.filter {
         it.isDirectory && it.listFiles()!!.isNotEmpty() // Ignore empty folders and files
@@ -59,12 +61,12 @@
     return supportedLocales.toList()
 }
 
-fun mergeLocaleLists(allLocales: Collection<Collection<String>>): List<String> {
+fun mergeLocaleLists(allLocales: Collection<Collection<String>>): Set<String> {
     val foldedLocales = allLocales.fold(mutableSetOf<String>()) { acc, it ->
         acc.addAll(it)
         acc
     }
-    return foldedLocales.toList()
+    return foldedLocales
 }
 
 fun writeSupportedLocales(output: File, locales: Collection<String>, defaultLocale: String?) {
@@ -91,11 +93,10 @@
     return localeQualifier?.run { generateLocaleString(localeQualifier) }
 }
 
-fun writeLocaleConfig(output: File, locales: Collection<String>) {
-    val localeSet = locales.toMutableSet()
+fun writeLocaleConfig(output: File, locales: Set<String>) {
     val outLines = mutableListOf<String>()
     outLines.add("<locale-config xmlns:android=\"http://schemas.android.com/apk/res/android\">")
-    localeSet.forEach { localeString ->
+    locales.forEach { localeString ->
         outLines.add("    <locale android:name=\"$localeString\"/>")
     }
     outLines.add("</locale-config>")
diff --git a/sdk-common/src/test/java/com/android/ide/common/resources/localeGen/LocaleGenerationTest.kt b/sdk-common/src/test/java/com/android/ide/common/resources/localeGen/LocaleGenerationTest.kt
index f2f3f26..f6f0c0a 100644
--- a/sdk-common/src/test/java/com/android/ide/common/resources/localeGen/LocaleGenerationTest.kt
+++ b/sdk-common/src/test/java/com/android/ide/common/resources/localeGen/LocaleGenerationTest.kt
@@ -69,7 +69,7 @@
         addResFolder(res3, "values-b+zh+Hans+SG", false)
 
         assertThat(generateLocaleList(listOf(res1, res2, res3)))
-            .containsExactly("en-US", "ru-RU", "es-ES", "pt-BR", "zh-Hans-SG")
+            .isEqualTo(listOf("es-ES", "en-US", "ru-RU", "pt-BR", "zh-Hans-SG"))
     }
 
     @Test
@@ -86,7 +86,7 @@
         val outfile = temporaryFolder.newFile("locale_config.xml")
         writeLocaleConfig(
             output = outfile,
-            locales = listOf("en-US", "ru-RU", "es-ES", "pt-BR", "zh-Hans-SG", "en-GB")
+            locales = setOf("en-US", "ru-RU", "es-ES", "pt-BR", "zh-Hans-SG", "en-GB")
         )
         assertThat(
             listOf(
@@ -97,7 +97,7 @@
                 """    <locale android:name="pt-BR"/>""",
                 """    <locale android:name="zh-Hans-SG"/>""",
                 """    <locale android:name="en-GB"/>""",
-                """</locale-config>""")).containsExactlyElementsIn(outfile.readLines()).inOrder()
+                """</locale-config>""")).isEqualTo(outfile.readLines())
     }
 
     @Test