Prueba de múltiples usuarios

Esta página describe aspectos importantes de la prueba de múltiples usuarios en la plataforma Android. Para obtener información sobre cómo implementar la compatibilidad con varios usuarios, consulte Compatibilidad con varios usuarios .

Rutas de dispositivos

La siguiente tabla enumera varias de las rutas de dispositivos y cómo se resuelven. Todos los valores de la columna Ruta son un almacenamiento en espacio aislado específico del usuario. La historia del almacenamiento de Android ha cambiado con el tiempo; lea la documentación de almacenamiento para obtener más información.

Camino Ruta del sistema (opcional) Objetivo
/data/user/{userId}/{app.path} /data/data Almacenamiento de aplicaciones
/storage/emulated/{userId} /sdcard Almacenamiento interno compartido
/data/media/{userId} ninguno Datos multimedia del usuario (por ejemplo, música, videos)
/data/system/users/{userId} ninguno Configuración/estado del sistema por usuario

Accesible solo por aplicaciones del sistema

Este es un ejemplo del uso de una ruta específica del usuario:

# to access user 10's private application data for app com.bar.foo:
$ adb shell ls /data/user/10/com.bar.foo/

interacciones adb entre usuarios

Varios comandos adb son útiles cuando se trata de múltiples usuarios. Algunos de estos comandos solo son compatibles con Android 9 y versiones posteriores:

  • adb shell am instrument --user <userId> ejecuta una prueba de instrumentación contra un usuario específico. De forma predeterminada, utiliza el usuario actual.
  • adb install --user <userId> instala un paquete para un usuario específico. Para garantizar que se instale un paquete para todos los usuarios, debe llamar a este para cada usuario.
  • adb uninstall --user <userId> desinstala un paquete para un usuario específico. Llame sin la marca --user para desinstalar para todos los usuarios.
  • adb shell am get-current-user obtiene el ID de usuario actual (en primer plano).
  • adb shell pm list users obtiene una lista de todos los usuarios existentes.
  • adb shell pm create-user crea un nuevo usuario y devuelve el ID.
  • adb shell pm remove-user elimina un usuario específico por ID.
  • adb shell pm disable --user <userId> desactiva un paquete para un usuario específico.
  • adb shell pm enable --user <userId> habilita un paquete para un usuario específico.
  • adb shell pm list packages --user <userId> enumera los paquetes ( -e para habilitado, -d para deshabilitado) para un usuario específico. Por defecto, esto siempre aparece para el usuario del sistema.

La siguiente información ayuda a explicar cómo se comporta adb con múltiples usuarios:

  • adb (o más exactamente, el demonio adbd ) siempre se ejecuta como el usuario del sistema (ID de usuario = 0) independientemente del usuario actual . Por lo tanto, las rutas de dispositivos que dependen del usuario (como /sdcard/ ) siempre se resuelven como el usuario del sistema. Consulte Rutas de dispositivos para obtener más detalles.

  • Si no se especifica un usuario predeterminado, cada subcomando adb tiene un usuario diferente. La mejor práctica es recuperar el ID de usuario con am get-current-user y luego usar explícitamente --user <userId> para cualquier comando que lo admita. Las marcas de usuario explícitas no fueron compatibles con todos los comandos hasta Android 9.

  • Se deniega el acceso a las rutas de /sdcard de usuarios secundarios a partir de Android 9. Consulte Proveedor de contenido para datos multiusuario para obtener detalles sobre cómo recuperar archivos durante la prueba.

Proveedor de contenido para datos multiusuario

Debido a que adb se ejecuta como el usuario del sistema y los datos están en un espacio aislado en Android 9 y versiones posteriores, debe usar proveedores de contenido para enviar o extraer cualquier dato de prueba de un usuario que no sea del sistema. Esto no es necesario si:

  • adbd se ejecuta como root (a través adb root ), lo cual solo es posible usando compilaciones userdebug o usereng .

  • Está utilizando ITestDevice de Trade Federation (Tradefed) para insertar/retirar los archivos, en cuyo caso use /sdcard/ paths en su configuración de prueba (por ejemplo, consulte el código fuente de pushFile en NativeDevice.java ).

Cuando un proveedor de contenido se ejecuta en el usuario secundario, puede acceder a él mediante el comando adb shell content con el user , uri y otros parámetros adecuados especificados.

