Build current version of test-sdk from gradle project.
Bug: 275364149
Test: LocalSdkProviderTest
Change-Id: I08cf0c438cc6066fd04b6925f563f29fbab3d94c
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/build.gradle b/privacysandbox/sdkruntime/sdkruntime-client/build.gradle
index 704d543..3c7ef5e 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/build.gradle
+++ b/privacysandbox/sdkruntime/sdkruntime-client/build.gradle
@@ -15,6 +15,7 @@
*/
import androidx.build.LibraryType
+import javax.inject.Inject
plugins {
id("AndroidXPlugin")
@@ -22,6 +23,72 @@
id("org.jetbrains.kotlin.android")
}
+abstract class BundleTestSdkDexTask extends DefaultTask {
+
+ @InputFiles
+ @PathSensitive(PathSensitivity.NAME_ONLY)
+ abstract ConfigurableFileCollection getTestSdkApkFolders()
+
+ @OutputDirectory
+ abstract DirectoryProperty getOutputDir()
+
+ @Inject
+ abstract FileSystemOperations getFileSystemOperations()
+
+ @Inject
+ abstract ArchiveOperations getArchiveOperations()
+
+ @TaskAction
+ def exec() {
+ for (File folder : testSdkApkFolders.files) {
+ for (File file : folder.listFiles()) {
+ String fileName = file.name
+ if (!fileName.endsWith(".apk")) {
+ continue
+ }
+
+ int projectNameEnd = fileName.indexOf("-")
+ String projectName = projectNameEnd > 0 ? fileName.substring(0, projectNameEnd) : fileName
+
+ fileSystemOperations.copy {
+ from(archiveOperations.zipTree(file))
+ into(outputDir.dir("test-sdks/$projectName/"))
+ include('*.dex')
+ }
+ }
+ }
+ }
+}
+
+def bundleTestSdkDexTaskProvider = tasks.register("bundleTestSdkDexTask", BundleTestSdkDexTask) {
+ description("Bundle DEX from the androidTestBundleDex configuration into assets folder")
+
+ def configuration = configurations.getByName("androidTestBundleDex")
+ testSdkApkFolders.from(configuration.incoming.artifactView {}.files)
+}
+
+androidComponents {
+ onVariants(selector().withBuildType("debug")) {
+ androidTest.sources.assets.addGeneratedSourceDirectory(
+ bundleTestSdkDexTaskProvider,
+ BundleTestSdkDexTask::getOutputDir
+ )
+ }
+}
+
+configurations {
+ androidTestBundleDex {
+ canBeConsumed = false
+ canBeResolved = true
+ attributes {
+ attribute(
+ LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
+ objects.named(LibraryElements, "testSdkApk")
+ )
+ }
+ }
+}
+
dependencies {
api(libs.kotlinStdlib)
api(libs.kotlinCoroutinesCore)
@@ -48,6 +115,8 @@
androidTestImplementation(libs.mockitoCore, excludes.bytebuddy) // DexMaker has it"s own MockMaker
androidTestImplementation(libs.dexmakerMockitoInline, excludes.bytebuddy) // DexMaker has it"s own MockMaker
+
+ androidTestBundleDex(project(":privacysandbox:sdkruntime:test-sdks:current"))
}
android {
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkProviderTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkProviderTest.kt
index 4149ac0..09f256a 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkProviderTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/loader/LocalSdkProviderTest.kt
@@ -19,7 +19,6 @@
import android.os.Binder
import android.os.Bundle
import android.os.IBinder
-import android.view.View
import androidx.lifecycle.Lifecycle
import androidx.privacysandbox.sdkruntime.client.EmptyActivity
import androidx.privacysandbox.sdkruntime.client.TestActivityHolder
@@ -31,7 +30,6 @@
import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
import androidx.privacysandbox.sdkruntime.core.SandboxedSdkInfo
-import androidx.privacysandbox.sdkruntime.core.SandboxedSdkProviderCompat
import androidx.privacysandbox.sdkruntime.core.Versions
import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
@@ -227,60 +225,6 @@
assertThat(controller.sdkActivityHandlers[token]).isNull()
}
- class CurrentVersionProviderLoadTest : SandboxedSdkProviderCompat() {
- @JvmField
- var onLoadSdkBinder: Binder? = null
-
- @JvmField
- var lastOnLoadSdkParams: Bundle? = null
-
- @JvmField
- var isBeforeUnloadSdkCalled = false
-
- @Throws(LoadSdkCompatException::class)
- override fun onLoadSdk(params: Bundle): SandboxedSdkCompat {
- val result = CurrentVersionSdkTest(context!!)
- onLoadSdkBinder = result
-
- lastOnLoadSdkParams = params
- if (params.getBoolean("needFail", false)) {
- throw LoadSdkCompatException(RuntimeException(), params)
- }
- return SandboxedSdkCompat(result)
- }
-
- override fun beforeUnloadSdk() {
- isBeforeUnloadSdkCalled = true
- }
-
- override fun getView(
- windowContext: Context,
- params: Bundle,
- width: Int,
- height: Int
- ): View {
- return View(windowContext)
- }
- }
-
- @Suppress("unused") // Reflection calls
- internal class CurrentVersionSdkTest(
- private val context: Context
- ) : Binder() {
- fun getSandboxedSdks(): List<SandboxedSdkCompat> =
- SdkSandboxControllerCompat.from(context).getSandboxedSdks()
-
- fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
- SdkSandboxControllerCompat.from(context).getAppOwnedSdkSandboxInterfaces()
-
- fun registerSdkSandboxActivityHandler(handler: SdkSandboxActivityHandlerCompat): IBinder =
- SdkSandboxControllerCompat.from(context).registerSdkSandboxActivityHandler(handler)
-
- fun unregisterSdkSandboxActivityHandler(handler: SdkSandboxActivityHandlerCompat) {
- SdkSandboxControllerCompat.from(context).unregisterSdkSandboxActivityHandler(handler)
- }
- }
-
internal class TestClassLoaderFactory(
private val testStorage: TestLocalSdkStorage
) : SdkLoader.ClassLoaderFactory {
@@ -364,35 +308,23 @@
)
}
- // add SDK loaded from test sources
+ val currentVersionSdk = TestSdkInfo(
+ Versions.API_VERSION,
+ "test-sdks/current/classes.dex",
+ "androidx.privacysandbox.sdkruntime.testsdk.current.CompatProvider"
+ )
val controller = TestStubController()
+
+ val loadedSdk = loadTestSdkFromAssets(currentVersionSdk.localSdkConfig, controller)
+ assertThat(loadedSdk.extractApiVersion())
+ .isEqualTo(currentVersionSdk.apiVersion)
+
add(
arrayOf(
- "BuiltFromSource",
- Versions.API_VERSION,
+ currentVersionSdk.localSdkConfig.dexPaths[0],
+ currentVersionSdk.apiVersion,
controller,
- loadTestSdkFromSource(controller),
- )
- )
- }
-
- private fun loadTestSdkFromSource(controller: TestStubController): LocalSdkProvider {
- val sdkLoader = SdkLoader(
- object : SdkLoader.ClassLoaderFactory {
- override fun createClassLoaderFor(
- sdkConfig: LocalSdkConfig,
- parent: ClassLoader
- ): ClassLoader = javaClass.classLoader!!
- },
- ApplicationProvider.getApplicationContext(),
- controller
- )
-
- return sdkLoader.loadSdk(
- LocalSdkConfig(
- packageName = "test.CurrentVersionProviderLoadTest",
- dexPaths = emptyList(),
- entryPoint = CurrentVersionProviderLoadTest::class.java.name
+ loadedSdk
)
)
}
diff --git a/privacysandbox/sdkruntime/test-sdks/current/build.gradle b/privacysandbox/sdkruntime/test-sdks/current/build.gradle
new file mode 100644
index 0000000..c69ab15
--- /dev/null
+++ b/privacysandbox/sdkruntime/test-sdks/current/build.gradle
@@ -0,0 +1,56 @@
+/*
+ * 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.
+ */
+
+import com.android.build.api.artifact.SingleArtifact
+
+plugins {
+ id("AndroidXPlugin")
+ id("com.android.application")
+ id("org.jetbrains.kotlin.android")
+}
+
+android {
+ namespace "androidx.privacysandbox.sdkruntime.testsdk.current"
+}
+
+dependencies {
+ implementation(project(":privacysandbox:sdkruntime:sdkruntime-core"))
+}
+
+/*
+ * Allow integration tests to consume the APK produced by this project
+ */
+configurations {
+ testSdkApk {
+ canBeConsumed = true
+ canBeResolved = false
+ attributes {
+ attribute(
+ LibraryElements.LIBRARY_ELEMENTS_ATTRIBUTE,
+ objects.named(LibraryElements, "testSdkApk")
+ )
+ }
+ }
+}
+
+androidComponents {
+ beforeVariants(selector().all()) { enabled = buildType == 'release' }
+ onVariants(selector().all().withBuildType("release"), { variant ->
+ artifacts {
+ testSdkApk(variant.artifacts.get(SingleArtifact.APK.INSTANCE))
+ }
+ })
+}
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/test-sdks/current/src/main/AndroidManifest.xml b/privacysandbox/sdkruntime/test-sdks/current/src/main/AndroidManifest.xml
new file mode 100644
index 0000000..8de5974
--- /dev/null
+++ b/privacysandbox/sdkruntime/test-sdks/current/src/main/AndroidManifest.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright 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.
+ -->
+<manifest xmlns:android="http://schemas.android.com/apk/res/android">
+</manifest>
\ No newline at end of file
diff --git a/privacysandbox/sdkruntime/test-sdks/current/src/main/java/androidx/privacysandbox/sdkruntime/testsdk/current/CompatProvider.kt b/privacysandbox/sdkruntime/test-sdks/current/src/main/java/androidx/privacysandbox/sdkruntime/testsdk/current/CompatProvider.kt
new file mode 100644
index 0000000..03f31ea
--- /dev/null
+++ b/privacysandbox/sdkruntime/test-sdks/current/src/main/java/androidx/privacysandbox/sdkruntime/testsdk/current/CompatProvider.kt
@@ -0,0 +1,83 @@
+/*
+ * Copyright 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 androidx.privacysandbox.sdkruntime.testsdk.current
+
+import android.content.Context
+import android.os.Binder
+import android.os.Bundle
+import android.os.IBinder
+import android.view.View
+import androidx.privacysandbox.sdkruntime.core.AppOwnedSdkSandboxInterfaceCompat
+import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
+import androidx.privacysandbox.sdkruntime.core.SandboxedSdkCompat
+import androidx.privacysandbox.sdkruntime.core.SandboxedSdkProviderCompat
+import androidx.privacysandbox.sdkruntime.core.activity.SdkSandboxActivityHandlerCompat
+import androidx.privacysandbox.sdkruntime.core.controller.SdkSandboxControllerCompat
+
+@Suppress("unused") // Reflection usage from tests in privacysandbox:sdkruntime:sdkruntime-client
+class CompatProvider : SandboxedSdkProviderCompat() {
+ @JvmField
+ var onLoadSdkBinder: Binder? = null
+
+ @JvmField
+ var lastOnLoadSdkParams: Bundle? = null
+
+ @JvmField
+ var isBeforeUnloadSdkCalled = false
+
+ @Throws(LoadSdkCompatException::class)
+ override fun onLoadSdk(params: Bundle): SandboxedSdkCompat {
+ val result = CurrentVersionSdkTest(context!!)
+ onLoadSdkBinder = result
+
+ lastOnLoadSdkParams = params
+ if (params.getBoolean("needFail", false)) {
+ throw LoadSdkCompatException(RuntimeException(), params)
+ }
+ return SandboxedSdkCompat(result)
+ }
+
+ override fun beforeUnloadSdk() {
+ isBeforeUnloadSdkCalled = true
+ }
+
+ override fun getView(
+ windowContext: Context,
+ params: Bundle,
+ width: Int,
+ height: Int
+ ): View {
+ return View(windowContext)
+ }
+
+ internal class CurrentVersionSdkTest(
+ private val context: Context
+ ) : Binder() {
+ fun getSandboxedSdks(): List<SandboxedSdkCompat> =
+ SdkSandboxControllerCompat.from(context).getSandboxedSdks()
+
+ fun getAppOwnedSdkSandboxInterfaces(): List<AppOwnedSdkSandboxInterfaceCompat> =
+ SdkSandboxControllerCompat.from(context).getAppOwnedSdkSandboxInterfaces()
+
+ fun registerSdkSandboxActivityHandler(handler: SdkSandboxActivityHandlerCompat): IBinder =
+ SdkSandboxControllerCompat.from(context).registerSdkSandboxActivityHandler(handler)
+
+ fun unregisterSdkSandboxActivityHandler(handler: SdkSandboxActivityHandlerCompat) {
+ SdkSandboxControllerCompat.from(context).unregisterSdkSandboxActivityHandler(handler)
+ }
+ }
+}
diff --git a/settings.gradle b/settings.gradle
index 34dec2f..5e4699c 100644
--- a/settings.gradle
+++ b/settings.gradle
@@ -906,6 +906,7 @@
includeProject(":privacysandbox:plugins:plugins-privacysandbox-library", [BuildType.MAIN])
includeProject(":privacysandbox:sdkruntime:sdkruntime-client", [BuildType.MAIN])
includeProject(":privacysandbox:sdkruntime:sdkruntime-core", [BuildType.MAIN])
+includeProject(":privacysandbox:sdkruntime:test-sdks:current", [BuildType.MAIN])
includeProject(":privacysandbox:tools:tools", [BuildType.MAIN])
includeProject(":privacysandbox:tools:tools-apicompiler", [BuildType.MAIN])
includeProject(":privacysandbox:tools:tools-apigenerator", [BuildType.MAIN])