このページでは、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
の各サブコマンドは別のユーザーとして実行されます。--user <userId>
フラグをサポートしているコマンドには、am get-current-user
でユーザー ID を取得してから、明示的にこのフラグを使用することをおすすめします。Android 9 までは、すべてのコマンドで明示的に user フラグを使用することはできませんでした。Android 9 以降では、セカンダリ ユーザーの
/sdcard
パスへのアクセスが拒否されます。テスト中にファイルを取得する方法については、マルチユーザー データのコンテンツ プロバイダをご覧ください。
マルチユーザー データのコンテンツ プロバイダ
Android 9 以降では、adb
はシステム ユーザーとして動作し、データはサンドボックス化されているため、システム ユーザー以外のユーザーのテストデータを push または pull するにはコンテンツ プロバイダを使用する必要があります。ただし、次の場合にはその必要がありません。
adbd
がルートとして動作している(adb root
を使用)。これはuserdebug
ビルドまたはusereng
ビルドでのみ可能です。Trade Federation(Tradefed)の
ITestDevice
を使用してファイルを push または pull している。この場合は、テスト構成の/sdcard/
パスを使用します。たとえば、NativeDevice.java
のpushFile
のソースコードを確認してください。
コンテンツ プロバイダがセカンダリ ユーザーで動作している場合は、user
や uri
などの適切なパラメータを指定して adb shell content
コマンドを使用することによりアクセスできます。
アプリ デベロッパー向けの回避策
push
コマンドまたは pull
コマンドの代わりに、adb content
と ContentProvider
のインスタンスを使用してテストファイルを操作します。
- 必要に応じて、ファイルの提供や保存ができるアプリがホストしている
ContentProvider
のインスタンスを作成します。アプリの内部ストレージを使用してください。 adb shell content
のread
コマンドまたはwrite
コマンドを使用して、ファイルを push または pull します。
メディア ファイルの回避策
メディア ファイルを SD カードのメディア パーティションに push するには、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>
ターゲット作成ツール
ターゲット作成ツールは通常、特定の構成でデバイスをセットアップするために使用されます。マルチユーザー テストの場合は、作成ツールを使用して特定タイプのユーザーを作成したり、他のユーザーに切り替えたりすることもできます。
セカンダリ ユーザーがないデバイスタイプの場合は、AndroidTest.xml
内で CreateUserPreparer
を使用してセカンダリ ユーザーを作成し、そのユーザーに切り替えられます。テストの最後に、作成ツールが元のユーザーに戻して、セカンダリ ユーザーを削除します。
<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
(ステータス チェッカーを参照)を使用します。