Testen mehrerer Benutzer

Auf dieser Seite werden wichtige Aspekte des Testens mehrerer Benutzer auf der Android-Plattform beschrieben. Informationen zur Implementierung der Mehrbenutzerunterstützung finden Sie unter Unterstützung mehrerer Benutzer .

Gerätepfade

In der folgenden Tabelle sind mehrere Gerätepfade und deren Auflösung aufgeführt. Alle Werte in der Spalte „Pfad“ sind ein benutzerspezifischer Sandbox-Speicher. Die Speichergeschichte von Android hat sich im Laufe der Zeit verändert; Weitere Informationen finden Sie in der Speicherdokumentation .

Weg Systempfad (optional) Zweck
/data/user/{userId}/{app.path} /data/data App-Speicher
/storage/emulated/{userId} /sdcard Gemeinsamer interner Speicher
/data/media/{userId} keiner Mediendaten des Nutzers (zum Beispiel Musik, Videos)
/data/system/users/{userId} keiner Systemkonfiguration/-status pro Benutzer

Nur für System-Apps zugänglich

Hier ist ein Beispiel für die Verwendung eines benutzerspezifischen Pfads:

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

ADB-Interaktionen zwischen Benutzern

Mehrere adb Befehle sind nützlich, wenn Sie mit mehreren Benutzern arbeiten. Einige dieser Befehle werden nur in Android 9 und höher unterstützt:

  • adb shell am instrument --user <userId> führt einen Instrumentierungstest für einen bestimmten Benutzer aus. Standardmäßig wird hierfür der aktuelle Benutzer verwendet.
  • adb install --user <userId> installiert ein Paket für einen bestimmten Benutzer. Um sicherzustellen, dass ein Paket für alle Benutzer installiert wird, müssen Sie dieses für jeden Benutzer aufrufen.
  • adb uninstall --user <userId> deinstalliert ein Paket für einen bestimmten Benutzer. Rufen Sie ohne das Flag --user auf, um die Deinstallation für alle Benutzer durchzuführen.
  • adb shell am get-current-user ruft die aktuelle Benutzer-ID (im Vordergrund) ab.
  • adb shell pm list users ruft eine Liste aller vorhandenen Benutzer ab.
  • adb shell pm create-user erstellt einen neuen Benutzer und gibt die ID zurück.
  • adb shell pm remove-user entfernt einen bestimmten Benutzer anhand seiner ID.
  • adb shell pm disable --user <userId> deaktiviert ein Paket für einen bestimmten Benutzer.
  • adb shell pm enable --user <userId> aktiviert ein Paket für einen bestimmten Benutzer.
  • adb shell pm list packages --user <userId> listet Pakete ( -e für aktiviert, -d für deaktiviert) für einen bestimmten Benutzer auf. Standardmäßig wird dies immer für den Systembenutzer aufgeführt.

Die folgenden Informationen helfen zu erklären, wie sich adb bei mehreren Benutzern verhält:

  • adb (oder genauer gesagt der adbd Daemon) wird immer als Systembenutzer (Benutzer-ID = 0) ausgeführt , unabhängig davon, welcher Benutzer aktuell ist . Daher werden Gerätepfade, die benutzerabhängig sind (z. B. /sdcard/ ), immer als Systembenutzer aufgelöst. Weitere Einzelheiten finden Sie unter Gerätepfade .

  • Wenn kein Standardbenutzer angegeben ist, hat jeder adb Unterbefehl einen anderen Benutzer. Die beste Vorgehensweise besteht darin, die Benutzer-ID mit am get-current-user abzurufen und dann explizit --user <userId> für jeden Befehl zu verwenden, der dies unterstützt. Explizite Benutzerflags wurden bis Android 9 nicht für alle Befehle unterstützt.

  • Der Zugriff auf /sdcard Pfade sekundärer Benutzer wird ab Android 9 verweigert. Weitere Informationen zum Abrufen von Dateien während des Tests finden Sie unter Inhaltsanbieter für Mehrbenutzerdaten .

Inhaltsanbieter für Mehrbenutzerdaten

