Tester plusieurs utilisateurs

Cette page décrit les aspects importants des tests multi-utilisateurs sur la plate-forme Android. Pour savoir comment implémenter la prise en charge multi-utilisateur, consultez Prendre en charge plusieurs utilisateurs.

Chemins d'accès par appareils

Le tableau suivant liste plusieurs chemins d'accès aux appareils et explique comment ils sont résolus. Toutes les valeurs de la colonne Chemin d'accès sont un stockage bac à sable spécifique à l'utilisateur. Le stockage Android a évolué au fil du temps. Pour en savoir plus, consultez la documentation Stockage.

Chemin d'accès Chemin d'accès au système (facultatif) Objectif
/data/user/{userId}/{app.path} /data/data Stockage des applications
/storage/emulated/{userId} /sdcard Espace de stockage interne partagé
/data/media/{userId} none Données multimédias utilisateur (par exemple, musique, vidéos)
/data/system/users/{userId} none Configuration/état du système par utilisateur

Accessible uniquement par les applications système

Voici un exemple d'utilisation d'un chemin spécifique à l'utilisateur :

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

Interactions adb entre les utilisateurs

Plusieurs commandes adb sont utiles lorsque vous gérez plusieurs utilisateurs. Certaines de ces commandes ne sont compatibles qu'avec Android 9 ou version ultérieure :

  • adb shell am instrument --user <userId> exécute un test d'instrumentation sur un utilisateur spécifique. Par défaut, l'utilisateur actuel est utilisé.
  • adb install --user <userId> installe un package pour un utilisateur spécifique. Pour vous assurer qu'un package est installé pour tous les utilisateurs, vous devez appeler cette méthode pour chacun d'eux.
  • adb uninstall --user <userId> désinstalle un package pour un utilisateur spécifique. Appelez sans l'indicateur --user pour désinstaller pour tous les utilisateurs.
  • adb shell am get-current-user obtient l'ID utilisateur actuel (au premier plan).
  • adb shell pm list users obtient la liste de tous les utilisateurs existants.
  • adb shell pm create-user crée un utilisateur et renvoie son ID.
  • adb shell pm remove-user supprime un utilisateur spécifique par son ID.
  • adb shell pm disable --user <userId> désactive un package pour un utilisateur spécifique.
  • adb shell pm enable --user <userId> permet d'activer un package pour un utilisateur spécifique.
  • adb shell pm list packages --user <userId> liste les packages (-e pour les packages activés, -d pour les packages désactivés) pour un utilisateur spécifique. Par défaut, cette commande liste toujours les utilisateurs du système.

Les informations suivantes vous aideront à comprendre le comportement de adb avec plusieurs utilisateurs :

  • adb (ou plus précisément le daemon adbd) s'exécute toujours en tant que utilisateur système (ID utilisateur = 0) quel que soit l'utilisateur actuel. Par conséquent, les chemins d'appareil qui dépendent de l'utilisateur (comme /sdcard/) sont toujours résolus en tant qu'utilisateur système. Pour en savoir plus, consultez Chemins d'accès aux appareils.

  • Si aucun utilisateur par défaut n'est spécifié, chaque sous-commande adb a un utilisateur différent. La bonne pratique consiste à récupérer l'ID utilisateur avec am get-current-user, puis à utiliser explicitement --user <userId> pour toute commande qui le prend en charge. Les indicateurs utilisateur explicites n'étaient pas compatibles avec toutes les commandes avant Android 9.

  • L'accès aux chemins /sdcard des utilisateurs secondaires est refusé à partir d'Android 9. Consultez Fournisseur de contenu pour les données multi-utilisateurs pour savoir comment récupérer des fichiers lors des tests.

Fournisseur de contenu pour les données multi-utilisateurs

