Call AIDL generation from KSP processor
Test: PrivacySandboxKspCompilerTest
Bug: 243918439
Change-Id: Icddb75ac37c6569389f112019c0f7ba963519516
diff --git a/privacysandbox/tools/tools-apicompiler/build.gradle b/privacysandbox/tools/tools-apicompiler/build.gradle
index fea0b81..d185ba8 100644
--- a/privacysandbox/tools/tools-apicompiler/build.gradle
+++ b/privacysandbox/tools/tools-apicompiler/build.gradle
@@ -15,6 +15,8 @@
*/
import androidx.build.LibraryType
+import androidx.build.SdkHelperKt
+import androidx.build.SupportConfig
plugins {
id("AndroidXPlugin")
@@ -30,6 +32,21 @@
testImplementation(project(":room:room-compiler-processing-testing"))
testImplementation(libs.junit)
testImplementation(libs.truth)
+ // Include android jar for compilation of generated sources.
+ testImplementation(fileTree(
+ dir: "${SdkHelperKt.getSdkPath(project)}/platforms/$SupportConfig.COMPILE_SDK_VERSION/",
+ include: "android.jar"
+ ))
+ // Get AIDL compiler path and pass it to tests for code generation.
+ def aidlCompilerPath = "${SdkHelperKt.getSdkPath(project)}/build-tools/${SupportConfig.BUILD_TOOLS_VERSION}/aidl"
+ test {
+ inputs.files(aidlCompilerPath)
+ .withPropertyName("aidl_compiler_path")
+ .withPathSensitivity(PathSensitivity.NAME_ONLY)
+ doFirst {
+ systemProperty "aidl_compiler_path", aidlCompilerPath
+ }
+ }
}
androidx {
diff --git a/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/PrivacySandboxKspCompiler.kt b/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/PrivacySandboxKspCompiler.kt
index 3423e89..672311d 100644
--- a/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/PrivacySandboxKspCompiler.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/PrivacySandboxKspCompiler.kt
@@ -16,42 +16,52 @@
package androidx.privacysandbox.tools.apicompiler
+import androidx.privacysandbox.tools.apicompiler.generator.SdkCodeGenerator
import androidx.privacysandbox.tools.apicompiler.parser.ApiParser
import com.google.devtools.ksp.processing.CodeGenerator
-import com.google.devtools.ksp.processing.Dependencies
import com.google.devtools.ksp.processing.KSPLogger
import com.google.devtools.ksp.processing.Resolver
import com.google.devtools.ksp.processing.SymbolProcessor
import com.google.devtools.ksp.processing.SymbolProcessorEnvironment
import com.google.devtools.ksp.processing.SymbolProcessorProvider
import com.google.devtools.ksp.symbol.KSAnnotated
+import java.nio.file.Paths
class PrivacySandboxKspCompiler(
private val logger: KSPLogger,
- private val codeGenerator: CodeGenerator
+ private val codeGenerator: CodeGenerator,
+ private val options: Map<String, String>,
) :
SymbolProcessor {
+ companion object {
+ const val AIDL_COMPILER_PATH_OPTIONS_KEY = "aidl_compiler_path"
+ }
+
var invoked = false
override fun process(resolver: Resolver): List<KSAnnotated> {
if (invoked) {
return emptyList()
}
- ApiParser(resolver, logger).parseApi()
- // TODO: remove once actual conde generation is in place.
- createTestFile()
invoked = true
- return emptyList()
- }
+ val parsedApi = ApiParser(resolver, logger).parseApi()
- private fun createTestFile() {
- val testFile = codeGenerator.createNewFile(Dependencies(false), "", "TestFile", "txt")
- testFile.write("TestFile".toByteArray())
+ val path = options[AIDL_COMPILER_PATH_OPTIONS_KEY]?.let(Paths::get)
+ if (path == null) {
+ logger.error("KSP argument '$AIDL_COMPILER_PATH_OPTIONS_KEY' was not set.")
+ return emptyList()
+ }
+ SdkCodeGenerator(codeGenerator, parsedApi, path).generate()
+ return emptyList()
}
class Provider : SymbolProcessorProvider {
override fun create(environment: SymbolProcessorEnvironment): SymbolProcessor {
- return PrivacySandboxKspCompiler(environment.logger, environment.codeGenerator)
+ return PrivacySandboxKspCompiler(
+ environment.logger,
+ environment.codeGenerator,
+ environment.options
+ )
}
}
}
\ No newline at end of file
diff --git a/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/generator/SdkCodeGenerator.kt b/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/generator/SdkCodeGenerator.kt
new file mode 100644
index 0000000..b080ea3
--- /dev/null
+++ b/privacysandbox/tools/tools-apicompiler/src/main/java/androidx/privacysandbox/tools/apicompiler/generator/SdkCodeGenerator.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2022 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 androidx.privacysandbox.tools.apicompiler.generator
+
+import androidx.privacysandbox.tools.core.ParsedApi
+import androidx.privacysandbox.tools.core.generator.AidlCompiler
+import androidx.privacysandbox.tools.core.generator.AidlGenerator
+import com.google.devtools.ksp.processing.CodeGenerator
+import com.google.devtools.ksp.processing.Dependencies
+import java.nio.file.Files.createTempDirectory
+import java.nio.file.Path
+
+class SdkCodeGenerator(
+ private val codeGenerator: CodeGenerator,
+ private val api: ParsedApi,
+ private val aidlCompilerPath: Path,
+) {
+ fun generate() {
+ generateAidlSources()
+ }
+
+ private fun generateAidlSources() {
+ val workingDir = createTempDirectory("aidl")
+ try {
+ AidlGenerator.generate(AidlCompiler(aidlCompilerPath), api, workingDir)
+ .forEach { source ->
+ // Sources created by the AIDL compiler have to be copied to files created through the
+ // KSP APIs, so that they are included in downstream compilation.
+ val kspGeneratedFile = codeGenerator.createNewFile(
+ Dependencies(false),
+ source.packageName,
+ source.interfaceName,
+ extensionName = "java"
+ )
+ source.file.inputStream().copyTo(kspGeneratedFile)
+ }
+ } finally {
+ workingDir.toFile().deleteRecursively()
+ }
+ }
+}
\ No newline at end of file
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/PrivacySandboxKspCompilerTest.kt b/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/PrivacySandboxKspCompilerTest.kt
index 168aaf8..9e3b644 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/PrivacySandboxKspCompilerTest.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/PrivacySandboxKspCompilerTest.kt
@@ -37,8 +37,8 @@
import androidx.privacysandbox.tools.PrivacySandboxService
@PrivacySandboxService
interface MySdk {
- suspend fun doStuff(x: Int, y: Int): String
- suspend fun doMoreStuff()
+ fun doStuff(x: Int, y: Int): String
+ fun doMoreStuff()
}
"""
)
@@ -50,9 +50,15 @@
TestCompilationArguments(
sources = listOf(source),
symbolProcessorProviders = listOf(provider),
+ processorOptions = getProcessorOptions(),
)
)
- ).succeeds()
+ ).generatesExactlySources(
+ "com/mysdk/IMySdk.java",
+ "com/mysdk/ICancellationSignal.java",
+ "com/mysdk/IUnitTransactionCallback.java",
+ "com/mysdk/IStringTransactionCallback.java",
+ )
}
@Test
@@ -77,9 +83,16 @@
Files.createTempDirectory("test").toFile(),
TestCompilationArguments(
sources = listOf(source),
- symbolProcessorProviders = listOf(provider)
+ symbolProcessorProviders = listOf(provider),
+ processorOptions = getProcessorOptions(),
)
)
).fails()
}
+
+ private fun getProcessorOptions() =
+ mapOf(
+ "aidl_compiler_path" to (System.getProperty("aidl_compiler_path")
+ ?: throw IllegalArgumentException("aidl_compiler_path flag not set."))
+ )
}
\ No newline at end of file
diff --git a/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/util/KspTestRunner.kt b/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/util/KspTestRunner.kt
index 24eaf8c..394d8cf 100644
--- a/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/util/KspTestRunner.kt
+++ b/privacysandbox/tools/tools-apicompiler/src/test/java/androidx/privacysandbox/tools/apicompiler/util/KspTestRunner.kt
@@ -72,6 +72,12 @@
assertWithMessage("UnexpectedErrors: ${getErrorMessages()}").that(result.success).isTrue()
}
+ fun generatesExactlySources(vararg sourcePaths: String) {
+ succeeds()
+ assertThat(result.generatedSources.map(Source::relativePath))
+ .containsExactlyElementsIn(sourcePaths)
+ }
+
fun fails() {
assertThat(result.success).isFalse()
}