Da adb als Systembenutzer ausgeführt wird und die Daten in Android 9 und höher in einer Sandbox gespeichert sind, müssen Sie Inhaltsanbieter verwenden, um Testdaten von einem Nicht-Systembenutzer zu übertragen oder abzurufen. Dies ist nicht erforderlich, wenn:

  • adbd wird als Root ausgeführt (über adb root ), was nur mit userdebug oder usereng Builds möglich ist.

  • Sie verwenden ITestDevice von Trade Federation (Tradefed), um die Dateien per Push/Pull zu übertragen. Verwenden Sie in diesem Fall /sdcard/ -Pfade in Ihrer Testkonfiguration (siehe beispielsweise den Quellcode für pushFile in NativeDevice.java ).

Wenn ein Inhaltsanbieter im sekundären Benutzer ausgeführt wird, können Sie darauf zugreifen, indem Sie den adb shell content mit den entsprechenden user , uri und anderen angegebenen Parametern verwenden.

Problemumgehung für App-Entwickler

Interagieren Sie mit Testdateien mithilfe adb content und einer Instanz von ContentProvider anstelle des push oder pull Befehls.

  1. Erstellen Sie eine von der App gehostete Instanz von ContentProvider , die Dateien bei Bedarf bereitstellen/speichern kann. Nutzen Sie den internen Speicher der App.
  2. Verwenden Sie read oder write adb shell content , um die Dateien per Push/Pull zu übertragen.

Problemumgehung für Mediendateien

Um Mediendateien auf die Medienpartition der SD-Karte zu übertragen, verwenden Sie die öffentlichen APIs von MediaStore . Zum Beispiel:

# 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

Installieren eines generischen Inhaltsanbieters

Installieren und verwenden Sie einen vorhandenen Inhaltsanbieter, der Dateien im benutzerspezifischen /sdcard Pfad liest und schreibt.

Erstellen Sie TradefedContentProvider.apk aus der Quelle mit 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
```

Mehrbenutzerunterstützung der Handelsföderation

Tradefed ist das offizielle Android-Testgerät. In diesem Abschnitt werden einige der integrierten Unterstützungen von Tradefed für Mehrbenutzer-Testszenarien zusammengefasst.

Statusprüfer

Systemstatusprüfer (SSCs) werden vor den Zielvorbereitern ausgeführt, und ihre Bereinigung wird nach diesen Vorbereitern ausgeführt.

UserChecker ist explizit definiert, um Entwicklern beim Testen mehrerer Benutzer zu helfen. Es verfolgt, ob ein Test den Status der Benutzer auf dem Gerät geändert hat (z. B. Benutzer erstellt, ohne sie beim Teardown zu entfernen). Darüber hinaus wird bei aktivierter user-cleanup automatisch versucht, nach dem Test zu bereinigen, wobei weiterhin hilfreiche Fehler bereitgestellt werden, damit der Test behoben werden kann.

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

Zielvorbereiter

Zielvorbereiter werden normalerweise verwendet, um ein Gerät mit einer bestimmten Konfiguration einzurichten. Bei Mehrbenutzertests können Vorbereiter verwendet werden, um Benutzer eines bestimmten Typs zu erstellen und zu anderen Benutzern zu wechseln.

Für Gerätetypen, die keinen sekundären Benutzer haben, können Sie CreateUserPreparer verwenden, um in AndroidTest.xml einen sekundären Benutzer zu erstellen und zu diesem zu wechseln . Am Ende des Tests schaltet der Ersteller zurück und löscht den sekundären Benutzer.

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

Wenn der gewünschte Benutzertyp bereits auf dem Gerät vorhanden ist, wechseln Sie mit SwitchUserTargetPreparer zum vorhandenen Benutzer. Zu den üblichen Werten für user-type gehören system oder secondary .

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

Hostgesteuerte Tests

In einigen Fällen muss ein Test den Benutzer innerhalb des Tests wechseln. Nehmen Sie den Wechsel nicht innerhalb eines geräteseitigen Testframeworks wie UI Automator vor, da der Testprozess jederzeit abgebrochen werden kann. Verwenden Sie stattdessen ein hostseitiges Testframework wie das Host-Driven Test Framework von Tradefed, das Zugriff auf ITestDevice ermöglicht und jede erforderliche Benutzermanipulation ermöglicht.

Verwenden Sie UserChecker (beschrieben unter Statusprüfer ) für hostgesteuerte Tests, die den Benutzerstatus ändern, da dadurch sichergestellt wird, dass der Test nach sich selbst ordnungsgemäß bereinigt wird.