Étant donné que adb s'exécute en tant qu'utilisateur système et que les données sont mises en bac à sable dans Android 9 et versions ultérieures, vous devez utiliser des fournisseurs de contenu pour envoyer ou extraire des données de test d'un utilisateur non système. Cette étape n'est pas nécessaire si :

  • adbd s'exécute en tant que root (via adb root), ce qui n'est possible qu'avec les builds userdebug ou usereng.

  • Vous utilisez ITestDevice de Trade Federation (Tradefed) pour envoyer ou extraire les fichiers. Dans ce cas, utilisez les chemins /sdcard/ dans la configuration de votre test (par exemple, consultez le code source de pushFile dans NativeDevice.java).

Lorsqu'un fournisseur de contenu s'exécute dans l'utilisateur secondaire, vous pouvez y accéder à l'aide de la commande adb shell content avec les paramètres user, uri et autres appropriés spécifiés.

Solution de contournement pour les développeurs d'applications

Interagissez avec les fichiers de test à l'aide de adb content et d'une instance de ContentProvider, au lieu de la commande push ou pull.

  1. Créez une instance de ContentProvider hébergée par l'application, qui peut servir et stocker des fichiers si nécessaire. Utilisez la mémoire de stockage interne de l'application.
  2. Utilisez les commandes adb shell content read ou write pour transférer ou extraire les fichiers.

Solution de contournement pour les fichiers multimédias

Pour transférer des fichiers multimédias vers la partition multimédia de la carte SD, utilisez les API publiques MediaStore. Exemple :

# 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

Installer un fournisseur de contenu générique

Installez et utilisez un fournisseur de contenu existant qui lit et écrit des fichiers dans le chemin d'accès /sdcard spécifique à l'utilisateur.

Créez TradefedContentProvider.apk à partir de la source à l'aide de 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
```

Compatibilité multi-utilisateur avec Trade Federation

Tradefed est le harnais de test Android officiel. Cette section récapitule certaines des fonctionnalités intégrées de Tradefed pour les scénarios de test multi-utilisateurs.

Outils de vérification de l'état

Les vérificateurs d'état du système (VÉS) sont exécutés avant les préparateurs cibles, et leur nettoyage est exécuté après ces préparateurs.

UserChecker est défini explicitement pour aider les développeurs à tester plusieurs utilisateurs. Il permet de savoir si un test a modifié l'état des utilisateurs sur l'appareil (par exemple, s'il a créé des utilisateurs sans les supprimer lors de la suppression). De plus, si user-cleanup est défini, il tente automatiquement de nettoyer après le test, tout en fournissant des erreurs utiles pour que le test puisse être corrigé.

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

Préparateur de cibles

Les préparateurs de cibles sont généralement utilisés pour configurer un appareil avec une configuration particulière. Dans le cas de tests multi-utilisateurs, les préparateurs peuvent être utilisés pour créer des utilisateurs d'un type spécifique et pour passer à d'autres utilisateurs.

Pour les types d'appareils qui n'ont pas d'utilisateur secondaire, vous pouvez utiliser CreateUserPreparer pour créer et passer à un utilisateur secondaire dans AndroidTest.xml. À la fin du test, le préparateur repasse à l'utilisateur principal et supprime l'utilisateur secondaire.

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

Si le type d'utilisateur que vous souhaitez utiliser existe déjà sur l'appareil, utilisez SwitchUserTargetPreparer pour passer à l'utilisateur existant. Les valeurs courantes pour user-type incluent system ou secondary.

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

Tests pilotés par l'hôte

Dans certains cas, un test doit changer d'utilisateur au cours du test. Ne passez pas d'un framework de test côté appareil, tel que UI Automator, car le processus de test peut être arrêté à tout moment. Utilisez plutôt un framework de test côté hôte tel que le framework de test piloté par l'hôte de Tradefed, qui donne accès à ITestDevice, ce qui permet toute manipulation utilisateur nécessaire.

Utilisez UserChecker (décrit dans Vérificateurs d'état) pour les tests pilotés par l'hôte qui modifient l'état de l'utilisateur, car il garantit que le test se nettoie correctement après son exécution.