Cómo probar varios usuarios

En esta página, se describen aspectos importantes para probar varios usuarios en la plataforma de Android. Para obtener información sobre la implementación de la compatibilidad con varios usuarios, consulta Cómo admitir varios usuarios.

Rutas de dispositivos

En la siguiente tabla, se enumeran varias de las rutas de acceso del dispositivo y cómo se resuelven. Todos los valores de la columna Ruta son un almacenamiento en zona de pruebas específico del usuario. La historia del almacenamiento de Android cambió con el tiempo. Para obtener más información, lee la documentación sobre almacenamiento.

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

Solo las apps del sistema pueden acceder a ellos.

Este es un ejemplo de cómo usar una ruta de acceso 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 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, se usa el usuario actual.
  • adb install --user <userId> instala un paquete para un usuario específico. Para asegurarte de que un paquete se instale para todos los usuarios, debes llamar a esta función para cada uno de ellos.
  • adb uninstall --user <userId> desinstala un paquete para un usuario específico. Llama sin la marca --user a fin de desinstalarla 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 usuario nuevo y muestra el ID.
  • adb shell pm remove-user quita un usuario específico por ID.
  • adb shell pm disable --user <userId> inhabilita 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 inhabilitado) de un usuario específico. De forma predeterminada, esto siempre aparece para el usuario del sistema.

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

  • adb (o, más precisamente, el daemon adbd) siempre se ejecuta como el usuario del sistema (ID de usuario = 0) independientemente de qué usuario sea el actual. Por lo tanto, las rutas de acceso del dispositivo que dependen del usuario (como /sdcard/) siempre se resuelven como el usuario del sistema. Consulta Rutas de dispositivos para obtener más detalles.

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

  • A partir de Android 9, se deniega el acceso a las rutas de acceso /sdcard de los usuarios secundarios. Consulta Proveedor de contenido para datos de varios usuarios para obtener detalles sobre cómo recuperar archivos durante las pruebas.

Proveedor de contenido para datos multiusuario

Debido a que adb se ejecuta como el usuario del sistema y los datos se encuentran en la zona de pruebas en Android 9 y versiones posteriores, debes usar proveedores de contenido para enviar o recuperar datos de prueba de un usuario que no sea del sistema. Esto no es necesario en los siguientes casos:

  • adbd se ejecuta como raíz (a través de adb root), lo que solo es posible con compilaciones userdebug o usereng.

  • Usas ITestDevice de la Federación de Comercio (Tradefed) para enviar o extraer los archivos, en cuyo caso usa rutas de acceso /sdcard/ en la configuración de la prueba (por ejemplo, consulta el código fuente de pushFile en NativeDevice.java).

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

Solución alternativa para desarrolladores de apps

Interactúa con archivos de prueba mediante adb content y una instancia de ContentProvider, en lugar de los comandos push o pull.

  1. Crea una instancia de ContentProvider alojada por la app que pueda entregar y almacenar archivos cuando sea necesario. Usa el almacenamiento interno de la app.
  2. Usa los comandos adb shell content read o write para enviar o extraer los archivos.

Solución para archivos multimedia

Para enviar archivos multimedia a la partición multimedia de la tarjeta SD, usa las APIs públicas de 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

Instala un proveedor de contenido genérico

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

Compila TradefedContentProvider.apk desde la fuente con 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
```

Compatibilidad con varios usuarios de la Federación de Comercio

Tradefed es el agente de prueba oficial de Android. En esta sección, se resume parte de la compatibilidad integrada de Tradefed para situaciones de pruebas multiusuario.

Verificadores 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 ellos.

UserChecker se define de forma explícita para ayudar a los desarrolladores cuando prueban varios usuarios. Realiza un seguimiento de si una prueba cambió el estado de los usuarios en el dispositivo (por ejemplo, si creó usuarios sin quitarlos durante la eliminación). Además, si se configura user-cleanup, intenta limpiar automáticamente después de la prueba y, al mismo tiempo, proporciona errores útiles para que se pueda corregir la prueba.

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

Preparador de destino

Por lo general, los preparadores de destino se usan para configurar un dispositivo con una configuración particular. En el caso de los preparadores de pruebas multiusuario, se pueden usar para crear usuarios de un tipo específico y cambiar a otros usuarios.

En el caso de 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 vuelve a cambiar y borra al usuario secundario.

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

Si el tipo de usuario que deseas ya existe en el dispositivo, usa SwitchUserTargetPreparer para cambiar al usuario existente. Entre los valores comunes para user-type, se incluyen system o secondary.

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

Pruebas dirigidas por el host

En algunos casos, una prueba debe cambiar de usuario dentro de la prueba. No realices el cambio desde un framework de prueba del lado del dispositivo, como UI Automator, ya que el proceso de prueba se puede finalizar en cualquier momento. En su lugar, usa un framework de pruebas del host, como el framework de pruebas dirigido por el host de Tradefed, que brinda acceso a ITestDevice, lo que permite cualquier manipulación del usuario que sea necesaria.

Usa UserChecker (que se describe en Verificadores de estado) para las pruebas dirigidas por el host que cambian el estado del usuario, ya que garantiza que la prueba se limpie correctamente después de sí misma.