Prueba de múltiples usuarios

Esta página describe aspectos importantes de la prueba de varios usuarios en la plataforma Android. Para obtener información sobre cómo implementar la compatibilidad con múltiples usuarios, consulte Soporte para 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, vídeos)
/data/system/users/{userId} ninguno Configuración/estado del sistema por usuario

Accesible solo por aplicaciones del sistema

A continuación se muestra 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 de adb entre usuarios

Varios comandos adb son útiles cuando se trata de varios usuarios. Algunos de estos comandos solo se admiten en 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, esto 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 llamarlo para cada usuario.
  • adb uninstall --user <userId> desinstala un paquete para un usuario específico. Llame sin el indicador --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> deshabilita 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 paquetes ( -e para habilitado, -d para deshabilitado) para un usuario específico. De forma predeterminada, esto siempre muestra el usuario del sistema.

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

  • adb (o más exactamente, el demonio adbd ) siempre se ejecuta como usuario del sistema (ID de usuario = 0) independientemente del usuario actual . Por lo tanto, las rutas de dispositivo 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 /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 las pruebas.

Proveedor de contenido para datos multiusuario

Debido a que adb se ejecuta como usuario del sistema y los datos están protegidos en Android 9 y versiones posteriores, debe utilizar proveedores de contenido para enviar o extraer datos 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 enviar/extraer los archivos, en cuyo caso utilice las rutas /sdcard/ 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 apropiados especificados.

Solución alternativa para desarrolladores de aplicaciones

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

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

Solución alternativa para archivos multimedia

Para enviar archivos multimedia a la partición multimedia de la tarjeta SD, utilice 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 utilice un proveedor de contenido existente que lea y escriba archivos en la ruta /sdcard específica del usuario.

Compile TradefedContentProvider.apk desde la fuente usando 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 de los preparadores de destino y su limpieza se ejecuta después de esos preparadores.

UserChecker se define explícitamente para ayudar a los desarrolladores a probar a varios usuarios. Realiza un seguimiento de si una prueba ha cambiado el estado de los usuarios en el dispositivo (por ejemplo, ha creado usuarios sin eliminarlos durante el desmontaje). Además, si se configura user-cleanup , automáticamente intenta limpiar después de la prueba, sin dejar de proporcionar 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 se utilizan normalmente para configurar un dispositivo con una configuración particular. En el caso de 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, puedes usar CreateUserPreparer para crear y cambiar a un usuario secundario en AndroidTest.xml . Al final de la prueba, el preparador regresa 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 impulsadas por el host

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

Utilice 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.