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 demonioadbd
) 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 conam 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ésadb root
), lo cual solo es posible usando compilacionesuserdebug
ousereng
.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 depushFile
enNativeDevice.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
.
- 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. - Use los comandos
read
owrite
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.