Merge "Remove sandbox support from SdkSandboxManagerCompat for Api 33 devices." into androidx-main
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatSandboxedTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatSandboxedTest.kt
index 2f31e22..1d50290 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatSandboxedTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatSandboxedTest.kt
@@ -22,14 +22,10 @@
import android.app.sdksandbox.SdkSandboxManager
import android.content.Context
import android.os.Binder
-import android.os.Build
import android.os.Bundle
import android.os.IBinder
import android.os.OutcomeReceiver
-import android.os.ext.SdkExtensions.AD_SERVICES
-import androidx.annotation.RequiresExtension
import androidx.privacysandbox.sdkruntime.client.loader.asTestSdk
-import androidx.privacysandbox.sdkruntime.core.AdServicesInfo
import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
import androidx.test.core.app.ApplicationProvider
import androidx.test.ext.junit.runners.AndroidJUnit4
@@ -39,8 +35,6 @@
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Assert.assertThrows
-import org.junit.Assume.assumeFalse
-import org.junit.Assume.assumeTrue
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
@@ -52,23 +46,19 @@
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
-import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.Mockito.`when`
import org.mockito.invocation.InvocationOnMock
@SmallTest
@RunWith(AndroidJUnit4::class)
// TODO(b/249982507) Test should be rewritten to use real SDK in sandbox instead of mocking manager
-// TODO(b/262577044) Remove RequiresExtension after extensions support in @SdkSuppress
-@RequiresExtension(extension = AD_SERVICES, version = 4)
-@SdkSuppress(minSdkVersion = Build.VERSION_CODES.TIRAMISU)
+@SdkSuppress(minSdkVersion = 34)
class SdkSandboxManagerCompatSandboxedTest {
private lateinit var mContext: Context
@Before
fun setUp() {
- assumeTrue("Requires Sandbox API available", isSandboxApiAvailable())
mContext = Mockito.spy(ApplicationProvider.getApplicationContext<Context>())
}
@@ -171,7 +161,6 @@
}
@Test
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE, codeName = "UpsideDownCake")
fun startSdkSandboxActivity_whenSandboxAvailable_delegateToPlatform() {
val sdkSandboxManager = mockSandboxManager(mContext)
val managerCompat = SdkSandboxManagerCompat.from(mContext)
@@ -222,43 +211,7 @@
}
@Test
- fun getSandboxedSdks_whenLoadedSdkListNotAvailable_dontDelegateToSandbox() {
- assumeFalse("Requires getSandboxedSdks API not available", isAtLeastV5())
-
- val sdkSandboxManager = mockSandboxManager(mContext)
- val managerCompat = SdkSandboxManagerCompat.from(mContext)
-
- managerCompat.getSandboxedSdks()
-
- verifyZeroInteractions(sdkSandboxManager)
- }
-
- @Test
- fun getSandboxedSdks_whenLoadedSdkListNotAvailable_returnsLocallyLoadedSdkList() {
- assumeFalse("Requires getSandboxedSdks API not available", isAtLeastV5())
-
- // SdkSandboxManagerCompat.from require SandboxManager available for AdServices version >= 4
- mockSandboxManager(mContext)
- val managerCompat = SdkSandboxManagerCompat.from(mContext)
-
- val localSdk = runBlocking {
- managerCompat.loadSdk(
- TestSdkConfigs.CURRENT.packageName,
- Bundle()
- )
- }
-
- val sandboxedSdks = managerCompat.getSandboxedSdks()
-
- assertThat(sandboxedSdks).containsExactly(localSdk)
- }
-
- @Test
- // TODO(b/262577044) Remove RequiresExtension after extensions support in @SdkSuppress
- @RequiresExtension(extension = AD_SERVICES, version = 5)
- fun getSandboxedSdks_whenLoadedSdkListAvailable_returnCombinedLocalAndPlatformResult() {
- assumeTrue("Requires getSandboxedSdks API available", isAtLeastV5())
-
+ fun getSandboxedSdks_whenSandboxAvailable_returnCombinedLocalAndPlatformResult() {
val sdkSandboxManager = mockSandboxManager(mContext)
val sandboxedSdk = SandboxedSdk(Binder())
`when`(sdkSandboxManager.sandboxedSdks)
@@ -279,11 +232,7 @@
}
@Test
- // TODO(b/262577044) Remove RequiresExtension after extensions support in @SdkSuppress
- @RequiresExtension(extension = AD_SERVICES, version = 5)
fun sdkController_getSandboxedSdks_dontIncludeSandboxedSdk() {
- assumeTrue("Requires getSandboxedSdks API available", isAtLeastV5())
-
val sdkSandboxManager = mockSandboxManager(mContext)
val sandboxedSdk = SandboxedSdk(Binder())
`when`(sdkSandboxManager.sandboxedSdks)
@@ -306,55 +255,46 @@
assertThat(result).isEqualTo(localSdk.getInterface())
}
- companion object SandboxApi {
+ private fun mockSandboxManager(spyContext: Context): SdkSandboxManager {
+ val sdkSandboxManager = mock(SdkSandboxManager::class.java)
+ `when`(spyContext.getSystemService(SdkSandboxManager::class.java))
+ .thenReturn(sdkSandboxManager)
+ return sdkSandboxManager
+ }
- private fun isSandboxApiAvailable() =
- AdServicesInfo.isAtLeastV4()
-
- private fun isAtLeastV5() =
- AdServicesInfo.isAtLeastV5()
-
- private fun mockSandboxManager(spyContext: Context): SdkSandboxManager {
- val sdkSandboxManager = mock(SdkSandboxManager::class.java)
- `when`(spyContext.getSystemService(SdkSandboxManager::class.java))
- .thenReturn(sdkSandboxManager)
- return sdkSandboxManager
+ private fun setupLoadSdkAnswer(
+ sdkSandboxManager: SdkSandboxManager,
+ sandboxedSdk: SandboxedSdk
+ ) {
+ val answer = { args: InvocationOnMock ->
+ val receiver = args.getArgument<OutcomeReceiver<SandboxedSdk, LoadSdkException>>(3)
+ receiver.onResult(sandboxedSdk)
+ null
}
+ doAnswer(answer)
+ .`when`(sdkSandboxManager).loadSdk(
+ any(),
+ any(),
+ any(),
+ any()
+ )
+ }
- private fun setupLoadSdkAnswer(
- sdkSandboxManager: SdkSandboxManager,
- sandboxedSdk: SandboxedSdk
- ) {
- val answer = { args: InvocationOnMock ->
- val receiver = args.getArgument<OutcomeReceiver<SandboxedSdk, LoadSdkException>>(3)
- receiver.onResult(sandboxedSdk)
- null
- }
- doAnswer(answer)
- .`when`(sdkSandboxManager).loadSdk(
- any(),
- any(),
- any(),
- any()
- )
+ private fun setupLoadSdkAnswer(
+ sdkSandboxManager: SdkSandboxManager,
+ loadSdkException: LoadSdkException
+ ) {
+ val answer = { args: InvocationOnMock ->
+ val receiver = args.getArgument<OutcomeReceiver<SandboxedSdk, LoadSdkException>>(3)
+ receiver.onError(loadSdkException)
+ null
}
-
- private fun setupLoadSdkAnswer(
- sdkSandboxManager: SdkSandboxManager,
- loadSdkException: LoadSdkException
- ) {
- val answer = { args: InvocationOnMock ->
- val receiver = args.getArgument<OutcomeReceiver<SandboxedSdk, LoadSdkException>>(3)
- receiver.onError(loadSdkException)
- null
- }
- doAnswer(answer)
- .`when`(sdkSandboxManager).loadSdk(
- any(),
- any(),
- any(),
- any()
- )
- }
+ doAnswer(answer)
+ .`when`(sdkSandboxManager).loadSdk(
+ any(),
+ any(),
+ any(),
+ any()
+ )
}
}
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatTest.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatTest.kt
index 5ee872d..81d35cf 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatTest.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/androidTest/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompatTest.kt
@@ -15,18 +15,15 @@
*/
package androidx.privacysandbox.sdkruntime.client
-import android.app.Activity
import android.content.Context
import android.content.ContextWrapper
import android.os.Binder
-import android.os.Build
import android.os.Bundle
import androidx.privacysandbox.sdkruntime.client.activity.LocalSdkActivityHandlerRegistry
import androidx.privacysandbox.sdkruntime.client.activity.SdkActivity
import androidx.privacysandbox.sdkruntime.client.loader.CatchingSdkActivityHandler
import androidx.privacysandbox.sdkruntime.client.loader.asTestSdk
import androidx.privacysandbox.sdkruntime.client.loader.extractSdkProviderFieldValue
-import androidx.privacysandbox.sdkruntime.core.AdServicesInfo
import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException
import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException.Companion.LOAD_SDK_INTERNAL_ERROR
import androidx.privacysandbox.sdkruntime.core.LoadSdkCompatException.Companion.LOAD_SDK_SDK_DEFINED_ERROR
@@ -41,13 +38,8 @@
import kotlinx.coroutines.runBlocking
import org.junit.After
import org.junit.Assert.assertThrows
-import org.junit.Assume.assumeTrue
import org.junit.Test
import org.junit.runner.RunWith
-import org.mockito.Mockito
-import org.mockito.Mockito.any
-import org.mockito.Mockito.spy
-import org.mockito.Mockito.verify
@SmallTest
@RunWith(AndroidJUnit4::class)
@@ -80,29 +72,8 @@
}
@Test
- // TODO(b/249982507) DexmakerMockitoInline requires P+. Rewrite to support P-
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.P)
- fun loadSdk_whenNoLocalSdkExistsAndSandboxNotAvailable_dontDelegateToSandbox() {
- // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
- assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
-
- val context = spy(ApplicationProvider.getApplicationContext<Context>())
- val managerCompat = SdkSandboxManagerCompat.from(context)
-
- assertThrows(LoadSdkCompatException::class.java) {
- runBlocking {
- managerCompat.loadSdk("sdk-not-exists", Bundle())
- }
- }
-
- verify(context, Mockito.never()).getSystemService(any())
- }
-
- @Test
- fun loadSdk_whenNoLocalSdkExistsAndSandboxNotAvailable_throwsSdkNotFoundException() {
- // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
- assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
-
+ @SdkSuppress(maxSdkVersion = 33)
+ fun loadSdk_whenNoLocalSdkExistsAndApiBelow34_throwsSdkNotFoundException() {
val context = ApplicationProvider.getApplicationContext<Context>()
val managerCompat = SdkSandboxManagerCompat.from(context)
@@ -203,18 +174,11 @@
}
@Test
- // TODO(b/249982507) DexmakerMockitoInline requires P+. Rewrite to support P-
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.P)
- fun unloadSdk_whenNoLocalSdkLoadedAndSandboxNotAvailable_dontDelegateToSandbox() {
- // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
- assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
-
- val context = spy(ApplicationProvider.getApplicationContext<Context>())
+ @SdkSuppress(maxSdkVersion = 33)
+ fun unloadSdk_whenNoLocalSdkLoadedAndApiBelow34_doesntThrow() {
+ val context = ApplicationProvider.getApplicationContext<Context>()
val managerCompat = SdkSandboxManagerCompat.from(context)
-
managerCompat.unloadSdk("sdk-not-loaded")
-
- verify(context, Mockito.never()).getSystemService(any())
}
@Test
@@ -268,13 +232,9 @@
}
@Test
- // TODO(b/249982507) DexmakerMockitoInline requires P+. Rewrite to support P-
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.P)
- fun addSdkSandboxProcessDeathCallback_whenSandboxNotAvailable_dontDelegateToSandbox() {
- // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
- assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
-
- val context = spy(ApplicationProvider.getApplicationContext<Context>())
+ @SdkSuppress(maxSdkVersion = 33)
+ fun addSdkSandboxProcessDeathCallback_whenApiBelow34_doesntThrow() {
+ val context = ApplicationProvider.getApplicationContext<Context>()
val managerCompat = SdkSandboxManagerCompat.from(context)
managerCompat.addSdkSandboxProcessDeathCallback(Runnable::run, object :
@@ -282,18 +242,12 @@
override fun onSdkSandboxDied() {
}
})
-
- verify(context, Mockito.never()).getSystemService(any())
}
@Test
- // TODO(b/249982507) DexmakerMockitoInline requires P+. Rewrite to support P-
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.P)
- fun removeSdkSandboxProcessDeathCallback_whenSandboxNotAvailable_dontDelegateToSandbox() {
- // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
- assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
-
- val context = spy(ApplicationProvider.getApplicationContext<Context>())
+ @SdkSuppress(maxSdkVersion = 33)
+ fun removeSdkSandboxProcessDeathCallback_whenApiBelow34_doesntThrow() {
+ val context = ApplicationProvider.getApplicationContext<Context>()
val managerCompat = SdkSandboxManagerCompat.from(context)
managerCompat.removeSdkSandboxProcessDeathCallback(object :
@@ -301,39 +255,37 @@
override fun onSdkSandboxDied() {
}
})
-
- verify(context, Mockito.never()).getSystemService(any())
}
@Test
- // TODO(b/249982507) DexmakerMockitoInline requires P+. Rewrite to support P-
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.P)
- fun getSandboxedSdks_whenSandboxNotAvailable_dontDelegateToSandbox() {
- // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
- assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
-
- val context = spy(ApplicationProvider.getApplicationContext<Context>())
+ @SdkSuppress(maxSdkVersion = 33)
+ fun getSandboxedSdks_whenApiBelow34_returnsLocallyLoadedSdkList() {
+ val context = ApplicationProvider.getApplicationContext<Context>()
val managerCompat = SdkSandboxManagerCompat.from(context)
- managerCompat.getSandboxedSdks()
+ val localSdk = runBlocking {
+ managerCompat.loadSdk(
+ TestSdkConfigs.CURRENT.packageName,
+ Bundle()
+ )
+ }
- verify(context, Mockito.never()).getSystemService(any())
+ val sandboxedSdks = managerCompat.getSandboxedSdks()
+
+ assertThat(sandboxedSdks).containsExactly(localSdk)
}
@Test
- // TODO(b/249982507) DexmakerMockitoInline requires P+. Rewrite to support P-
- @SdkSuppress(minSdkVersion = Build.VERSION_CODES.P)
- fun startSdkSandboxActivity_whenSandboxNotAvailable_dontDelegateToSandbox() {
- // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
- assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
-
- val context = spy(ApplicationProvider.getApplicationContext<Context>())
+ @SdkSuppress(maxSdkVersion = 33)
+ fun startSdkSandboxActivity_whenNoHandlerRegisteredAndApiBelow34_doesntThrow() {
+ val context = ApplicationProvider.getApplicationContext<Context>()
val managerCompat = SdkSandboxManagerCompat.from(context)
- val fromActivitySpy = Mockito.mock(Activity::class.java)
- managerCompat.startSdkSandboxActivity(fromActivitySpy, Binder())
-
- verify(context, Mockito.never()).getSystemService(any())
+ with(ActivityScenario.launch(EmptyActivity::class.java)) {
+ withActivity {
+ managerCompat.startSdkSandboxActivity(this, Binder())
+ }
+ }
}
@Test
@@ -392,27 +344,4 @@
anotherLocalSdk.getInterface(),
)
}
-
- @Test
- fun getSandboxedSdks_whenSandboxNotAvailable_returnsLocallyLoadedSdkList() {
- // TODO(b/262577044) Replace with @SdkSuppress after supporting maxExtensionVersion
- assumeTrue("Requires Sandbox API not available", isSandboxApiNotAvailable())
-
- val context = ApplicationProvider.getApplicationContext<Context>()
- val managerCompat = SdkSandboxManagerCompat.from(context)
-
- val localSdk = runBlocking {
- managerCompat.loadSdk(
- TestSdkConfigs.CURRENT.packageName,
- Bundle()
- )
- }
-
- val sandboxedSdks = managerCompat.getSandboxedSdks()
-
- assertThat(sandboxedSdks).containsExactly(localSdk)
- }
-
- private fun isSandboxApiNotAvailable() =
- !AdServicesInfo.isAtLeastV4()
}
diff --git a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt
index a3f2e01..59ee471 100644
--- a/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt
+++ b/privacysandbox/sdkruntime/sdkruntime-client/src/main/java/androidx/privacysandbox/sdkruntime/client/SdkSandboxManagerCompat.kt
@@ -24,10 +24,8 @@
import android.os.Build
import android.os.Bundle
import android.os.IBinder
-import android.os.ext.SdkExtensions.AD_SERVICES
import androidx.annotation.DoNotInline
import androidx.annotation.RequiresApi
-import androidx.annotation.RequiresExtension
import androidx.core.os.BuildCompat
import androidx.core.os.asOutcomeReceiver
import androidx.privacysandbox.sdkruntime.client.activity.LocalSdkActivityHandlerRegistry
@@ -290,14 +288,14 @@
)
@DoNotInline
- fun getSandboxedSdks(): List<SandboxedSdkCompat> = emptyList()
+ fun getSandboxedSdks(): List<SandboxedSdkCompat>
fun startSdkSandboxActivity(fromActivity: Activity, sdkActivityToken: IBinder)
}
- @RequiresApi(33)
- @RequiresExtension(extension = AD_SERVICES, version = 4)
- private open class ApiAdServicesV4Impl(context: Context) : PlatformApi {
+ @RequiresApi(34)
+ @SuppressLint("NewApi", "ClassVerificationFailure") // until updating checks to requires api 34
+ private open class Api34Impl(context: Context) : PlatformApi {
protected val sdkSandboxManager = context.getSystemService(
SdkSandboxManager::class.java
)
@@ -322,6 +320,12 @@
sdkSandboxManager.unloadSdk(sdkName)
}
+ override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
+ return sdkSandboxManager
+ .sandboxedSdks
+ .map { platformSdk -> SandboxedSdkCompat(platformSdk) }
+ }
+
@DoNotInline
override fun addSdkSandboxProcessDeathCallback(
callbackExecutor: Executor,
@@ -350,9 +354,7 @@
}
override fun startSdkSandboxActivity(fromActivity: Activity, sdkActivityToken: IBinder) {
- throw UnsupportedOperationException(
- "This API is only supported for devices run on Android U+"
- )
+ sdkSandboxManager.startSdkSandboxActivity(fromActivity, sdkActivityToken)
}
private suspend fun loadSdkInternal(
@@ -379,29 +381,6 @@
}
}
- @RequiresApi(33)
- @RequiresExtension(extension = AD_SERVICES, version = 5)
- private open class ApiAdServicesV5Impl(
- context: Context
- ) : ApiAdServicesV4Impl(context) {
- @DoNotInline
- override fun getSandboxedSdks(): List<SandboxedSdkCompat> {
- return sdkSandboxManager
- .sandboxedSdks
- .map { platformSdk -> SandboxedSdkCompat(platformSdk) }
- }
- }
-
- @RequiresExtension(extension = AD_SERVICES, version = 5)
- @RequiresApi(34)
- private class ApiAdServicesUDCImpl(
- context: Context
- ) : ApiAdServicesV5Impl(context) {
- override fun startSdkSandboxActivity(fromActivity: Activity, sdkActivityToken: IBinder) {
- sdkSandboxManager.startSdkSandboxActivity(fromActivity, sdkActivityToken)
- }
- }
-
private class FailImpl : PlatformApi {
@DoNotInline
override suspend fun loadSdk(
@@ -414,6 +393,8 @@
override fun unloadSdk(sdkName: String) {
}
+ override fun getSandboxedSdks(): List<SandboxedSdkCompat> = emptyList()
+
override fun addSdkSandboxProcessDeathCallback(
callbackExecutor: Executor,
callback: SdkSandboxProcessDeathCallbackCompat
@@ -474,14 +455,9 @@
}
private object PlatformApiFactory {
- @SuppressLint("NewApi", "ClassVerificationFailure")
fun create(context: Context): PlatformApi {
return if (Build.VERSION.SDK_INT >= 34 || AdServicesInfo.isDeveloperPreview()) {
- ApiAdServicesUDCImpl(context)
- } else if (AdServicesInfo.isAtLeastV5()) {
- ApiAdServicesV5Impl(context)
- } else if (AdServicesInfo.isAtLeastV4()) {
- ApiAdServicesV4Impl(context)
+ Api34Impl(context)
} else {
FailImpl()
}