本頁面說明在 Android 平台上測試多位使用者時的重要事項。如要瞭解如何實作多使用者支援功能,請參閱「支援多位使用者」。
裝置路徑
下表列出幾個裝置路徑及其解析方式。 「路徑」欄中的所有值都是使用者專屬的沙箱儲存空間。Android 的儲存空間概念隨著時間演進而有所不同,詳情請參閱「儲存空間」說明文件。
| 路徑 | 系統路徑 (選用) | 目的 |
|---|---|---|
/data/user/{userId}/{app.path}
|
/data/data
|
應用程式儲存空間 |
/storage/emulated/{userId}
|
/sdcard
|
共用內部儲存空間 |
/data/media/{userId}
|
無 | 使用者媒體資料 (例如音樂、影片) |
/data/system/users/{userId}
|
無 | 每個使用者的系統設定/狀態
僅供系統應用程式存取 |
以下是使用使用者專屬路徑的範例:
# to access user 10's private application data for app com.bar.foo:
$ adb shell ls /data/user/10/com.bar.foo/
跨使用者的 adb 互動
處理多位使用者時,有幾個 adb 指令非常實用。部分指令僅適用於 Android 9 以上版本:
adb shell am instrument --user <userId>對特定使用者執行檢測設備測試。根據預設,這會使用目前使用者。adb install --user <userId>會為特定使用者安裝套件。如要確保為所有使用者安裝套件,您必須為每位使用者呼叫此函式。adb uninstall --user <userId>會為特定使用者解除安裝套件。 呼叫時不使用--user旗標,即可為所有使用者解除安裝。adb shell am get-current-user會取得目前 (前景) 使用者 ID。adb shell pm list users取得所有現有使用者的清單。adb shell pm create-user會建立新使用者,並傳回 ID。adb shell pm remove-user會依 ID 移除特定使用者。adb shell pm disable --user <userId>可為特定使用者停用套件。adb shell pm enable --user <userId>為特定使用者啟用套件。adb shell pm list packages --user <userId>會列出特定使用者的套件 (啟用時為-e,停用時為-d)。根據預設,這項清單一律會列出系統使用者。
以下資訊有助於瞭解 adb 在多位使用者環境中的運作方式:
adb(更準確地說,是adbd精靈) 一律以系統使用者 (使用者 ID = 0) 身分執行,無論目前使用者是誰。因此,取決於使用者的裝置路徑 (例如/sdcard/) 一律會解析為系統使用者。詳情請參閱「裝置路徑」。如果未指定預設使用者,每個
adb子指令都會有不同的使用者。最佳做法是使用am get-current-user擷取使用者 ID,然後針對支援該 ID 的任何指令明確使用--user <userId>。在 Android 9 之前,並非所有指令都支援明確的使用者標記。從 Android 9 開始,系統會拒絕次要使用者存取
/sdcard路徑。如要瞭解如何在測試期間擷取檔案,請參閱「多使用者資料的內容供應器」。
多使用者資料的內容供應器
由於 adb 是以系統使用者身分執行,且資料會在 Android 9 以上版本中進行沙箱化,因此您必須使用內容供應器,從非系統使用者推送或提取任何測試資料。如果符合下列情況,則不需要執行這項操作:
adbd以根使用者身分執行 (透過adb root),這只能透過userdebug或usereng建構版本達成。您使用 Trade Federation (Tradefed) 的
ITestDevice推送或提取檔案,在這種情況下,請在測試設定中使用/sdcard/路徑 (例如,請參閱NativeDevice.java中的pushFile原始碼)。
如果內容供應器在次要使用者中執行,您可以使用 adb shell content 指令,並指定適當的 user、uri 和其他參數,即可存取該供應器。
應用程式開發人員的解決方法
使用 adb content 和 ContentProvider 的執行個體與測試檔案互動,而不是 push 或 pull 指令。
- 建立應用程式代管的
ContentProvider執行個體,以便視需要提供及儲存檔案。使用應用程式的內部儲存空間。 - 使用
adb shell contentread或write指令推送或提取檔案。
媒體檔案的解決方法
如要將媒體檔案推送至 SD 卡的媒體分割區,請使用 MediaStore 公開 API。例如:
# 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
安裝一般內容供應商
安裝並使用現有的內容供應器,將檔案讀取及寫入至使用者專屬的 /sdcard 路徑。
使用 make TradefedContentProvider 從來源建構 TradefedContentProvider.apk:
```
# 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
```
Trade Federation 多使用者支援
Tradefed 是官方的 Android 測試控管工具,本節將摘要說明 Tradefed 內建的多使用者測試情境支援功能。
狀態檢查工具
系統狀態檢查程式 (SSC) 會在目標準備程式之前執行,並在這些準備程式之後 執行清理作業。
UserChecker
明確定義,可協助開發人員測試多位使用者。這項測試會追蹤測試是否變更裝置上使用者的狀態 (例如建立使用者,但未在拆除時移除)。此外,如果設定 user-cleanup,系統會在測試後自動嘗試清除,同時提供實用錯誤,方便修正測試。
<system_checker class="com.android.tradefed.suite.checker.UserChecker" >
<option name="user-cleanup" value="true" />
</system_checker>
目標準備者
目標準備器通常用於設定具有特定設定的裝置。如果是多使用者測試,準備人員可以建立特定類型的使用者,以及切換至其他使用者。
如果裝置類型沒有次要使用者,您可以使用 CreateUserPreparer 在 AndroidTest.xml 中建立及切換次要使用者。測試結束時,準備者會切換回來並刪除次要使用者。
<target_preparer
class="com.google.android.tradefed.targetprep.CreateUserPreparer" >
</target_preparer>
如果裝置上已有您要使用的使用者類型,請使用 SwitchUserTargetPreparer 切換至現有使用者。user-type 的常見值包括 system 或 secondary。
<target_preparer
class="com.android.tradefed.targetprep.SwitchUserTargetPreparer">
<option name="user-type" value="secondary" />
</target_preparer>
主機導向測試
在某些情況下,測試需要在測試中切換使用者。請勿從裝置端測試架構 (例如 UI Automator) 進行切換,因為測試程序隨時可能遭到終止。請改用主機端測試架構,例如 Tradefed 的主機驅動測試架構,這類架構可存取 ITestDevice,因此可進行任何必要的使用者操作。
如要進行主機驅動的測試,請使用 UserChecker (如「狀態檢查程式」中所述),因為這類測試會變更使用者狀態,確保測試後能正確清除自身。