Solución alternativa para desarrolladores de aplicaciones

Interactúe con los archivos de prueba usando adb content y una instancia de ContentProvider , en lugar del comando push o pull .

  1. Cree una instancia de ContentProvider alojada por la aplicación que pueda servir/almacenar archivos donde sea necesario. Utilice el almacenamiento interno de la aplicación.
  2. Use los comandos read o write adb shell content para empujar/extraer los archivos.

Solución alternativa para archivos multimedia

Para enviar archivos de medios a la partición de medios de la tarjeta SD, use las API públicas MediaStore . Por ejemplo:

# push MVIMG_20190129_142956.jpg to /storage/emulated/10/Pictures
# step 1
$ adb shell content insert --user 10 --uri content://media/external/images/media/ --bind _display_name:s:foo.jpg

# step 2
$ adb shell content query --user 10 --projection _id --uri content://media/external/images/media/ --where "_display_name=\'foo.jpg\'"

# step 3
$ adb shell content write --user 10 --uri content://media/external/images/media/8022 < MVIMG_20190129_142956.jpg

Instalación de un proveedor de contenido genérico

Instale y use un proveedor de contenido existente que lea y escriba archivos en la ruta /sdcard específica del usuario.

Cree TradefedContentProvider.apk desde la fuente utilizando make TradefedContentProvider .

```
# install content provider apk
$ adb install --user 10 -g TradefedContentProvider.apk

# pull some_file.txt
$ adb shell content read --user 10 --uri content://android.tradefed.contentprovider/sdcard/some_file.txt > local_file.txt

# push local_file.txt
$ adb shell content write --user 10 --uri content://android.tradefed.contentprovider/sdcard/some_file.txt < local_file.txt
```

Soporte multiusuario de la Federación de Comercio

Tradefed es el arnés de prueba oficial de Android. Esta sección resume parte del soporte integrado de Tradefed para escenarios de prueba multiusuario.

Comprobadores de estado

Los verificadores de estado del sistema (SSC) se ejecutan antes que los preparadores de destino y su limpieza se ejecuta después de esos preparadores.

UserChecker se define explícitamente para ayudar a los desarrolladores cuando prueban a varios usuarios. Realiza un seguimiento de si una prueba ha cambiado el estado de los usuarios en el dispositivo (por ejemplo, usuarios creados sin eliminarlos en el desmontaje). Además, si se configura user-cleanup , automáticamente intenta limpiar después de la prueba, al mismo tiempo que proporciona errores útiles para que la prueba pueda corregirse.

<system_checker class="com.android.tradefed.suite.checker.UserChecker" >
    <option name="user-cleanup" value="true" />
</system_checker>

preparador de objetivos

Los preparadores de destino generalmente se usan para configurar un dispositivo con una configuración particular. En el caso de las pruebas multiusuario, los preparadores se pueden utilizar para crear usuarios de un tipo específico, así como para cambiar a otros usuarios.

Para los tipos de dispositivos que no tienen un usuario secundario, puede usar CreateUserPreparer para crear y cambiar a un usuario secundario en AndroidTest.xml . Al final de la prueba, el preparador vuelve y elimina al usuario secundario.

<target_preparer
  class="com.google.android.tradefed.targetprep.CreateUserPreparer" >
</target_preparer>

Si el tipo de usuario que desea ya existe en el dispositivo, use SwitchUserTargetPreparer para cambiar al usuario existente. Los valores comunes para user-type incluyen system o secondary .

<target_preparer
  class="com.android.tradefed.targetprep.SwitchUserTargetPreparer">
    <option name="user-type" value="secondary" />
</target_preparer>

Pruebas dirigidas por host

En algunos casos, una prueba necesita cambiar usuarios dentro de la prueba . No haga el cambio desde dentro de un marco de prueba del lado del dispositivo, como UI Automator , porque el proceso de prueba puede cancelarse en cualquier momento. En su lugar, utilice un marco de prueba del lado del host como el Marco de prueba basado en el host de Tradefed, que brinda acceso a ITestDevice , lo que permite cualquier manipulación del usuario que sea necesaria.

Use UserChecker (descrito en Comprobadores de estado ) para pruebas controladas por host que cambian el estado del usuario porque garantiza que la prueba se limpie correctamente después de sí misma.