結論
Androidシステムで、定義されているpermissionを確認する方法はいくつか用意されているが、
少なくともAndroid8.1では、下記のどちらかの方法を使うべき。
$ adb shell dumpsys package permissions
Permissions:
Permission [com.google.android.apps.nexuslauncher.permission.READ_SETTINGS] (878caf2):
sourcePackage=com.google.android.apps.nexuslauncher
uid=10099 gids=null type=0 prot=signature|privileged
perm=Permission{2705543 com.google.android.apps.nexuslauncher.permission.READ_SETTINGS}
packageSetting=PackageSetting{8a0e7c0 com.google.android.apps.nexuslauncher/10099}
Permission [android.permission.REAL_GET_TASKS] (19f5cf9):
sourcePackage=android
uid=1000 gids=null type=0 prot=signature|privileged
perm=Permission{c4a43e android.permission.REAL_GET_TASKS}
packageSetting=PackageSetting{df7243c android/1000}
...
$ adb shell cat /data/system/packages.xml
<?xml version='1.0' encoding='utf-8' standalone='yes' ?>
<packages>
<version sdkVersion="29" databaseVersion="3" fingerprint="google/sdk_gphone_x86/generic_x86:10/QPP6.190730.005.B1/5775370:userdebug/dev-keys" />
<version volumeUuid="primary_physical" sdkVersion="29" databaseVersion="3" fingerprint="google/sdk_gphone_x86/generic_x86:10/QPP6.190730.005.B1/5775370:userdebug/dev-keys" />
<permission-trees>
<item name="com.google.android.googleapps.permission.GOOGLE_AUTH" package="com.google.android.gsf" />
</permission-trees>
<permissions>
<item name="com.google.android.apps.nexuslauncher.permission.READ_SETTINGS" package="com.google.android.apps.nexuslauncher" protection="18" />
<item name="android.permission.REAL_GET_TASKS" package="android" protection="18" />="com.google.android.apps.nexuslauncher" protection="18" />
...
NGな方法
Android Developerには、下記のように記載がある。
しかし、少なくともAndroid8.1では、全てのpermissionは出力されないので注意。
設定アプリ、またはシェルコマンド adb shell pm list permissions を使って現在システムに定義されているパーミッションをご覧いただけます。
なお、adb shell cmd package list permissions
も、内部実装は共通なので、同じくすべてのpermissionは出力されない。
何が違うのか
まず、pm list permissions
は、permission groupに属さないpermissionしか表示しない実装になっている。
(ちなみに、pmコマンドのマニュアルでは、「既知のすべてのパーミッションを出力します。」となっている)
例えば、CALL_PHONE
permissionは、PHONE
groupに属しているので、表示されない。
-g
オプションをつけることで、既知のpermission groupそれぞれに対して、所属するpermissionをすべて出力することができるが、これも完璧ではない。
permissionの定義がイケてなくて、存在しないpermission groupに属していることにしてしまっている場合、リストアップされない。
具体的には、android.permission.DOWNLOAD_WITHOUT_NOTIFICATION
というpermissionは
android.permission-group.NETWORK
というグループに属すると定義されているが、
android.permission-group.NETWORK
が定義されていないため、pm list permissions -g
では表示されない。
一方でdumpsys package permissions
は、
素直に/data/system/packages.xml
の中のpermissions
要素をリストアップしているため、同じ問題が発生しない。
なお実装は、以下のあたり。
pm list permissions
: frameworks/base/services/core/java/com/android/server/pm/PackageManagerShellCommand.javaのrunListPermissions
, doListPermissions
dumpsys package permissions
: frameworks/base/services/core/java/com/android/server/pm/Settings.javaのdumpPermissionsLPr
おわりに
PackageManagerはdumpsysとpm(cmd)が両方似たような領域でがんばっていて、どちらを使うべきかいちいち悩む。。。
今回のpermissionに関しても、網羅性という観点ではdumpsys package permissions
一択だが、
pm list permissions
には-f
オプションをつけることでlabelとdescriptionを出力してくれるという便利な機能があり、
dumpsys
だけ使えりゃいい、というわけでもない。
なんでこんなことになってしまっているのか。。。