Uso compartido seguro de grandes conjuntos de datos con BLOB de datos

En algunas situaciones, como las que implican aprendizaje automático o reproducción de contenido multimedia, es posible que la app desee usar el mismo conjunto de datos grande que otra app.

Para ayudar a reducir la redundancia de datos, tanto en la red como en el disco, Android 11 (API nivel 30) almacena en caché conjuntos de datos compartidos, compatibles con casos prácticos como aprendizaje automático y reproducción de contenido multimedia. Cuando la app necesita acceder a un conjunto de datos grande compartido, primero puede buscar estos conjuntos de datos almacenados en caché, llamados BLOB de datos compartidos, antes de determinar si es necesario descargar una copia nueva. Las apps pueden usar esta funcionalidad de conjuntos de datos compartidos con las API de BlobStoreManager, que es un nuevo administrador de servicios del sistema en Android 11.

El sistema mantiene los BLOB de datos compartidos y controla cuáles son las apps que pueden acceder a ellos. Cuando la app agrega BLOB de datos, puedes indicar qué otras apps tendrán acceso mediante uno de los siguientes métodos:

  • Para otorgar acceso a un conjunto específico de aplicaciones en un dispositivo, pasa los nombres de los paquetes de estas apps a allowPackageAccess().
  • Para permitir solo las apps cuyos certificados estén firmados con la misma clave utilizada para la app, como un conjunto de aplicaciones que administras, llama a allowSameSignatureAccess().
  • Para otorgar acceso a todas las apps de un dispositivo, llama a allowPublicAccess().

Cómo acceder a los BLOB de datos compartidos

El sistema muestra una representación de cada BLOB de datos compartido mediante un objeto BlobHandle. Cada instancia de BlobHandle contiene un hash seguro a nivel criptográfico, y algunos detalles de identificación del conjunto de datos.

Para acceder a los BLOB de datos compartidos, descarga los detalles de identificación del servidor. Con estos detalles, verifica si el conjunto de datos ya está disponible en el sistema.

El siguiente paso depende de si los datos están disponibles o no.

Conjunto de datos disponible

Si el conjunto de datos ya está disponible en el dispositivo, accede a él desde el sistema, como se muestra en el siguiente fragmento de código:

Kotlin

val blobStoreManager =
        getSystemService(Context.BLOB_STORE_SERVICE) as BlobStoreManager
// The label "Sample photos" is visible to the user.
val blobHandle = BlobHandle.createWithSha256(sha256DigestBytes,
        "Sample photos",
        System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1),
        "photoTrainingDataset")
try {
    val input = ParcelFileDescriptor.AutoCloseInputStream(
            blobStoreManager.openBlob(blobHandle))
    useDataset(input)
}

Java

BlobStoreManager blobStoreManager =
        ((BlobStoreManager) getSystemService(Context.BLOB_STORE_SERVICE));
if (blobStoreManager != null) {
    // The label "Sample photos" is visible to the user.
    BlobHandle blobHandle = BlobHandle.createWithSha256(
            sha256DigestBytes,
            "Sample photos",
            System.currentTimeMillis() + TimeUnit.DAYS.toMillis(1),
            "photoTrainingDataset");
    try (InputStream input = new ParcelFileDescriptor.AutoCloseInputStream(
            blobStoreManager.openBlob(blobHandle))) {
        useDataset(input);
    }
}

Conjunto de datos no disponible

Si el conjunto de datos no está disponible, descárgalo del servidor y agrégalo al sistema, como se muestra en el siguiente fragmento de código:

Kotlin

val sessionId = blobStoreManager.createSession(blobHandle)
try {
    val session = blobStoreManager.openSession(sessionId)
    try {
        // For this example, write 200 MiB at the beginning of the file.
        val output = ParcelFileDescriptor.AutoCloseOutputStream(
                session.openWrite(0, 1024 * 1024 * 200))
        writeDataset(output)

        session.apply {
            allowSameSignatureAccess()
            allowPackageAccess(your-app-package,
                    app-certificate)
            allowPackageAccess(some-other-app-package,
                    app-certificate)
            commit(mainExecutor, callback)
        }
    }
}

Java

long sessionId = blobStoreManager.createSession(blobHandle);
try (BlobStoreManager.Session session =
        blobStoreManager.openSession(sessionId)) {
    // For this example, write 200 MiB at the beginning of the file.
    try (OutputStream output = new ParcelFileDescriptor.AutoCloseOutputStream(
            session.openWrite(0, 1024 * 1024 * 200)))
        writeDataset(output);
        session.allowSameSignatureAccess();
        session.allowPackageAccess(your-app-package,
                    app-certificate);
        session.allowPackageAccess(some-other-app-package,
                    app-certificate);
        session.commit(getMainExecutor(), callback);
    }
}