[privacy sandbox] Add targetSdkVersion to DSL and it as manifest merging input
Adds targetSdkVersion option to PrivacySandbox DSL. It will default to compileSdk version if not set.
targetSdkVersion will be provided to the manifest merger to avoid unintentionally setting targetSdkVersion using from dependendency manifests.
Fixes: 345719173
Test: PrivacySandboxSdkTest
Change-Id: Id955e71d5b9256c129a46af2b0c8b9e013ab4497
diff --git a/build-system/gradle-api/api/current.txt b/build-system/gradle-api/api/current.txt
index 4eeb864..4d68fd1 100644
--- a/build-system/gradle-api/api/current.txt
+++ b/build-system/gradle-api/api/current.txt
@@ -1878,6 +1878,7 @@
method @Deprecated @org.gradle.api.Incubating public String? getNamespace();
method @org.gradle.api.Incubating public com.android.build.api.dsl.PrivacySandboxSdkOptimization getOptimization();
method @org.gradle.api.Incubating public com.android.build.api.dsl.SigningConfig getSigningConfig();
+ method @org.gradle.api.Incubating public Integer? getTargetSdk();
method @org.gradle.api.Incubating public void optimization(kotlin.jvm.functions.Function1<? super com.android.build.api.dsl.PrivacySandboxSdkOptimization,kotlin.Unit> action);
method @org.gradle.api.Incubating public void setBuildToolsVersion(String);
method @org.gradle.api.Incubating public void setCompileSdk(Integer?);
@@ -1886,6 +1887,7 @@
method @org.gradle.api.Incubating public void setMinSdk(Integer?);
method @org.gradle.api.Incubating public void setMinSdkPreview(String?);
method @Deprecated @org.gradle.api.Incubating public void setNamespace(String?);
+ method @org.gradle.api.Incubating public void setTargetSdk(Integer?);
method @org.gradle.api.Incubating public void signingConfig(kotlin.jvm.functions.Function1<? super com.android.build.api.dsl.SigningConfig,kotlin.Unit> action);
property @org.gradle.api.Incubating public abstract String buildToolsVersion;
property @org.gradle.api.Incubating public abstract com.android.build.api.dsl.PrivacySandboxSdkBundle bundle;
@@ -1898,6 +1900,7 @@
property @Deprecated @org.gradle.api.Incubating public abstract String? namespace;
property @org.gradle.api.Incubating public abstract com.android.build.api.dsl.PrivacySandboxSdkOptimization optimization;
property @org.gradle.api.Incubating public abstract com.android.build.api.dsl.SigningConfig signingConfig;
+ property @org.gradle.api.Incubating public abstract Integer? targetSdk;
}
@org.gradle.api.Incubating public interface PrivacySandboxSdkOptimization {
diff --git a/build-system/gradle-api/src/main/java/com/android/build/api/dsl/PrivacySandboxSdkExtension.kt b/build-system/gradle-api/src/main/java/com/android/build/api/dsl/PrivacySandboxSdkExtension.kt
index 98d6e2d..1ea7858 100644
--- a/build-system/gradle-api/src/main/java/com/android/build/api/dsl/PrivacySandboxSdkExtension.kt
+++ b/build-system/gradle-api/src/main/java/com/android/build/api/dsl/PrivacySandboxSdkExtension.kt
@@ -90,6 +90,10 @@
@set:Incubating
var minSdkPreview: String?
+ @get:Incubating
+ @set:Incubating
+ var targetSdk: Int?
+
@get:Deprecated(message = "namespace is replaced with applicationId in bundle block", replaceWith = ReplaceWith("bundle.applicationId"))
@get:Incubating
@set:Deprecated(message = "namespace is replaced with applicationId in bundle block", replaceWith = ReplaceWith("bundle.applicationId"))
diff --git a/build-system/gradle-api/src/test/resources/com/android/build/api/incubating-api.txt b/build-system/gradle-api/src/test/resources/com/android/build/api/incubating-api.txt
index f02018b..ede1ca7 100644
--- a/build-system/gradle-api/src/test/resources/com/android/build/api/incubating-api.txt
+++ b/build-system/gradle-api/src/test/resources/com/android/build/api/incubating-api.txt
@@ -317,6 +317,7 @@
* com.android.build.api.dsl.PrivacySandboxSdkExtension.getNamespace: java.lang.String ()
* com.android.build.api.dsl.PrivacySandboxSdkExtension.getOptimization: com.android.build.api.dsl.PrivacySandboxSdkOptimization ()
* com.android.build.api.dsl.PrivacySandboxSdkExtension.getSigningConfig: com.android.build.api.dsl.SigningConfig ()
+ * com.android.build.api.dsl.PrivacySandboxSdkExtension.getTargetSdk: java.lang.Integer ()
* com.android.build.api.dsl.PrivacySandboxSdkExtension.optimization: void (kotlin.jvm.functions.Function1<? super com.android.build.api.dsl.PrivacySandboxSdkOptimization, kotlin.Unit>)
* com.android.build.api.dsl.PrivacySandboxSdkExtension.setBuildToolsVersion: void (java.lang.String)
* com.android.build.api.dsl.PrivacySandboxSdkExtension.setCompileSdk: void (java.lang.Integer)
@@ -325,6 +326,7 @@
* com.android.build.api.dsl.PrivacySandboxSdkExtension.setMinSdk: void (java.lang.Integer)
* com.android.build.api.dsl.PrivacySandboxSdkExtension.setMinSdkPreview: void (java.lang.String)
* com.android.build.api.dsl.PrivacySandboxSdkExtension.setNamespace: void (java.lang.String)
+ * com.android.build.api.dsl.PrivacySandboxSdkExtension.setTargetSdk: void (java.lang.Integer)
* com.android.build.api.dsl.PrivacySandboxSdkExtension.signingConfig: void (kotlin.jvm.functions.Function1<? super com.android.build.api.dsl.SigningConfig, kotlin.Unit>)
* com.android.build.api.dsl.PrivacySandboxSdkOptimization
* com.android.build.api.dsl.PrivacySandboxSdkOptimization.getKeepRules: com.android.build.api.dsl.PrivacySandboxKeepRules ()
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/privaysandboxsdk/PrivacySandboxSdkVariantScope.kt b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/privaysandboxsdk/PrivacySandboxSdkVariantScope.kt
index 7fc4519..b1aed1e 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/privaysandboxsdk/PrivacySandboxSdkVariantScope.kt
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/privaysandboxsdk/PrivacySandboxSdkVariantScope.kt
@@ -43,6 +43,7 @@
val mergeSpec: Spec<ComponentIdentifier>
val compileSdkVersion: String
val minSdkVersion: ApiVersion
+ val targetSdkVersion: ApiVersion
val bootClasspath: Provider<List<RegularFile>>
val bundle: PrivacySandboxSdkBundleImpl
val services: TaskCreationServices
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/privaysandboxsdk/PrivacySandboxSdkVariantScopeImpl.kt b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/privaysandboxsdk/PrivacySandboxSdkVariantScopeImpl.kt
index 3ad2ebc..c792cb6 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/privaysandboxsdk/PrivacySandboxSdkVariantScopeImpl.kt
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/internal/privaysandboxsdk/PrivacySandboxSdkVariantScopeImpl.kt
@@ -70,17 +70,23 @@
}
override val compileSdkVersion: String by lazy {
- extension.compileSdkPreview?.let { validatePreviewTargetValue(it) }?.let { "android-$it" } ?:
- extension.compileSdkExtension?.let { "android-${extension.compileSdk}-ext$it" } ?:
- extension.compileSdk?.let {"android-$it"} ?: throw RuntimeException(
- "compileSdk version is not set"
- )
+ "android-${getCompileSdkApiVersion(extension).apiString}"
}
+
override val minSdkVersion: ApiVersion by lazy {
extension.minSdkPreview?.let { DefaultApiVersion(it) } ?:
extension.minSdk?.let { DefaultApiVersion(it) } ?:
DefaultApiVersion(34)
}
+
+ override val targetSdkVersion: ApiVersion by lazy {
+ extension.targetSdk?.let {
+ DefaultApiVersion(
+ it
+ )
+ } ?: getCompileSdkApiVersion(extension)
+ }
+
override val bootClasspath: Provider<List<RegularFile>>
get() = bootClasspathConfigProvider.invoke().bootClasspath
override val bundle: PrivacySandboxSdkBundleImpl
@@ -100,4 +106,20 @@
projectServices.projectOptions,
namespacedAndroidResources = NAMESPACED_ANDROID_RESOURCES_FOR_PRIVACY_SANDBOX_ENABLED
)
+
+ private fun getCompileSdkApiVersion(extension: PrivacySandboxSdkExtension): ApiVersion {
+ return maybeGetCompileSdkPreview(extension)
+ ?: maybeGetCompileSdk(extension)
+ ?: throw RuntimeException("compileSdk version is not set")
+ }
+
+ private fun maybeGetCompileSdk(extension: PrivacySandboxSdkExtension): ApiVersion? {
+ return (extension.compileSdkExtension ?: extension.compileSdk)
+ ?.let { DefaultApiVersion(it) }
+ }
+
+ private fun maybeGetCompileSdkPreview(extension: PrivacySandboxSdkExtension): ApiVersion? {
+ return extension.compileSdkPreview?.let { validatePreviewTargetValue(it) }
+ ?.let { DefaultApiVersion(it) }
+ }
}
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/FusedLibraryManifestMergerTask.kt b/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/FusedLibraryManifestMergerTask.kt
index 21ce3e8..015eebd 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/FusedLibraryManifestMergerTask.kt
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/FusedLibraryManifestMergerTask.kt
@@ -43,6 +43,7 @@
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFiles
import org.gradle.api.tasks.Internal
+import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.OutputFile
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
diff --git a/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/PrivacySandboxSdkManifestMergerTask.kt b/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/PrivacySandboxSdkManifestMergerTask.kt
index b36fe09..11dd0e3 100644
--- a/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/PrivacySandboxSdkManifestMergerTask.kt
+++ b/build-system/gradle-core/src/main/java/com/android/build/gradle/tasks/PrivacySandboxSdkManifestMergerTask.kt
@@ -36,7 +36,9 @@
import org.gradle.api.provider.MapProperty
import org.gradle.api.provider.Property
import org.gradle.api.tasks.CacheableTask
+import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile
+import org.gradle.api.tasks.Optional
import org.gradle.api.tasks.PathSensitive
import org.gradle.api.tasks.PathSensitivity
import org.gradle.api.tasks.TaskProvider
@@ -46,15 +48,19 @@
@BuildAnalyzer(primaryTaskCategory = TaskCategory.MANIFEST, secondaryTaskCategories = [TaskCategory.MERGING])
abstract class PrivacySandboxSdkManifestMergerTask: FusedLibraryManifestMergerTask() {
- @get: InputFile
+ @get:InputFile
@get:PathSensitive(PathSensitivity.NAME_ONLY)
abstract val mainManifestFile: RegularFileProperty
+ @get:Input
+ abstract val targetSdkVersion: Property<String>
+
abstract class PrivacySandboxManifestMergerParams: ProfileAwareWorkAction.Parameters() {
abstract val mainAndroidManifest: RegularFileProperty
abstract val dependencies: MapProperty<String, File>
abstract val namespace: Property<String>
abstract val minSdkVersion: Property<String>
+ abstract val targetSdkVersion: Property<String>
abstract val outMergedManifestLocation: RegularFileProperty
abstract val reportFile: RegularFileProperty
}
@@ -77,7 +83,7 @@
versionCode = null,
versionName = null,
minSdkVersion = minSdkVersion.get(),
- targetSdkVersion = null,
+ targetSdkVersion = targetSdkVersion.get(),
maxSdkVersion = null,
testOnly = false,
extractNativeLibs = null,
@@ -108,6 +114,7 @@
params.dependencies.set(identifierToManifestDependencyFile)
params.namespace.set(namespace)
params.minSdkVersion.set(minSdkVersion)
+ params.targetSdkVersion.setDisallowChanges(targetSdkVersion)
params.outMergedManifestLocation.set(mergedFusedLibraryManifest)
params.reportFile.set(reportFile)
params.mainAndroidManifest.set(mainManifestFile)
@@ -151,6 +158,7 @@
)
task.libraryManifests.set(libraryManifests)
task.minSdkVersion.setDisallowChanges(creationConfig.minSdkVersion.apiString)
+ task.targetSdkVersion.setDisallowChanges(creationConfig.targetSdkVersion.apiString)
task.namespace.setDisallowChanges(creationConfig.extension.bundle.applicationId)
task.tmpDir.setDisallowChanges(
creationConfig.layout.buildDirectory.dir("tmp/FusedLibraryManifestMerger")
diff --git a/build-system/integration-test/application/src/test/java/com/android/build/gradle/integration/privacysandbox/PrivacySandboxSdkTest.kt b/build-system/integration-test/application/src/test/java/com/android/build/gradle/integration/privacysandbox/PrivacySandboxSdkTest.kt
index 9430d06..66763a8 100644
--- a/build-system/integration-test/application/src/test/java/com/android/build/gradle/integration/privacysandbox/PrivacySandboxSdkTest.kt
+++ b/build-system/integration-test/application/src/test/java/com/android/build/gradle/integration/privacysandbox/PrivacySandboxSdkTest.kt
@@ -19,26 +19,18 @@
import com.android.SdkConstants
import com.android.build.gradle.integration.common.fixture.testprojects.prebuilts.privacysandbox.privacySandboxSampleProject
import com.android.build.gradle.integration.common.utils.TestFileUtils
-import com.android.build.gradle.internal.scope.InternalArtifactType
import com.android.build.gradle.options.BooleanOption
import com.android.ide.common.signing.KeystoreHelper
-import com.android.testutils.TestUtils
-import com.android.testutils.apk.Apk
import com.android.testutils.apk.Dex
import com.android.testutils.apk.Zip
import com.android.testutils.truth.PathSubject.assertThat
import com.android.testutils.truth.ZipFileSubject
-import com.android.tools.apk.analyzer.AaptInvoker
import com.android.utils.FileUtils
-import com.android.utils.StdLogger
import com.google.common.truth.Truth.assertThat
import org.junit.Rule
import org.junit.Test
import java.io.File
-import java.nio.file.Files
import java.util.Objects
-import java.util.zip.ZipFile
-import kotlin.io.path.name
import kotlin.io.path.readText
/** Integration tests for the privacy sandbox SDK */
@@ -340,4 +332,21 @@
)
executor().run(":privacy-sandbox-sdk:generatePrivacySandboxProguardRules")
}
+
+ @Test
+ fun testTargetSdkVersion() {
+ project.getSubproject(":privacy-sandbox-sdk").buildFile.appendText("\nandroid.targetSdk 33")
+ executor().run(":privacy-sandbox-sdk:assemble")
+ val sdkProject = project.getSubproject(":privacy-sandbox-sdk")
+ val asbManifest = sdkProject.getIntermediateFile(
+ "merged_manifest", "single", "mergeManifest", "AndroidManifest.xml")
+ val manifestLines = asbManifest.readLines()
+ assertThat(manifestLines).containsAtLeastElementsIn(
+ listOf(
+ " <uses-sdk",
+ " android:minSdkVersion=\"23\"",
+ " android:targetSdkVersion=\"33\" />"
+ )
+ )
+ }
}
diff --git a/build-system/integration-test/framework/src/main/java/com/android/build/gradle/integration/common/fixture/testprojects/prebuilts/privacysandbox/PrivacySandboxSdkTestProjects.kt b/build-system/integration-test/framework/src/main/java/com/android/build/gradle/integration/common/fixture/testprojects/prebuilts/privacysandbox/PrivacySandboxSdkTestProjects.kt
index ea21cc5..c507ce0 100644
--- a/build-system/integration-test/framework/src/main/java/com/android/build/gradle/integration/common/fixture/testprojects/prebuilts/privacysandbox/PrivacySandboxSdkTestProjects.kt
+++ b/build-system/integration-test/framework/src/main/java/com/android/build/gradle/integration/common/fixture/testprojects/prebuilts/privacysandbox/PrivacySandboxSdkTestProjects.kt
@@ -75,7 +75,7 @@
// language=xml
manifest = """
<manifest package="com.externaldex.externalaar" xmlns:android="http://schemas.android.com/apk/res/android">
- <uses-sdk android:targetSdkVersion="34" android:minSdkVersion="21" />
+ <uses-sdk android:minSdkVersion="21" />
<!-- Permission that needs to be removed before ASB packaging -->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
</manifest>