En esta página, se describen aspectos importantes de las pruebas con varios usuarios en la plataforma de Android. Para obtener información sobre cómo implementar la compatibilidad con varios usuarios, consulta Compatibilidad con varios usuarios.
Rutas de dispositivos
En la siguiente tabla, se enumeran varias rutas de acceso del dispositivo y cómo se resuelven. Todos los valores de la columna Ruta de acceso son un almacenamiento aislado específico del usuario. El almacenamiento de Android cambió con el tiempo. Para obtener más información, consulta la documentación sobre almacenamiento.
| Ruta | Ruta de acceso 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 de contenido multimedia del usuario (por ejemplo, música y videos) | 
| /data/system/users/{userId} | none | Configuración o estado del sistema por usuario Solo las apps del sistema pueden acceder a él | 
A continuación, se muestra un ejemplo del uso de 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 de 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 en 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 este método para cada usuario.
- adb uninstall --user <userId>desinstala un paquete para un usuario específico. Llama sin la marca- --userpara desinstalar la app para todos los usuarios.
- adb shell am get-current-userobtiene el ID del usuario actual (en primer plano).
- adb shell pm list usersobtiene una lista de todos los usuarios existentes.
- adb shell pm create-usercrea un usuario nuevo y devuelve el ID.
- adb shell pm remove-userquita un usuario específico por su 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 (- -epara habilitados,- -dpara inhabilitados) para un usuario específico. De forma predeterminada, siempre se muestra la lista para el usuario del sistema.
La siguiente información ayuda a explicar cómo se comporta adb con varios usuarios:
- adb(o, con mayor precisión, el daemon- adbd) siempre se ejecuta como el usuario del sistema (ID de usuario = 0) independientemente del usuario 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 - adbtendrá un usuario diferente. La práctica recomendada es recuperar el ID del usuario con- am get-current-usery, 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 - /sdcardde 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 de varios usuarios
Dado que adb se ejecuta como usuario del sistema y los datos se aíslan en Android 9 y versiones posteriores, debes usar proveedores de contenido para enviar o extraer datos de prueba de un usuario que no sea del sistema. Esto no es necesario en los siguientes casos:
- adbdse ejecuta como raíz (a través de- adb root), lo que solo es posible con compilaciones de- userdebugo- usereng.
- Usas - ITestDevicede Trade Federation (Tradefed) para enviar o extraer los archivos, en cuyo caso debes usar rutas de acceso- /sdcard/en la configuración de la prueba (por ejemplo, consulta el código fuente de- pushFileen- NativeDevice.java).
Cuando un proveedor de contenido se ejecuta en el usuario secundario, puedes acceder a él con el comando adb shell content y los parámetros user, uri y otros parámetros especificados correspondientes.
Solución alternativa para desarrolladores de apps
Interactúa con los archivos de prueba usando adb content y una instancia de ContentProvider, en lugar del comando push o pull.
- Crea una instancia de ContentProvideralojada por la app que pueda entregar y almacenar archivos cuando sea necesario. Usar el almacenamiento interno de la app
- Usa los comandos adb shell contentreadowritepara enviar o extraer los archivos.
Solución alternativa para archivos multimedia
Para enviar archivos multimedia a la partición de medios 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
Cómo instalar 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 Trade Federation
Tradefed es el agente de prueba oficial de Android. En esta sección, se resumen algunas de las funciones integradas de Tradefed para admitir situaciones de prueba 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 esos preparadores.
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, creó usuarios sin quitarlos en la limpieza). Además, si se configura user-cleanup, se intenta limpiar automáticamente después de la prueba, a la vez que se proporcionan 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 en particular. En el caso de las pruebas con varios usuarios, se pueden usar preparadores 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 el 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. 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 controladas 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 dispositivo, como UI Automator, ya que el proceso de prueba se puede detener en cualquier momento. En su lugar, usa un framework de prueba del host, como el framework de prueba controlado por el host de Tradefed, que brinda acceso a ITestDevice y permite cualquier manipulación del usuario que sea necesaria.
Usa UserChecker (que se describe en Verificadores de estado) para las pruebas controladas por el host que cambian el estado del usuario, ya que garantiza que la prueba se limpie correctamente después de sí misma.
