From 3d6ad935c8e881295be5b6fe9e91bcb19e1b99a5 Mon Sep 17 00:00:00 2001 From: Dave Snabel-Caunt Date: Wed, 14 Aug 2024 21:36:13 +0100 Subject: [PATCH 1/8] EUID Support --- dev-app/src/main/AndroidManifest.xml | 3 + .../main/java/com/uid2/dev/DevApplication.kt | 26 +++- .../main/java/com/uid2/dev/MainActivity.kt | 13 +- .../com/uid2/dev/network/AppUID2Client.kt | 18 +-- .../com/uid2/dev/ui/MainScreenViewModel.kt | 23 +++- .../main/java/com/uid2/dev/utils/BundleEx.kt | 7 + .../main/java/com/uid2/dev/utils/ContextEx.kt | 10 ++ .../com/uid2/dev/utils/PackageManagerEx.kt | 13 ++ dev-app/src/main/res/values/strings.xml | 1 + sdk/src/main/java/com/uid2/EUIDManager.kt | 122 ++++++++++++++++++ sdk/src/main/java/com/uid2/UID2Manager.kt | 95 +++++++++++++- .../com/uid2/storage/FileStorageManager.kt | 10 +- .../java/com/uid2/storage/StorageManager.kt | 12 -- .../src/main/AndroidManifest.xml | 3 + .../java/com/uid2/dev/BannerActivity.java | 11 +- .../java/com/uid2/dev/GMADevApplication.kt | 20 ++- .../main/java/com/uid2/dev/utils/BundleEx.kt | 7 + .../main/java/com/uid2/dev/utils/ContextEx.kt | 10 ++ .../com/uid2/dev/utils/PackageManagerEx.kt | 13 ++ .../securesignals/gma/EUIDMediationAdapter.kt | 76 +++++++++++ .../securesignals/gma/UID2MediationAdapter.kt | 3 +- .../gma/EUIDMediationAdapterTest.kt | 29 +++++ .../src/main/AndroidManifest.xml | 4 + .../java/com/uid2/dev/IMADevApplication.kt | 20 ++- .../main/java/com/uid2/dev/MainActivity.java | 10 +- .../main/java/com/uid2/dev/utils/BundleEx.kt | 7 + .../main/java/com/uid2/dev/utils/ContextEx.kt | 10 ++ .../com/uid2/dev/utils/PackageManagerEx.kt | 13 ++ .../ima/EUIDSecureSignalsAdapter.kt | 70 ++++++++++ .../ima/UID2SecureSignalsAdapter.kt | 3 +- .../ima/EUIDSecureSignalsAdapterTest.kt | 29 +++++ 31 files changed, 630 insertions(+), 61 deletions(-) create mode 100644 dev-app/src/main/java/com/uid2/dev/utils/BundleEx.kt create mode 100644 dev-app/src/main/java/com/uid2/dev/utils/ContextEx.kt create mode 100644 dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt create mode 100644 sdk/src/main/java/com/uid2/EUIDManager.kt create mode 100644 securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/BundleEx.kt create mode 100644 securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/ContextEx.kt create mode 100644 securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt create mode 100644 securesignals-gma/src/main/java/com/uid2/securesignals/gma/EUIDMediationAdapter.kt create mode 100644 securesignals-gma/src/test/java/com/uid2/securesignals/gma/EUIDMediationAdapterTest.kt create mode 100644 securesignals-ima-dev-app/src/main/java/com/uid2/dev/utils/BundleEx.kt create mode 100644 securesignals-ima-dev-app/src/main/java/com/uid2/dev/utils/ContextEx.kt create mode 100644 securesignals-ima-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt create mode 100644 securesignals-ima/src/main/java/com/uid2/securesignals/ima/EUIDSecureSignalsAdapter.kt create mode 100644 securesignals-ima/src/test/java/com/uid2/securesignals/ima/EUIDSecureSignalsAdapterTest.kt diff --git a/dev-app/src/main/AndroidManifest.xml b/dev-app/src/main/AndroidManifest.xml index d9659a6..d5e389a 100644 --- a/dev-app/src/main/AndroidManifest.xml +++ b/dev-app/src/main/AndroidManifest.xml @@ -18,6 +18,9 @@ + + + diff --git a/dev-app/src/main/java/com/uid2/dev/DevApplication.kt b/dev-app/src/main/java/com/uid2/dev/DevApplication.kt index 703509b..887ee81 100644 --- a/dev-app/src/main/java/com/uid2/dev/DevApplication.kt +++ b/dev-app/src/main/java/com/uid2/dev/DevApplication.kt @@ -3,7 +3,10 @@ package com.uid2.dev import android.app.Application import android.os.StrictMode import android.util.Log +import com.uid2.EUIDManager import com.uid2.UID2Manager +import com.uid2.dev.utils.getMetadata +import com.uid2.dev.utils.isEnvironmentEUID import com.uid2.prebid.UID2Prebid import org.prebid.mobile.PrebidMobile @@ -13,16 +16,32 @@ class DevApplication : Application() { override fun onCreate() { super.onCreate() + val isEnvironmentEUID = getMetadata().isEnvironmentEUID() + // Initialise the UID2Manager class. We will use it's DefaultNetworkSession rather than providing our own // custom implementation. This can be done to allow wrapping something like OkHttp. - UID2Manager.init(context = this, serverUrl = INTEG_SERVER_URL, isLoggingEnabled = true) + if (isEnvironmentEUID) { + EUIDManager.init( + context = this, + EUIDManager.Environment.Custom(EUID_INTEG_SERVER_URL), + isLoggingEnabled = true, + ) + } else { + UID2Manager.init( + context = this, + UID2Manager.Environment.Custom(UID2_INTEG_SERVER_URL), + isLoggingEnabled = true, + ) + } // Alternatively, we could initialise the UID2Manager with our own custom NetworkSession... // UID2Manager.init(this, INTEG_SERVER_URL, OkNetworkSession(), true) // Create the Prebid integration and allow it to start observing the UID2Manager instance. PrebidMobile.initializeSdk(this) { Log.i(TAG, "Prebid: $it") } - prebid = UID2Prebid().apply { + prebid = UID2Prebid( + if (isEnvironmentEUID) EUIDManager.getInstance() else UID2Manager.getInstance(), + ).apply { initialize() } @@ -45,6 +64,7 @@ class DevApplication : Application() { private companion object { const val TAG = "DevApplication" - const val INTEG_SERVER_URL = "https://operator-integ.uidapi.com" + const val UID2_INTEG_SERVER_URL = "https://operator-integ.uidapi.com" + const val EUID_INTEG_SERVER_URL = "https://integ.euid.eu/v2" } } diff --git a/dev-app/src/main/java/com/uid2/dev/MainActivity.kt b/dev-app/src/main/java/com/uid2/dev/MainActivity.kt index 8738e11..ad74ba4 100644 --- a/dev-app/src/main/java/com/uid2/dev/MainActivity.kt +++ b/dev-app/src/main/java/com/uid2/dev/MainActivity.kt @@ -5,23 +5,34 @@ import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.viewModels import androidx.compose.material.MaterialTheme +import com.uid2.EUIDManager import com.uid2.UID2Manager import com.uid2.dev.network.AppUID2Client import com.uid2.dev.ui.MainScreen import com.uid2.dev.ui.MainScreenViewModel import com.uid2.dev.ui.MainScreenViewModelFactory +import com.uid2.dev.utils.getMetadata +import com.uid2.dev.utils.isEnvironmentEUID +import com.uid2.devapp.R class MainActivity : ComponentActivity() { private val viewModel: MainScreenViewModel by viewModels { + val isEUID = getMetadata().isEnvironmentEUID() MainScreenViewModelFactory( AppUID2Client.fromContext(baseContext), - UID2Manager.getInstance(), + if (isEUID) EUIDManager.getInstance() else UID2Manager.getInstance(), + isEUID, ) } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) + + if (getMetadata().isEnvironmentEUID()) { + setTitle(R.string.app_name_euid) + } + setContent { MaterialTheme { MainScreen(viewModel) diff --git a/dev-app/src/main/java/com/uid2/dev/network/AppUID2Client.kt b/dev-app/src/main/java/com/uid2/dev/network/AppUID2Client.kt index ecb9973..11bb8d5 100644 --- a/dev-app/src/main/java/com/uid2/dev/network/AppUID2Client.kt +++ b/dev-app/src/main/java/com/uid2/dev/network/AppUID2Client.kt @@ -1,12 +1,9 @@ package com.uid2.dev.network import android.content.Context -import android.content.pm.ApplicationInfo -import android.content.pm.PackageManager -import android.os.Build -import android.os.Bundle import android.util.Base64 import com.uid2.data.UID2Identity +import com.uid2.dev.utils.getMetadata import com.uid2.network.DataEnvelope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext @@ -191,18 +188,5 @@ class AppUID2Client( it.getString(UID2_API_SECRET_KEY, ""), ) } - - private fun Context.getMetadata(): Bundle = packageManager.getApplicationInfoCompat( - packageName, - PackageManager.GET_META_DATA, - ).metaData - - private fun PackageManager.getApplicationInfoCompat(packageName: String, flags: Int = 0): ApplicationInfo = - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(flags.toLong())) - } else { - @Suppress("DEPRECATION") - getApplicationInfo(packageName, flags) - } } } diff --git a/dev-app/src/main/java/com/uid2/dev/ui/MainScreenViewModel.kt b/dev-app/src/main/java/com/uid2/dev/ui/MainScreenViewModel.kt index cbb6351..4d2f5e6 100644 --- a/dev-app/src/main/java/com/uid2/dev/ui/MainScreenViewModel.kt +++ b/dev-app/src/main/java/com/uid2/dev/ui/MainScreenViewModel.kt @@ -51,11 +51,15 @@ sealed interface MainScreenState : ViewState { class MainScreenViewModel( private val api: AppUID2Client, private val manager: UID2Manager, + isEUID: Boolean, ) : BasicViewModel() { private val _viewState = MutableStateFlow(UserUpdatedState(null, NO_IDENTITY)) override val viewState: StateFlow = _viewState.asStateFlow() + private val subscriptionId: String = if (isEUID) SUBSCRIPTION_ID_EUID else SUBSCRIPTION_ID_UID2 + private val publicKey: String = if (isEUID) PUBLIC_KEY_EUID else PUBLIC_KEY_UID2 + init { // Observe the state of the UID2Manager and translate those into our own ViewState. This will happen when the // Identity is initial set, or refreshed, or reset. @@ -98,8 +102,8 @@ class MainScreenViewModel( // Generate the identity via Client Side Integration (client side token generation). manager.generateIdentity( IdentityRequest.Email(action.address), - SUBSCRIPTION_ID, - PUBLIC_KEY, + subscriptionId, + publicKey, onGenerateResult, ) } else { @@ -120,8 +124,8 @@ class MainScreenViewModel( // Generate the identity via Client Side Integration (client side token generation). manager.generateIdentity( IdentityRequest.Phone(action.number), - SUBSCRIPTION_ID, - PUBLIC_KEY, + subscriptionId, + publicKey, onGenerateResult, ) } else { @@ -149,19 +153,24 @@ class MainScreenViewModel( private companion object { const val TAG = "MainScreenViewModel" - const val SUBSCRIPTION_ID = "toPh8vgJgt" + const val SUBSCRIPTION_ID_UID2 = "toPh8vgJgt" + const val SUBSCRIPTION_ID_EUID = "w6yPQzN4dA" + + @Suppress("ktlint:standard:max-line-length") + const val PUBLIC_KEY_UID2 = "UID2-X-I-MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKAbPfOz7u25g1fL6riU7p2eeqhjmpALPeYoyjvZmZ1xM2NM8UeOmDZmCIBnKyRZ97pz5bMCjrs38WM22O7LJuw==" @Suppress("ktlint:standard:max-line-length") - const val PUBLIC_KEY = "UID2-X-I-MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEKAbPfOz7u25g1fL6riU7p2eeqhjmpALPeYoyjvZmZ1xM2NM8UeOmDZmCIBnKyRZ97pz5bMCjrs38WM22O7LJuw==" + const val PUBLIC_KEY_EUID = "EUID-X-I-MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEH/k7HYGuWhjhCo8nXgj/ypClo5kek7uRKvzCGwj04Y1eXOWmHDOLAQVCPquZdfVVezIpABNAl9zvsSEC7g+ZGg==" } } class MainScreenViewModelFactory( private val api: AppUID2Client, private val manager: UID2Manager, + private val isEUID: Boolean, ) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { - return MainScreenViewModel(api, manager) as T + return MainScreenViewModel(api, manager, isEUID) as T } } diff --git a/dev-app/src/main/java/com/uid2/dev/utils/BundleEx.kt b/dev-app/src/main/java/com/uid2/dev/utils/BundleEx.kt new file mode 100644 index 0000000..2a68700 --- /dev/null +++ b/dev-app/src/main/java/com/uid2/dev/utils/BundleEx.kt @@ -0,0 +1,7 @@ +package com.uid2.dev.utils + +import android.os.Bundle + +private const val UID2_ENVIRONMENT_EUID = "uid2_environment_euid" + +fun Bundle.isEnvironmentEUID(): Boolean = getBoolean(UID2_ENVIRONMENT_EUID, false) diff --git a/dev-app/src/main/java/com/uid2/dev/utils/ContextEx.kt b/dev-app/src/main/java/com/uid2/dev/utils/ContextEx.kt new file mode 100644 index 0000000..91eef6c --- /dev/null +++ b/dev-app/src/main/java/com/uid2/dev/utils/ContextEx.kt @@ -0,0 +1,10 @@ +package com.uid2.dev.utils + +import android.content.Context +import android.content.pm.PackageManager +import android.os.Bundle + +fun Context.getMetadata(): Bundle = packageManager.getApplicationInfoCompat( + packageName, + PackageManager.GET_META_DATA, +).metaData diff --git a/dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt b/dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt new file mode 100644 index 0000000..274d3bf --- /dev/null +++ b/dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt @@ -0,0 +1,13 @@ +package com.uid2.dev.utils + +import android.content.pm.ApplicationInfo +import android.content.pm.PackageManager +import android.os.Build + +fun PackageManager.getApplicationInfoCompat(packageName: String, flags: Int = 0): ApplicationInfo = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(flags.toLong())) + } else { + @Suppress("DEPRECATION") + getApplicationInfo(packageName, flags) + } diff --git a/dev-app/src/main/res/values/strings.xml b/dev-app/src/main/res/values/strings.xml index 71d8e9b..688f94d 100644 --- a/dev-app/src/main/res/values/strings.xml +++ b/dev-app/src/main/res/values/strings.xml @@ -1,5 +1,6 @@ UID2 SDK Dev App + EUID SDK Dev App Email Phone Number diff --git a/sdk/src/main/java/com/uid2/EUIDManager.kt b/sdk/src/main/java/com/uid2/EUIDManager.kt new file mode 100644 index 0000000..a5592eb --- /dev/null +++ b/sdk/src/main/java/com/uid2/EUIDManager.kt @@ -0,0 +1,122 @@ +package com.uid2 + +import android.content.Context +import com.uid2.UID2Manager.Companion.APPLICATION_ID_DEFAULT +import com.uid2.network.DefaultNetworkSession +import com.uid2.network.NetworkSession +import com.uid2.storage.FileStorageManager +import com.uid2.storage.FileStorageManager.Store.EUID +import com.uid2.storage.StorageManager +import com.uid2.utils.InputUtils +import com.uid2.utils.Logger +import com.uid2.utils.TimeUtils +import kotlinx.coroutines.Dispatchers + +public class EUIDManager private constructor() { + + public sealed interface Environment { + public val serverUrl: String + + /** + * AWS EU West 2 (London). + */ + public data object London : Environment { + override val serverUrl: String = EUID_API_URL_PRODUCTION + } + + /** + * The default Environment, equivalent to [London]. + */ + public data object Production : Environment { + override val serverUrl: String = EUID_API_URL_PRODUCTION + } + + /** + * An Environment with its own API endpoint, such as for integration testing. + */ + public data class Custom( + override val serverUrl: String, + ) : Environment + } + + public companion object { + + // The default API server. + internal const val EUID_API_URL_PRODUCTION = "https://prod.euid.eu/v2" + + private var serverUrl: String = EUID_API_URL_PRODUCTION + private var applicationId: String = APPLICATION_ID_DEFAULT + private var networkSession: NetworkSession = DefaultNetworkSession() + private var storageManager: StorageManager? = null + private var isLoggingEnabled: Boolean = false + + private var instance: UID2Manager? = null + + /** + * Initializes the class with the given [Context], along with a [NetworkSession] that will be responsible + * for making any required network calls. + * + * @param context The context to initialise from. This will be used to obtain the package's metadata to extract + * the API URL. + * @param environment The API Environment to use. + * @param networkSession A custom [NetworkSession] which can be used for making any required network calls. + * The default implementation supported by the SDK can be found as [DefaultNetworkSession]. + */ + @JvmStatic + @JvmOverloads + @Throws(InitializationException::class) + public fun init( + context: Context, + environment: Environment = Environment.Production, + networkSession: NetworkSession = DefaultNetworkSession(), + isLoggingEnabled: Boolean = false, + ) { + if (instance != null) { + throw InitializationException() + } + + this.serverUrl = environment.serverUrl + this.applicationId = context.packageName + this.networkSession = networkSession + this.storageManager = FileStorageManager(context.applicationContext, EUID) + this.isLoggingEnabled = isLoggingEnabled + } + + /** + * Returns True if the manager is already initialised, otherwise False. + */ + @JvmStatic + public fun isInitialized(): Boolean = instance != null + + /** + * Gets the current singleton instance of the manager. + * + * @throws InitializationException Thrown if the manager has not yet been initialised. + */ + @JvmStatic + public fun getInstance(): UID2Manager { + if (storageManager == null) { + throw InitializationException() + } + val storage = storageManager ?: throw InitializationException() + val logger = Logger(isLoggingEnabled) + + return instance ?: UID2Manager( + UID2Client( + apiUrl = serverUrl, + session = networkSession, + applicationId = applicationId, + logger = logger, + ), + storage, + TimeUtils, + InputUtils(), + Dispatchers.Default, + true, + logger, + ).apply { + instance = this + } + } + } +} diff --git a/sdk/src/main/java/com/uid2/UID2Manager.kt b/sdk/src/main/java/com/uid2/UID2Manager.kt index c5b3ed3..c8ac23a 100644 --- a/sdk/src/main/java/com/uid2/UID2Manager.kt +++ b/sdk/src/main/java/com/uid2/UID2Manager.kt @@ -24,6 +24,8 @@ import com.uid2.data.IdentityStatus.REFRESH_EXPIRED import com.uid2.data.UID2Identity import com.uid2.network.DefaultNetworkSession import com.uid2.network.NetworkSession +import com.uid2.storage.FileStorageManager +import com.uid2.storage.FileStorageManager.Store.UID2 import com.uid2.storage.StorageManager import com.uid2.utils.InputUtils import com.uid2.utils.Logger @@ -532,13 +534,67 @@ public class UID2Manager internal constructor( } } + public sealed interface Environment { + public val serverUrl: String + + /** + * AWS US East (Ohio). + */ + public data object Ohio : Environment { + override val serverUrl: String = "https://prod.uidapi.com" + } + + /** + * AWS US West (Oregon). + */ + public data object Oregon : Environment { + override val serverUrl: String = "https://usw.prod.uidapi.com" + } + + /** + * AWS Asia Pacific (Singapore). + */ + public data object Singapore : Environment { + override val serverUrl: String = "https://sg.prod.uidapi.com" + } + + /** + * AWS Asia Pacific (Sydney). + */ + public data object Sydney : Environment { + override val serverUrl: String = "https://au.prod.uidapi.com" + } + + /** + * AWS Asia Pacific (Tokyo). + */ + public data object Tokyo : Environment { + override val serverUrl: String = "https://jp.prod.uidapi.com" + } + + /** + * The default Environment, equivalent to [Ohio]. + */ + public data object Production : Environment { + override val serverUrl: String = UID2_API_URL_PRODUCTION + } + + /** + * An Environment with its own API endpoint, such as for integration testing. + */ + public data class Custom( + override val serverUrl: String, + ) : Environment + } + public companion object { + private const val TAG = "UID2Manager" // The default API server. - private const val UID2_API_URL_DEFAULT = "https://prod.uidapi.com" + internal const val UID2_API_URL_PRODUCTION = "https://prod.uidapi.com" - private const val APPLICATION_ID_DEFAULT = "unknown" + internal const val APPLICATION_ID_DEFAULT = "unknown" private const val PACKAGE_NOT_AVAILABLE = "Identity not available" private const val PACKAGE_AD_TOKEN_NOT_AVAILABLE = "advertising_token is not available or is not valid" @@ -557,7 +613,7 @@ public class UID2Manager internal constructor( // The additional time we will allow to pass before checking the expiration of the Identity. private const val EXPIRATION_CHECK_TOLERANCE_MS = 50 - private var serverUrl: String = UID2_API_URL_DEFAULT + private var serverUrl: String = UID2_API_URL_PRODUCTION private var applicationId: String = APPLICATION_ID_DEFAULT private var networkSession: NetworkSession = DefaultNetworkSession() private var storageManager: StorageManager? = null @@ -565,6 +621,33 @@ public class UID2Manager internal constructor( private var instance: UID2Manager? = null + /** + * Initializes the class with the given [Context], along with a [NetworkSession] that will be responsible + * for making any required network calls. + * + * @param context The context to initialise from. This will be used to obtain the package's metadata to extract + * the API URL. + * @param networkSession A custom [NetworkSession] which can be used for making any required network calls. + * The default implementation supported by the SDK can be found as [DefaultNetworkSession]. + */ + @JvmStatic + @JvmOverloads + @JvmName("initWithEnvironment") + @Throws(InitializationException::class) + @Deprecated( + message = "Initialize with a custom Environment rather than a serverUrl String", + replaceWith = ReplaceWith("initWithEnvironment(context, environment, networkSession, isLoggingEnabled)"), + level = DeprecationLevel.WARNING, + ) + public fun init( + context: Context, + serverUrl: String = UID2_API_URL_PRODUCTION, + networkSession: NetworkSession = DefaultNetworkSession(), + isLoggingEnabled: Boolean = false, + ) { + init(context, Environment.Custom(serverUrl), networkSession, isLoggingEnabled) + } + /** * Initializes the class with the given [Context], along with a [NetworkSession] that will be responsible * for making any required network calls. @@ -579,7 +662,7 @@ public class UID2Manager internal constructor( @Throws(InitializationException::class) public fun init( context: Context, - serverUrl: String = UID2_API_URL_DEFAULT, + environment: Environment = Environment.Production, networkSession: NetworkSession = DefaultNetworkSession(), isLoggingEnabled: Boolean = false, ) { @@ -587,10 +670,10 @@ public class UID2Manager internal constructor( throw InitializationException() } - this.serverUrl = serverUrl + this.serverUrl = environment.serverUrl this.applicationId = context.packageName this.networkSession = networkSession - this.storageManager = StorageManager.getInstance(context.applicationContext) + this.storageManager = FileStorageManager(context.applicationContext, UID2) this.isLoggingEnabled = isLoggingEnabled } diff --git a/sdk/src/main/java/com/uid2/storage/FileStorageManager.kt b/sdk/src/main/java/com/uid2/storage/FileStorageManager.kt index bbd07e7..f1b0246 100644 --- a/sdk/src/main/java/com/uid2/storage/FileStorageManager.kt +++ b/sdk/src/main/java/com/uid2/storage/FileStorageManager.kt @@ -18,6 +18,11 @@ internal class FileStorageManager( private val ioDispatcher: CoroutineDispatcher = Dispatchers.IO, ) : StorageManager { + enum class Store(val filename: String) { + UID2(UID2_FILE_IDENTITY), + EUID(EUID_FILE_IDENTITY), + } + // For storage, we use the parent filesDir which is part of the Application's internal storage. This internal // storage is sandboxed to prevent any other app, or even the user, from accessing it directly. We rely on Android // keeping this file secure. @@ -25,7 +30,7 @@ internal class FileStorageManager( // On Android 10+, this location is also likely encrypted. // // https://developer.android.com/training/data-storage/app-specific#internal-access-files - constructor(context: Context) : this({ File(context.filesDir, FILE_IDENTITY) }) + constructor(context: Context, store: Store) : this({ File(context.filesDir, store.filename) }) // This lazy value *should* only be requested on the ioDispatcher. private val identityFile: File by lazy { identityFileFactory() } @@ -59,7 +64,8 @@ internal class FileStorageManager( } private companion object { - const val FILE_IDENTITY = "uid2_identity.json" + const val UID2_FILE_IDENTITY = "uid2_identity.json" + const val EUID_FILE_IDENTITY = "euid_identity.json" const val KEY_STATUS = "identity_status" // The character set used for both reading and writing to the file. diff --git a/sdk/src/main/java/com/uid2/storage/StorageManager.kt b/sdk/src/main/java/com/uid2/storage/StorageManager.kt index b3c30ff..5ff4869 100644 --- a/sdk/src/main/java/com/uid2/storage/StorageManager.kt +++ b/sdk/src/main/java/com/uid2/storage/StorageManager.kt @@ -1,6 +1,5 @@ package com.uid2.storage -import android.content.Context import com.uid2.data.IdentityStatus import com.uid2.data.UID2Identity @@ -22,15 +21,4 @@ internal interface StorageManager { * Clears any previously stored data. */ suspend fun clear(): Boolean - - companion object { - private var instance: StorageManager? = null - - /** - * Gets the single instance of the FileStorageManager. - */ - fun getInstance(context: Context) = instance ?: FileStorageManager(context).apply { - instance = this - } - } } diff --git a/securesignals-gma-dev-app/src/main/AndroidManifest.xml b/securesignals-gma-dev-app/src/main/AndroidManifest.xml index e686ac6..47cd90c 100644 --- a/securesignals-gma-dev-app/src/main/AndroidManifest.xml +++ b/securesignals-gma-dev-app/src/main/AndroidManifest.xml @@ -13,6 +13,9 @@ android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-3940256099942544~3347511713"/> + + + diff --git a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/BannerActivity.java b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/BannerActivity.java index 6a3d3e8..d5e4d37 100644 --- a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/BannerActivity.java +++ b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/BannerActivity.java @@ -1,5 +1,8 @@ package com.uid2.dev; +import static com.uid2.dev.utils.BundleExKt.isEnvironmentEUID; +import static com.uid2.dev.utils.ContextExKt.getMetadata; + import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import android.util.Log; @@ -11,9 +14,9 @@ import com.google.android.gms.ads.RequestConfiguration; import com.google.android.gms.ads.initialization.InitializationStatus; import com.google.android.gms.ads.initialization.OnInitializationCompleteListener; +import com.uid2.EUIDManager; import com.uid2.UID2Manager; import com.uid2.data.UID2Identity; - import org.json.JSONObject; import java.io.BufferedReader; @@ -101,7 +104,11 @@ private void loadUID2Identity() { refreshFrom, refreshExpires, fromJsonIdentity.getRefreshResponseKey()); - UID2Manager.getInstance().setIdentity(identity); + if (isEnvironmentEUID(getMetadata(this))) { + EUIDManager.getInstance().setIdentity(identity); + } else { + UID2Manager.getInstance().setIdentity(identity); + } } catch (Exception e) { Log.e(TAG, "Error loading Identity: " + e); } diff --git a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/GMADevApplication.kt b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/GMADevApplication.kt index 0b19a17..fc9e774 100644 --- a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/GMADevApplication.kt +++ b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/GMADevApplication.kt @@ -2,7 +2,11 @@ package com.uid2.dev import android.app.Application import android.util.Log +import com.uid2.EUIDManager import com.uid2.UID2Manager +import com.uid2.UID2Manager.Environment.Production +import com.uid2.dev.utils.getMetadata +import com.uid2.dev.utils.isEnvironmentEUID class GMADevApplication : Application() { @@ -12,10 +16,18 @@ class GMADevApplication : Application() { // Initialise the UID2Manager class. We will use it's DefaultNetworkSession rather than providing our own // custom implementation. This can be done to allow wrapping something like OkHttp. try { - UID2Manager.init( - context = this, - isLoggingEnabled = true, - ) + if (getMetadata().isEnvironmentEUID()) { + UID2Manager.init( + context = this, + environment = Production, + isLoggingEnabled = true, + ) + } else { + EUIDManager.init( + context = this, + isLoggingEnabled = true, + ) + } } catch (ex: Exception) { Log.e("IMADevApplication", "Error initialising UID2Manager", ex) } diff --git a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/BundleEx.kt b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/BundleEx.kt new file mode 100644 index 0000000..2a68700 --- /dev/null +++ b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/BundleEx.kt @@ -0,0 +1,7 @@ +package com.uid2.dev.utils + +import android.os.Bundle + +private const val UID2_ENVIRONMENT_EUID = "uid2_environment_euid" + +fun Bundle.isEnvironmentEUID(): Boolean = getBoolean(UID2_ENVIRONMENT_EUID, false) diff --git a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/ContextEx.kt b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/ContextEx.kt new file mode 100644 index 0000000..91eef6c --- /dev/null +++ b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/ContextEx.kt @@ -0,0 +1,10 @@ +package com.uid2.dev.utils + +import android.content.Context +import android.content.pm.PackageManager +import android.os.Bundle + +fun Context.getMetadata(): Bundle = packageManager.getApplicationInfoCompat( + packageName, + PackageManager.GET_META_DATA, +).metaData diff --git a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt new file mode 100644 index 0000000..274d3bf --- /dev/null +++ b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt @@ -0,0 +1,13 @@ +package com.uid2.dev.utils + +import android.content.pm.ApplicationInfo +import android.content.pm.PackageManager +import android.os.Build + +fun PackageManager.getApplicationInfoCompat(packageName: String, flags: Int = 0): ApplicationInfo = + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(flags.toLong())) + } else { + @Suppress("DEPRECATION") + getApplicationInfo(packageName, flags) + } diff --git a/securesignals-gma/src/main/java/com/uid2/securesignals/gma/EUIDMediationAdapter.kt b/securesignals-gma/src/main/java/com/uid2/securesignals/gma/EUIDMediationAdapter.kt new file mode 100644 index 0000000..78e1e0f --- /dev/null +++ b/securesignals-gma/src/main/java/com/uid2/securesignals/gma/EUIDMediationAdapter.kt @@ -0,0 +1,76 @@ +package com.uid2.securesignals.gma + +import android.content.Context +import com.google.android.gms.ads.AdError +import com.google.android.gms.ads.mediation.InitializationCompleteCallback +import com.google.android.gms.ads.mediation.MediationConfiguration +import com.google.android.gms.ads.mediation.rtb.RtbAdapter +import com.google.android.gms.ads.mediation.rtb.RtbSignalData +import com.google.android.gms.ads.mediation.rtb.SignalCallbacks +import com.uid2.EUIDManager +import com.uid2.UID2 +import com.google.android.gms.ads.mediation.VersionInfo as GmaVersionInfo + +/** + * An implementation of Google's GMS RtbAdapter that integrates UID2 tokens, accessed via the UID2Manager. + */ +public class EUIDMediationAdapter : RtbAdapter() { + + /** + * Gets the version of the UID2 SDK. + */ + @Suppress("DEPRECATION") + public override fun getSDKVersionInfo(): GmaVersionInfo = UID2.getVersionInfo().let { + GmaVersionInfo(it.major, it.minor, it.patch) + } + + /** + * Gets the version of the UID2 Secure Signals plugin. + */ + @Suppress("DEPRECATION") + public override fun getVersionInfo(): GmaVersionInfo = PluginVersion.getVersionInfo().let { + GmaVersionInfo(it.major, it.minor, it.patch) + } + + /** + * Initialises the UID2 SDK with the given Context. + */ + override fun initialize( + context: Context, + initializationCompleteCallback: InitializationCompleteCallback, + mediationConfigurations: MutableList, + ) { + // It's possible that the UID2Manager is already initialised. If so, it's a no-op. + if (!EUIDManager.isInitialized()) { + EUIDManager.init(context) + } + + // After we've asked to initialize the manager, we should wait until it's complete before reporting success. + // This will potentially allow any previously persisted identity to be fully restored before we allow any + // signals to be collected. + EUIDManager.getInstance().addOnInitializedListener(initializationCompleteCallback::onInitializationSucceeded) + } + + /** + * Collects the UID2 advertising token, if available. + */ + override fun collectSignals(rtbSignalData: RtbSignalData, signalCallbacks: SignalCallbacks) { + EUIDManager.getInstance().let { manager -> + val token = manager.getAdvertisingToken() + if (token != null) { + signalCallbacks.onSuccess(token) + } else { + // We include the IdentityStatus in the "error" to have better visibility on why the Advertising Token + // was not present. There are a number of valid reasons why we don't have a token, but we are still + // required to report these as "failures". + signalCallbacks.onFailure( + AdError( + manager.currentIdentityStatus.value, + "No Advertising Token", + "UID2", + ), + ) + } + } + } +} diff --git a/securesignals-gma/src/main/java/com/uid2/securesignals/gma/UID2MediationAdapter.kt b/securesignals-gma/src/main/java/com/uid2/securesignals/gma/UID2MediationAdapter.kt index 8c085b2..2b0763b 100644 --- a/securesignals-gma/src/main/java/com/uid2/securesignals/gma/UID2MediationAdapter.kt +++ b/securesignals-gma/src/main/java/com/uid2/securesignals/gma/UID2MediationAdapter.kt @@ -9,6 +9,7 @@ import com.google.android.gms.ads.mediation.rtb.RtbSignalData import com.google.android.gms.ads.mediation.rtb.SignalCallbacks import com.uid2.UID2 import com.uid2.UID2Manager +import com.uid2.UID2Manager.Environment.Production import com.google.android.gms.ads.mediation.VersionInfo as GmaVersionInfo /** @@ -42,7 +43,7 @@ public class UID2MediationAdapter : RtbAdapter() { ) { // It's possible that the UID2Manager is already initialised. If so, it's a no-op. if (!UID2Manager.isInitialized()) { - UID2Manager.init(context) + UID2Manager.init(context, Production) } // After we've asked to initialize the manager, we should wait until it's complete before reporting success. diff --git a/securesignals-gma/src/test/java/com/uid2/securesignals/gma/EUIDMediationAdapterTest.kt b/securesignals-gma/src/test/java/com/uid2/securesignals/gma/EUIDMediationAdapterTest.kt new file mode 100644 index 0000000..edb1900 --- /dev/null +++ b/securesignals-gma/src/test/java/com/uid2/securesignals/gma/EUIDMediationAdapterTest.kt @@ -0,0 +1,29 @@ +package com.uid2.securesignals.gma + +import com.uid2.UID2 +import org.junit.Assert +import org.junit.Test + +class EUIDMediationAdapterTest { + @Test + fun `test SDK version`() { + val adapter = EUIDMediationAdapter() + val version = adapter.versionInfo + val expectedVersion = UID2.getVersionInfo() + + Assert.assertEquals(expectedVersion.major, version.majorVersion) + Assert.assertEquals(expectedVersion.minor, version.minorVersion) + Assert.assertEquals(expectedVersion.patch, version.microVersion) + } + + @Test + fun `test plugin version`() { + val adapter = EUIDMediationAdapter() + val version = adapter.sdkVersionInfo + val expectedVersion = PluginVersion.getVersionInfo() + + Assert.assertEquals(expectedVersion.major, version.majorVersion) + Assert.assertEquals(expectedVersion.minor, version.minorVersion) + Assert.assertEquals(expectedVersion.patch, version.microVersion) + } +} diff --git a/securesignals-ima-dev-app/src/main/AndroidManifest.xml b/securesignals-ima-dev-app/src/main/AndroidManifest.xml index 27109a8..1f8fe39 100644 --- a/securesignals-ima-dev-app/src/main/AndroidManifest.xml +++ b/securesignals-ima-dev-app/src/main/AndroidManifest.xml @@ -10,6 +10,10 @@ android:label="@string/app_name" android:allowBackup="true" android:icon="@drawable/ic_launcher"> + + + + = Build.VERSION_CODES.TIRAMISU) { + getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(flags.toLong())) + } else { + @Suppress("DEPRECATION") + getApplicationInfo(packageName, flags) + } diff --git a/securesignals-ima/src/main/java/com/uid2/securesignals/ima/EUIDSecureSignalsAdapter.kt b/securesignals-ima/src/main/java/com/uid2/securesignals/ima/EUIDSecureSignalsAdapter.kt new file mode 100644 index 0000000..46c1eff --- /dev/null +++ b/securesignals-ima/src/main/java/com/uid2/securesignals/ima/EUIDSecureSignalsAdapter.kt @@ -0,0 +1,70 @@ +package com.uid2.securesignals.ima + +import android.content.Context +import com.google.ads.interactivemedia.v3.api.VersionInfo +import com.google.ads.interactivemedia.v3.api.signals.SecureSignalsAdapter +import com.google.ads.interactivemedia.v3.api.signals.SecureSignalsCollectSignalsCallback +import com.google.ads.interactivemedia.v3.api.signals.SecureSignalsInitializeCallback +import com.uid2.EUIDManager +import com.uid2.UID2 + +/** + * A custom exception type that is used to report failures from the EUIDSecureSignalsAdapter when an error has occurred. + */ +public class EUIDSecureSignalsException(message: String? = null, cause: Throwable? = null) : Exception(message, cause) + +/** + * An implementation of Google's IMA SecureSignalsAdapter that integrates UID2 tokens, accessed via the UID2Manager. + */ +public class EUIDSecureSignalsAdapter : SecureSignalsAdapter { + + /** + * Gets the version of the UID2 SDK. + */ + public override fun getSDKVersion(): VersionInfo = UID2.getVersionInfo().let { + VersionInfo(it.major, it.minor, it.patch) + } + + /** + * Gets the version of the UID2 Secure Signals plugin. + */ + public override fun getVersion(): VersionInfo = PluginVersion.getVersionInfo().let { + VersionInfo(it.major, it.minor, it.patch) + } + + /** + * Initialises the UID2 SDK with the given Context. + */ + public override fun initialize(context: Context, callback: SecureSignalsInitializeCallback) { + // It's possible that the EUIDManager is already initialised. If so, it's a no-op. + if (!EUIDManager.isInitialized()) { + EUIDManager.init(context) + } + + // After we've asked to initialize the manager, we should wait until it's complete before reporting success. + // This will potentially allow any previously persisted identity to be fully restored before we allow any + // signals to be collected. + EUIDManager.getInstance().addOnInitializedListener(callback::onSuccess) + } + + /** + * Collects the UID2 advertising token, if available. + */ + public override fun collectSignals(context: Context, callback: SecureSignalsCollectSignalsCallback) { + EUIDManager.getInstance().let { manager -> + val token = manager.getAdvertisingToken() + if (token != null) { + callback.onSuccess(token) + } else { + // We include the IdentityStatus in the "error" to have better visibility on why the Advertising Token + // was not present. There are a number of valid reasons why we don't have a token, but we are still + // required to report these as "failures". + callback.onFailure( + EUIDSecureSignalsException( + "No Advertising Token available (Status: ${manager.currentIdentityStatus.value})", + ), + ) + } + } + } +} diff --git a/securesignals-ima/src/main/java/com/uid2/securesignals/ima/UID2SecureSignalsAdapter.kt b/securesignals-ima/src/main/java/com/uid2/securesignals/ima/UID2SecureSignalsAdapter.kt index dcdc8c2..76e739f 100644 --- a/securesignals-ima/src/main/java/com/uid2/securesignals/ima/UID2SecureSignalsAdapter.kt +++ b/securesignals-ima/src/main/java/com/uid2/securesignals/ima/UID2SecureSignalsAdapter.kt @@ -7,6 +7,7 @@ import com.google.ads.interactivemedia.v3.api.signals.SecureSignalsCollectSignal import com.google.ads.interactivemedia.v3.api.signals.SecureSignalsInitializeCallback import com.uid2.UID2 import com.uid2.UID2Manager +import com.uid2.UID2Manager.Environment.Production /** * A custom exception type that is used to report failures from the UID2SecureSignalsAdapter when an error has occurred. @@ -38,7 +39,7 @@ public class UID2SecureSignalsAdapter : SecureSignalsAdapter { public override fun initialize(context: Context, callback: SecureSignalsInitializeCallback) { // It's possible that the UID2Manager is already initialised. If so, it's a no-op. if (!UID2Manager.isInitialized()) { - UID2Manager.init(context) + UID2Manager.init(context, environment = Production) } // After we've asked to initialize the manager, we should wait until it's complete before reporting success. diff --git a/securesignals-ima/src/test/java/com/uid2/securesignals/ima/EUIDSecureSignalsAdapterTest.kt b/securesignals-ima/src/test/java/com/uid2/securesignals/ima/EUIDSecureSignalsAdapterTest.kt new file mode 100644 index 0000000..2f2125e --- /dev/null +++ b/securesignals-ima/src/test/java/com/uid2/securesignals/ima/EUIDSecureSignalsAdapterTest.kt @@ -0,0 +1,29 @@ +package com.uid2.securesignals.ima + +import com.uid2.UID2 +import org.junit.Assert.assertEquals +import org.junit.Test + +class EUIDSecureSignalsAdapterTest { + @Test + fun `test SDK version`() { + val adapter = UID2SecureSignalsAdapter() + val version = adapter.sdkVersion + val expectedVersion = UID2.getVersionInfo() + + assertEquals(expectedVersion.major, version.majorVersion) + assertEquals(expectedVersion.minor, version.minorVersion) + assertEquals(expectedVersion.patch, version.microVersion) + } + + @Test + fun `test plugin version`() { + val adapter = UID2SecureSignalsAdapter() + val version = adapter.version + val expectedVersion = PluginVersion.getVersionInfo() + + assertEquals(expectedVersion.major, version.majorVersion) + assertEquals(expectedVersion.minor, version.minorVersion) + assertEquals(expectedVersion.patch, version.microVersion) + } +} From d8df68eb18f0ceb076d9d374c5801dee74dd1b7d Mon Sep 17 00:00:00 2001 From: Dave Snabel-Caunt Date: Wed, 28 Aug 2024 09:06:34 +0100 Subject: [PATCH 2/8] Make EUIDManager an object --- sdk/src/main/java/com/uid2/EUIDManager.kt | 141 +++++++++++----------- 1 file changed, 69 insertions(+), 72 deletions(-) diff --git a/sdk/src/main/java/com/uid2/EUIDManager.kt b/sdk/src/main/java/com/uid2/EUIDManager.kt index a5592eb..10c8559 100644 --- a/sdk/src/main/java/com/uid2/EUIDManager.kt +++ b/sdk/src/main/java/com/uid2/EUIDManager.kt @@ -12,7 +12,7 @@ import com.uid2.utils.Logger import com.uid2.utils.TimeUtils import kotlinx.coroutines.Dispatchers -public class EUIDManager private constructor() { +public object EUIDManager { public sealed interface Environment { public val serverUrl: String @@ -39,84 +39,81 @@ public class EUIDManager private constructor() { ) : Environment } - public companion object { + // The default API server. + internal const val EUID_API_URL_PRODUCTION = "https://prod.euid.eu/v2" - // The default API server. - internal const val EUID_API_URL_PRODUCTION = "https://prod.euid.eu/v2" + private var serverUrl: String = EUID_API_URL_PRODUCTION + private var applicationId: String = APPLICATION_ID_DEFAULT + private var networkSession: NetworkSession = DefaultNetworkSession() + private var storageManager: StorageManager? = null + private var isLoggingEnabled: Boolean = false - private var serverUrl: String = EUID_API_URL_PRODUCTION - private var applicationId: String = APPLICATION_ID_DEFAULT - private var networkSession: NetworkSession = DefaultNetworkSession() - private var storageManager: StorageManager? = null - private var isLoggingEnabled: Boolean = false + private var instance: UID2Manager? = null - private var instance: UID2Manager? = null - - /** - * Initializes the class with the given [Context], along with a [NetworkSession] that will be responsible - * for making any required network calls. - * - * @param context The context to initialise from. This will be used to obtain the package's metadata to extract - * the API URL. - * @param environment The API Environment to use. - * @param networkSession A custom [NetworkSession] which can be used for making any required network calls. - * The default implementation supported by the SDK can be found as [DefaultNetworkSession]. - */ - @JvmStatic - @JvmOverloads - @Throws(InitializationException::class) - public fun init( - context: Context, - environment: Environment = Environment.Production, - networkSession: NetworkSession = DefaultNetworkSession(), - isLoggingEnabled: Boolean = false, - ) { - if (instance != null) { - throw InitializationException() - } - - this.serverUrl = environment.serverUrl - this.applicationId = context.packageName - this.networkSession = networkSession - this.storageManager = FileStorageManager(context.applicationContext, EUID) - this.isLoggingEnabled = isLoggingEnabled + /** + * Initializes the class with the given [Context], along with a [NetworkSession] that will be responsible + * for making any required network calls. + * + * @param context The context to initialise from. This will be used to obtain the package's metadata to extract + * the API URL. + * @param environment The API Environment to use. + * @param networkSession A custom [NetworkSession] which can be used for making any required network calls. + * The default implementation supported by the SDK can be found as [DefaultNetworkSession]. + */ + @JvmStatic + @JvmOverloads + @Throws(InitializationException::class) + public fun init( + context: Context, + environment: Environment = Environment.Production, + networkSession: NetworkSession = DefaultNetworkSession(), + isLoggingEnabled: Boolean = false, + ) { + if (instance != null) { + throw InitializationException() } - /** - * Returns True if the manager is already initialised, otherwise False. - */ - @JvmStatic - public fun isInitialized(): Boolean = instance != null + this.serverUrl = environment.serverUrl + this.applicationId = context.packageName + this.networkSession = networkSession + this.storageManager = FileStorageManager(context.applicationContext, EUID) + this.isLoggingEnabled = isLoggingEnabled + } - /** - * Gets the current singleton instance of the manager. - * - * @throws InitializationException Thrown if the manager has not yet been initialised. - */ - @JvmStatic - public fun getInstance(): UID2Manager { - if (storageManager == null) { - throw InitializationException() - } - val storage = storageManager ?: throw InitializationException() - val logger = Logger(isLoggingEnabled) + /** + * Returns True if the manager is already initialised, otherwise False. + */ + @JvmStatic + public fun isInitialized(): Boolean = instance != null + + /** + * Gets the current singleton instance of the manager. + * + * @throws InitializationException Thrown if the manager has not yet been initialised. + */ + @JvmStatic + public fun getInstance(): UID2Manager { + if (storageManager == null) { + throw InitializationException() + } + val storage = storageManager ?: throw InitializationException() + val logger = Logger(isLoggingEnabled) - return instance ?: UID2Manager( - UID2Client( - apiUrl = serverUrl, - session = networkSession, - applicationId = applicationId, - logger = logger, - ), - storage, - TimeUtils, - InputUtils(), - Dispatchers.Default, - true, - logger, - ).apply { - instance = this - } + return instance ?: UID2Manager( + UID2Client( + apiUrl = serverUrl, + session = networkSession, + applicationId = applicationId, + logger = logger, + ), + storage, + TimeUtils, + InputUtils(), + Dispatchers.Default, + true, + logger, + ).apply { + instance = this } } } From a67cd9977124e248a9d6f264dc151125018516a1 Mon Sep 17 00:00:00 2001 From: Dave Snabel-Caunt Date: Tue, 3 Sep 2024 22:17:06 +0100 Subject: [PATCH 3/8] Fix inverted EUID/UID2 manager initialization --- .../src/main/java/com/uid2/dev/GMADevApplication.kt | 6 +++--- .../src/main/java/com/uid2/dev/IMADevApplication.kt | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/GMADevApplication.kt b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/GMADevApplication.kt index fc9e774..f2791c4 100644 --- a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/GMADevApplication.kt +++ b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/GMADevApplication.kt @@ -17,14 +17,14 @@ class GMADevApplication : Application() { // custom implementation. This can be done to allow wrapping something like OkHttp. try { if (getMetadata().isEnvironmentEUID()) { - UID2Manager.init( + EUIDManager.init( context = this, - environment = Production, isLoggingEnabled = true, ) } else { - EUIDManager.init( + UID2Manager.init( context = this, + environment = Production, isLoggingEnabled = true, ) } diff --git a/securesignals-ima-dev-app/src/main/java/com/uid2/dev/IMADevApplication.kt b/securesignals-ima-dev-app/src/main/java/com/uid2/dev/IMADevApplication.kt index d5e3958..a8a4417 100644 --- a/securesignals-ima-dev-app/src/main/java/com/uid2/dev/IMADevApplication.kt +++ b/securesignals-ima-dev-app/src/main/java/com/uid2/dev/IMADevApplication.kt @@ -17,14 +17,14 @@ class IMADevApplication : Application() { // custom implementation. This can be done to allow wrapping something like OkHttp. try { if (baseContext.getMetadata().isEnvironmentEUID()) { - UID2Manager.init( + EUIDManager.init( context = this, - environment = Production, isLoggingEnabled = true, ) } else { - EUIDManager.init( + UID2Manager.init( context = this, + environment = Production, isLoggingEnabled = true, ) } From 1281de38f9cea46addc4d2e8d50cda2e1558ff7f Mon Sep 17 00:00:00 2001 From: Dave Snabel-Caunt Date: Wed, 4 Sep 2024 16:50:36 +0100 Subject: [PATCH 4/8] Add/update lint baselines --- dev-app/lint-baseline.xml | 10 +++++----- securesignals-gma-dev-app/build.gradle | 1 + securesignals-gma-dev-app/lint-baseline.xml | 13 ++++++++++++- securesignals-ima-dev-app/build.gradle | 1 + securesignals-ima-dev-app/lint-baseline.xml | 13 ++++++++++++- 5 files changed, 31 insertions(+), 7 deletions(-) diff --git a/dev-app/lint-baseline.xml b/dev-app/lint-baseline.xml index eea8e2a..f71c200 100644 --- a/dev-app/lint-baseline.xml +++ b/dev-app/lint-baseline.xml @@ -4,12 +4,12 @@ + errorLine1=" getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(flags.toLong()))" + errorLine2=" ~~~~~~~~~~~~~~"> + file="src/main/java/com/uid2/dev/utils/PackageManagerEx.kt" + line="9" + column="80"/> diff --git a/securesignals-gma-dev-app/build.gradle b/securesignals-gma-dev-app/build.gradle index 8852cd3..de31c02 100644 --- a/securesignals-gma-dev-app/build.gradle +++ b/securesignals-gma-dev-app/build.gradle @@ -23,6 +23,7 @@ android { } lint { + baseline = file("lint-baseline.xml") disable 'GradleDependency' } diff --git a/securesignals-gma-dev-app/lint-baseline.xml b/securesignals-gma-dev-app/lint-baseline.xml index f418c4a..f71c200 100644 --- a/securesignals-gma-dev-app/lint-baseline.xml +++ b/securesignals-gma-dev-app/lint-baseline.xml @@ -1,4 +1,15 @@ - + + + + + diff --git a/securesignals-ima-dev-app/build.gradle b/securesignals-ima-dev-app/build.gradle index 630e47c..2de3883 100644 --- a/securesignals-ima-dev-app/build.gradle +++ b/securesignals-ima-dev-app/build.gradle @@ -23,6 +23,7 @@ android { } lint { + baseline = file("lint-baseline.xml") disable 'GradleDependency', 'IconDipSize', 'IconDensities', 'RtlEnabled' } diff --git a/securesignals-ima-dev-app/lint-baseline.xml b/securesignals-ima-dev-app/lint-baseline.xml index f418c4a..f71c200 100644 --- a/securesignals-ima-dev-app/lint-baseline.xml +++ b/securesignals-ima-dev-app/lint-baseline.xml @@ -1,4 +1,15 @@ - + + + + + From bb1931cdb1e68daea83115abac7916b8aea4db6d Mon Sep 17 00:00:00 2001 From: Ian Bird Date: Thu, 29 Aug 2024 11:00:29 +0100 Subject: [PATCH 5/8] Add SSL debugging support to DevApps --- dev-app/src/main/AndroidManifest.xml | 1 + dev-app/src/main/res/xml/network_security_config.xml | 8 ++++++++ securesignals-gma-dev-app/src/main/AndroidManifest.xml | 7 +++++-- .../src/main/res/xml/network_security_config.xml | 8 ++++++++ securesignals-ima-dev-app/src/main/AndroidManifest.xml | 7 +++++-- .../src/main/res/xml/network_security_config.xml | 8 ++++++++ 6 files changed, 35 insertions(+), 4 deletions(-) create mode 100644 dev-app/src/main/res/xml/network_security_config.xml create mode 100644 securesignals-gma-dev-app/src/main/res/xml/network_security_config.xml create mode 100644 securesignals-ima-dev-app/src/main/res/xml/network_security_config.xml diff --git a/dev-app/src/main/AndroidManifest.xml b/dev-app/src/main/AndroidManifest.xml index d5e389a..a08aa98 100644 --- a/dev-app/src/main/AndroidManifest.xml +++ b/dev-app/src/main/AndroidManifest.xml @@ -11,6 +11,7 @@ android:icon="@mipmap/ic_launcher" android:allowBackup="false" android:supportsRtl="true" + android:networkSecurityConfig="@xml/network_security_config" tools:targetApi="31"> diff --git a/dev-app/src/main/res/xml/network_security_config.xml b/dev-app/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..ed4f075 --- /dev/null +++ b/dev-app/src/main/res/xml/network_security_config.xml @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/securesignals-gma-dev-app/src/main/AndroidManifest.xml b/securesignals-gma-dev-app/src/main/AndroidManifest.xml index 47cd90c..1311467 100644 --- a/securesignals-gma-dev-app/src/main/AndroidManifest.xml +++ b/securesignals-gma-dev-app/src/main/AndroidManifest.xml @@ -1,12 +1,15 @@ - + + android:theme="@style/AppTheme" + android:networkSecurityConfig="@xml/network_security_config" + tools:ignore="UnusedAttribute"> + + + + + + + diff --git a/securesignals-ima-dev-app/src/main/AndroidManifest.xml b/securesignals-ima-dev-app/src/main/AndroidManifest.xml index 1f8fe39..4852817 100644 --- a/securesignals-ima-dev-app/src/main/AndroidManifest.xml +++ b/securesignals-ima-dev-app/src/main/AndroidManifest.xml @@ -1,5 +1,6 @@ - + @@ -9,7 +10,9 @@ android:name=".IMADevApplication" android:label="@string/app_name" android:allowBackup="true" - android:icon="@drawable/ic_launcher"> + android:icon="@drawable/ic_launcher" + android:networkSecurityConfig="@xml/network_security_config" + tools:ignore="UnusedAttribute"> diff --git a/securesignals-ima-dev-app/src/main/res/xml/network_security_config.xml b/securesignals-ima-dev-app/src/main/res/xml/network_security_config.xml new file mode 100644 index 0000000..ed4f075 --- /dev/null +++ b/securesignals-ima-dev-app/src/main/res/xml/network_security_config.xml @@ -0,0 +1,8 @@ + + + + + + + + From 53574df6e3546a9b0f24d7028de416c2afc87839 Mon Sep 17 00:00:00 2001 From: Dave Snabel-Caunt Date: Mon, 9 Sep 2024 13:46:53 +0100 Subject: [PATCH 6/8] Correct log tag --- .../src/main/java/com/uid2/dev/GMADevApplication.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/GMADevApplication.kt b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/GMADevApplication.kt index f2791c4..0d34a6a 100644 --- a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/GMADevApplication.kt +++ b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/GMADevApplication.kt @@ -29,7 +29,7 @@ class GMADevApplication : Application() { ) } } catch (ex: Exception) { - Log.e("IMADevApplication", "Error initialising UID2Manager", ex) + Log.e("GMADevApplication", "Error initialising UID2Manager", ex) } } } From ee1b41c3324bb87f6355a45abcd95b36eca198f8 Mon Sep 17 00:00:00 2001 From: Dave Snabel-Caunt Date: Mon, 9 Sep 2024 13:52:34 +0100 Subject: [PATCH 7/8] Use Suppress annotation rather than lint baselines --- dev-app/lint-baseline.xml | 10 +++++----- .../java/com/uid2/dev/utils/PackageManagerEx.kt | 1 + securesignals-gma-dev-app/build.gradle | 1 - securesignals-gma-dev-app/lint-baseline.xml | 13 +------------ .../java/com/uid2/dev/utils/PackageManagerEx.kt | 1 + securesignals-ima-dev-app/build.gradle | 1 - securesignals-ima-dev-app/lint-baseline.xml | 13 +------------ .../java/com/uid2/dev/utils/PackageManagerEx.kt | 1 + 8 files changed, 10 insertions(+), 31 deletions(-) diff --git a/dev-app/lint-baseline.xml b/dev-app/lint-baseline.xml index f71c200..eea8e2a 100644 --- a/dev-app/lint-baseline.xml +++ b/dev-app/lint-baseline.xml @@ -4,12 +4,12 @@ + errorLine1=" getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(flags.toLong()))" + errorLine2=" ~~~~~~~~~~~~~~"> + file="src/main/java/com/uid2/dev/network/AppUID2Client.kt" + line="202" + column="88"/> diff --git a/dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt b/dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt index 274d3bf..e4f930c 100644 --- a/dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt +++ b/dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt @@ -6,6 +6,7 @@ import android.os.Build fun PackageManager.getApplicationInfoCompat(packageName: String, flags: Int = 0): ApplicationInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + @Suppress("WrongConstant") getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(flags.toLong())) } else { @Suppress("DEPRECATION") diff --git a/securesignals-gma-dev-app/build.gradle b/securesignals-gma-dev-app/build.gradle index de31c02..8852cd3 100644 --- a/securesignals-gma-dev-app/build.gradle +++ b/securesignals-gma-dev-app/build.gradle @@ -23,7 +23,6 @@ android { } lint { - baseline = file("lint-baseline.xml") disable 'GradleDependency' } diff --git a/securesignals-gma-dev-app/lint-baseline.xml b/securesignals-gma-dev-app/lint-baseline.xml index f71c200..f418c4a 100644 --- a/securesignals-gma-dev-app/lint-baseline.xml +++ b/securesignals-gma-dev-app/lint-baseline.xml @@ -1,15 +1,4 @@ - - - - - + diff --git a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt index 274d3bf..e4f930c 100644 --- a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt +++ b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt @@ -6,6 +6,7 @@ import android.os.Build fun PackageManager.getApplicationInfoCompat(packageName: String, flags: Int = 0): ApplicationInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + @Suppress("WrongConstant") getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(flags.toLong())) } else { @Suppress("DEPRECATION") diff --git a/securesignals-ima-dev-app/build.gradle b/securesignals-ima-dev-app/build.gradle index 2de3883..630e47c 100644 --- a/securesignals-ima-dev-app/build.gradle +++ b/securesignals-ima-dev-app/build.gradle @@ -23,7 +23,6 @@ android { } lint { - baseline = file("lint-baseline.xml") disable 'GradleDependency', 'IconDipSize', 'IconDensities', 'RtlEnabled' } diff --git a/securesignals-ima-dev-app/lint-baseline.xml b/securesignals-ima-dev-app/lint-baseline.xml index f71c200..f418c4a 100644 --- a/securesignals-ima-dev-app/lint-baseline.xml +++ b/securesignals-ima-dev-app/lint-baseline.xml @@ -1,15 +1,4 @@ - - - - - + diff --git a/securesignals-ima-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt b/securesignals-ima-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt index 274d3bf..e4f930c 100644 --- a/securesignals-ima-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt +++ b/securesignals-ima-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt @@ -6,6 +6,7 @@ import android.os.Build fun PackageManager.getApplicationInfoCompat(packageName: String, flags: Int = 0): ApplicationInfo = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + @Suppress("WrongConstant") getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(flags.toLong())) } else { @Suppress("DEPRECATION") From 429d744887cd483e4120970afc2d3a58e34f1f1d Mon Sep 17 00:00:00 2001 From: Dave Snabel-Caunt Date: Mon, 9 Sep 2024 15:18:25 +0100 Subject: [PATCH 8/8] Revert GMA and IMA changes --- .../src/main/AndroidManifest.xml | 3 - .../java/com/uid2/dev/BannerActivity.java | 11 +-- .../java/com/uid2/dev/GMADevApplication.kt | 20 ++--- .../main/java/com/uid2/dev/utils/BundleEx.kt | 7 -- .../main/java/com/uid2/dev/utils/ContextEx.kt | 10 --- .../com/uid2/dev/utils/PackageManagerEx.kt | 14 ---- .../securesignals/gma/EUIDMediationAdapter.kt | 76 ------------------- .../gma/EUIDMediationAdapterTest.kt | 29 ------- .../src/main/AndroidManifest.xml | 3 - .../java/com/uid2/dev/IMADevApplication.kt | 20 ++--- .../main/java/com/uid2/dev/MainActivity.java | 10 +-- .../main/java/com/uid2/dev/utils/BundleEx.kt | 7 -- .../main/java/com/uid2/dev/utils/ContextEx.kt | 10 --- .../com/uid2/dev/utils/PackageManagerEx.kt | 14 ---- .../ima/EUIDSecureSignalsAdapter.kt | 70 ----------------- .../ima/EUIDSecureSignalsAdapterTest.kt | 29 ------- 16 files changed, 13 insertions(+), 320 deletions(-) delete mode 100644 securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/BundleEx.kt delete mode 100644 securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/ContextEx.kt delete mode 100644 securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt delete mode 100644 securesignals-gma/src/main/java/com/uid2/securesignals/gma/EUIDMediationAdapter.kt delete mode 100644 securesignals-gma/src/test/java/com/uid2/securesignals/gma/EUIDMediationAdapterTest.kt delete mode 100644 securesignals-ima-dev-app/src/main/java/com/uid2/dev/utils/BundleEx.kt delete mode 100644 securesignals-ima-dev-app/src/main/java/com/uid2/dev/utils/ContextEx.kt delete mode 100644 securesignals-ima-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt delete mode 100644 securesignals-ima/src/main/java/com/uid2/securesignals/ima/EUIDSecureSignalsAdapter.kt delete mode 100644 securesignals-ima/src/test/java/com/uid2/securesignals/ima/EUIDSecureSignalsAdapterTest.kt diff --git a/securesignals-gma-dev-app/src/main/AndroidManifest.xml b/securesignals-gma-dev-app/src/main/AndroidManifest.xml index 1311467..02047f6 100644 --- a/securesignals-gma-dev-app/src/main/AndroidManifest.xml +++ b/securesignals-gma-dev-app/src/main/AndroidManifest.xml @@ -16,9 +16,6 @@ android:name="com.google.android.gms.ads.APPLICATION_ID" android:value="ca-app-pub-3940256099942544~3347511713"/> - - - diff --git a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/BannerActivity.java b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/BannerActivity.java index d5e4d37..6a3d3e8 100644 --- a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/BannerActivity.java +++ b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/BannerActivity.java @@ -1,8 +1,5 @@ package com.uid2.dev; -import static com.uid2.dev.utils.BundleExKt.isEnvironmentEUID; -import static com.uid2.dev.utils.ContextExKt.getMetadata; - import android.os.Bundle; import androidx.appcompat.app.AppCompatActivity; import android.util.Log; @@ -14,9 +11,9 @@ import com.google.android.gms.ads.RequestConfiguration; import com.google.android.gms.ads.initialization.InitializationStatus; import com.google.android.gms.ads.initialization.OnInitializationCompleteListener; -import com.uid2.EUIDManager; import com.uid2.UID2Manager; import com.uid2.data.UID2Identity; + import org.json.JSONObject; import java.io.BufferedReader; @@ -104,11 +101,7 @@ private void loadUID2Identity() { refreshFrom, refreshExpires, fromJsonIdentity.getRefreshResponseKey()); - if (isEnvironmentEUID(getMetadata(this))) { - EUIDManager.getInstance().setIdentity(identity); - } else { - UID2Manager.getInstance().setIdentity(identity); - } + UID2Manager.getInstance().setIdentity(identity); } catch (Exception e) { Log.e(TAG, "Error loading Identity: " + e); } diff --git a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/GMADevApplication.kt b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/GMADevApplication.kt index 0d34a6a..5becb71 100644 --- a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/GMADevApplication.kt +++ b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/GMADevApplication.kt @@ -2,11 +2,8 @@ package com.uid2.dev import android.app.Application import android.util.Log -import com.uid2.EUIDManager import com.uid2.UID2Manager import com.uid2.UID2Manager.Environment.Production -import com.uid2.dev.utils.getMetadata -import com.uid2.dev.utils.isEnvironmentEUID class GMADevApplication : Application() { @@ -16,18 +13,11 @@ class GMADevApplication : Application() { // Initialise the UID2Manager class. We will use it's DefaultNetworkSession rather than providing our own // custom implementation. This can be done to allow wrapping something like OkHttp. try { - if (getMetadata().isEnvironmentEUID()) { - EUIDManager.init( - context = this, - isLoggingEnabled = true, - ) - } else { - UID2Manager.init( - context = this, - environment = Production, - isLoggingEnabled = true, - ) - } + UID2Manager.init( + context = this, + environment = Production, + isLoggingEnabled = true, + ) } catch (ex: Exception) { Log.e("GMADevApplication", "Error initialising UID2Manager", ex) } diff --git a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/BundleEx.kt b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/BundleEx.kt deleted file mode 100644 index 2a68700..0000000 --- a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/BundleEx.kt +++ /dev/null @@ -1,7 +0,0 @@ -package com.uid2.dev.utils - -import android.os.Bundle - -private const val UID2_ENVIRONMENT_EUID = "uid2_environment_euid" - -fun Bundle.isEnvironmentEUID(): Boolean = getBoolean(UID2_ENVIRONMENT_EUID, false) diff --git a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/ContextEx.kt b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/ContextEx.kt deleted file mode 100644 index 91eef6c..0000000 --- a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/ContextEx.kt +++ /dev/null @@ -1,10 +0,0 @@ -package com.uid2.dev.utils - -import android.content.Context -import android.content.pm.PackageManager -import android.os.Bundle - -fun Context.getMetadata(): Bundle = packageManager.getApplicationInfoCompat( - packageName, - PackageManager.GET_META_DATA, -).metaData diff --git a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt b/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt deleted file mode 100644 index e4f930c..0000000 --- a/securesignals-gma-dev-app/src/main/java/com/uid2/dev/utils/PackageManagerEx.kt +++ /dev/null @@ -1,14 +0,0 @@ -package com.uid2.dev.utils - -import android.content.pm.ApplicationInfo -import android.content.pm.PackageManager -import android.os.Build - -fun PackageManager.getApplicationInfoCompat(packageName: String, flags: Int = 0): ApplicationInfo = - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { - @Suppress("WrongConstant") - getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(flags.toLong())) - } else { - @Suppress("DEPRECATION") - getApplicationInfo(packageName, flags) - } diff --git a/securesignals-gma/src/main/java/com/uid2/securesignals/gma/EUIDMediationAdapter.kt b/securesignals-gma/src/main/java/com/uid2/securesignals/gma/EUIDMediationAdapter.kt deleted file mode 100644 index 78e1e0f..0000000 --- a/securesignals-gma/src/main/java/com/uid2/securesignals/gma/EUIDMediationAdapter.kt +++ /dev/null @@ -1,76 +0,0 @@ -package com.uid2.securesignals.gma - -import android.content.Context -import com.google.android.gms.ads.AdError -import com.google.android.gms.ads.mediation.InitializationCompleteCallback -import com.google.android.gms.ads.mediation.MediationConfiguration -import com.google.android.gms.ads.mediation.rtb.RtbAdapter -import com.google.android.gms.ads.mediation.rtb.RtbSignalData -import com.google.android.gms.ads.mediation.rtb.SignalCallbacks -import com.uid2.EUIDManager -import com.uid2.UID2 -import com.google.android.gms.ads.mediation.VersionInfo as GmaVersionInfo - -/** - * An implementation of Google's GMS RtbAdapter that integrates UID2 tokens, accessed via the UID2Manager. - */ -public class EUIDMediationAdapter : RtbAdapter() { - - /** - * Gets the version of the UID2 SDK. - */ - @Suppress("DEPRECATION") - public override fun getSDKVersionInfo(): GmaVersionInfo = UID2.getVersionInfo().let { - GmaVersionInfo(it.major, it.minor, it.patch) - } - - /** - * Gets the version of the UID2 Secure Signals plugin. - */ - @Suppress("DEPRECATION") - public override fun getVersionInfo(): GmaVersionInfo = PluginVersion.getVersionInfo().let { - GmaVersionInfo(it.major, it.minor, it.patch) - } - - /** - * Initialises the UID2 SDK with the given Context. - */ - override fun initialize( - context: Context, - initializationCompleteCallback: InitializationCompleteCallback, - mediationConfigurations: MutableList, - ) { - // It's possible that the UID2Manager is already initialised. If so, it's a no-op. - if (!EUIDManager.isInitialized()) { - EUIDManager.init(context) - } - - // After we've asked to initialize the manager, we should wait until it's complete before reporting success. - // This will potentially allow any previously persisted identity to be fully restored before we allow any - // signals to be collected. - EUIDManager.getInstance().addOnInitializedListener(initializationCompleteCallback::onInitializationSucceeded) - } - - /** - * Collects the UID2 advertising token, if available. - */ - override fun collectSignals(rtbSignalData: RtbSignalData, signalCallbacks: SignalCallbacks) { - EUIDManager.getInstance().let { manager -> - val token = manager.getAdvertisingToken() - if (token != null) { - signalCallbacks.onSuccess(token) - } else { - // We include the IdentityStatus in the "error" to have better visibility on why the Advertising Token - // was not present. There are a number of valid reasons why we don't have a token, but we are still - // required to report these as "failures". - signalCallbacks.onFailure( - AdError( - manager.currentIdentityStatus.value, - "No Advertising Token", - "UID2", - ), - ) - } - } - } -} diff --git a/securesignals-gma/src/test/java/com/uid2/securesignals/gma/EUIDMediationAdapterTest.kt b/securesignals-gma/src/test/java/com/uid2/securesignals/gma/EUIDMediationAdapterTest.kt deleted file mode 100644 index edb1900..0000000 --- a/securesignals-gma/src/test/java/com/uid2/securesignals/gma/EUIDMediationAdapterTest.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.uid2.securesignals.gma - -import com.uid2.UID2 -import org.junit.Assert -import org.junit.Test - -class EUIDMediationAdapterTest { - @Test - fun `test SDK version`() { - val adapter = EUIDMediationAdapter() - val version = adapter.versionInfo - val expectedVersion = UID2.getVersionInfo() - - Assert.assertEquals(expectedVersion.major, version.majorVersion) - Assert.assertEquals(expectedVersion.minor, version.minorVersion) - Assert.assertEquals(expectedVersion.patch, version.microVersion) - } - - @Test - fun `test plugin version`() { - val adapter = EUIDMediationAdapter() - val version = adapter.sdkVersionInfo - val expectedVersion = PluginVersion.getVersionInfo() - - Assert.assertEquals(expectedVersion.major, version.majorVersion) - Assert.assertEquals(expectedVersion.minor, version.minorVersion) - Assert.assertEquals(expectedVersion.patch, version.microVersion) - } -} diff --git a/securesignals-ima-dev-app/src/main/AndroidManifest.xml b/securesignals-ima-dev-app/src/main/AndroidManifest.xml index 4852817..13d22da 100644 --- a/securesignals-ima-dev-app/src/main/AndroidManifest.xml +++ b/securesignals-ima-dev-app/src/main/AndroidManifest.xml @@ -14,9 +14,6 @@ android:networkSecurityConfig="@xml/network_security_config" tools:ignore="UnusedAttribute"> - - - = Build.VERSION_CODES.TIRAMISU) { - @Suppress("WrongConstant") - getApplicationInfo(packageName, PackageManager.ApplicationInfoFlags.of(flags.toLong())) - } else { - @Suppress("DEPRECATION") - getApplicationInfo(packageName, flags) - } diff --git a/securesignals-ima/src/main/java/com/uid2/securesignals/ima/EUIDSecureSignalsAdapter.kt b/securesignals-ima/src/main/java/com/uid2/securesignals/ima/EUIDSecureSignalsAdapter.kt deleted file mode 100644 index 46c1eff..0000000 --- a/securesignals-ima/src/main/java/com/uid2/securesignals/ima/EUIDSecureSignalsAdapter.kt +++ /dev/null @@ -1,70 +0,0 @@ -package com.uid2.securesignals.ima - -import android.content.Context -import com.google.ads.interactivemedia.v3.api.VersionInfo -import com.google.ads.interactivemedia.v3.api.signals.SecureSignalsAdapter -import com.google.ads.interactivemedia.v3.api.signals.SecureSignalsCollectSignalsCallback -import com.google.ads.interactivemedia.v3.api.signals.SecureSignalsInitializeCallback -import com.uid2.EUIDManager -import com.uid2.UID2 - -/** - * A custom exception type that is used to report failures from the EUIDSecureSignalsAdapter when an error has occurred. - */ -public class EUIDSecureSignalsException(message: String? = null, cause: Throwable? = null) : Exception(message, cause) - -/** - * An implementation of Google's IMA SecureSignalsAdapter that integrates UID2 tokens, accessed via the UID2Manager. - */ -public class EUIDSecureSignalsAdapter : SecureSignalsAdapter { - - /** - * Gets the version of the UID2 SDK. - */ - public override fun getSDKVersion(): VersionInfo = UID2.getVersionInfo().let { - VersionInfo(it.major, it.minor, it.patch) - } - - /** - * Gets the version of the UID2 Secure Signals plugin. - */ - public override fun getVersion(): VersionInfo = PluginVersion.getVersionInfo().let { - VersionInfo(it.major, it.minor, it.patch) - } - - /** - * Initialises the UID2 SDK with the given Context. - */ - public override fun initialize(context: Context, callback: SecureSignalsInitializeCallback) { - // It's possible that the EUIDManager is already initialised. If so, it's a no-op. - if (!EUIDManager.isInitialized()) { - EUIDManager.init(context) - } - - // After we've asked to initialize the manager, we should wait until it's complete before reporting success. - // This will potentially allow any previously persisted identity to be fully restored before we allow any - // signals to be collected. - EUIDManager.getInstance().addOnInitializedListener(callback::onSuccess) - } - - /** - * Collects the UID2 advertising token, if available. - */ - public override fun collectSignals(context: Context, callback: SecureSignalsCollectSignalsCallback) { - EUIDManager.getInstance().let { manager -> - val token = manager.getAdvertisingToken() - if (token != null) { - callback.onSuccess(token) - } else { - // We include the IdentityStatus in the "error" to have better visibility on why the Advertising Token - // was not present. There are a number of valid reasons why we don't have a token, but we are still - // required to report these as "failures". - callback.onFailure( - EUIDSecureSignalsException( - "No Advertising Token available (Status: ${manager.currentIdentityStatus.value})", - ), - ) - } - } - } -} diff --git a/securesignals-ima/src/test/java/com/uid2/securesignals/ima/EUIDSecureSignalsAdapterTest.kt b/securesignals-ima/src/test/java/com/uid2/securesignals/ima/EUIDSecureSignalsAdapterTest.kt deleted file mode 100644 index 2f2125e..0000000 --- a/securesignals-ima/src/test/java/com/uid2/securesignals/ima/EUIDSecureSignalsAdapterTest.kt +++ /dev/null @@ -1,29 +0,0 @@ -package com.uid2.securesignals.ima - -import com.uid2.UID2 -import org.junit.Assert.assertEquals -import org.junit.Test - -class EUIDSecureSignalsAdapterTest { - @Test - fun `test SDK version`() { - val adapter = UID2SecureSignalsAdapter() - val version = adapter.sdkVersion - val expectedVersion = UID2.getVersionInfo() - - assertEquals(expectedVersion.major, version.majorVersion) - assertEquals(expectedVersion.minor, version.minorVersion) - assertEquals(expectedVersion.patch, version.microVersion) - } - - @Test - fun `test plugin version`() { - val adapter = UID2SecureSignalsAdapter() - val version = adapter.version - val expectedVersion = PluginVersion.getVersionInfo() - - assertEquals(expectedVersion.major, version.majorVersion) - assertEquals(expectedVersion.minor, version.minorVersion) - assertEquals(expectedVersion.patch, version.microVersion) - } -}