前言:dumpsys package 这个命令还是很强大的,前段时间权限相关遇到比较多,趁周末好好研究下。


参考链接:

1.Define a Custom App Permission

2.https://developer.android.com/guide/topics/security/permissions#normal-dangerous


1. dumpsys  package 微信

使用命令:

adb shell dumpsys package com.tencent.mm > /home/jiatai/Android/dumpsys/weixin

权限分两段:

第一段(看起来都是自定义权限)

Permissions:
  Permission [com.tencent.mm.matrix.strategynotify] (6ef054e):
    sourcePackage=com.tencent.mm
    uid=10138 gids=null type=0 prot=signature
    perm=Permission{fb7366f com.tencent.mm.matrix.strategynotify}
    packageSetting=PackageSetting{c722f7c com.tencent.mm/10138}
  Permission [com.tencent.mm.permission.MM_MESSAGE] (cfe3005):
    sourcePackage=com.tencent.mm
    uid=10138 gids=null type=0 prot=signature
    perm=Permission{3ba285a com.tencent.mm.permission.MM_MESSAGE}
    packageSetting=PackageSetting{c722f7c com.tencent.mm/10138}
  Permission [com.tencent.mm.plugin.permission.READ] (e2aca8b):
    sourcePackage=com.tencent.mm
    uid=10138 gids=null type=0 prot=signature
    perm=Permission{470c768 com.tencent.mm.plugin.permission.READ}
    packageSetting=PackageSetting{c722f7c com.tencent.mm/10138}
  Permission [com.tencent.mm.wear.message] (336c781):
    sourcePackage=com.tencent.mm
    uid=10138 gids=null type=0 prot=signature
    perm=Permission{de27026 com.tencent.mm.wear.message}
    packageSetting=PackageSetting{c722f7c com.tencent.mm/10138}
  Permission [com.tencent.mm.ext.permission.SPORT] (af98467):
    sourcePackage=com.tencent.mm
    uid=10138 gids=null type=0 prot=normal
    perm=Permission{13ef214 com.tencent.mm.ext.permission.SPORT}
    packageSetting=PackageSetting{c722f7c com.tencent.mm/10138}
  Permission [com.tencent.mm.ext.permission.WRITE] (5075abd):
    sourcePackage=com.tencent.mm
    uid=10138 gids=null type=0 prot=signature|privileged
    perm=Permission{cf568b2 com.tencent.mm.ext.permission.WRITE}
    packageSetting=PackageSetting{c722f7c com.tencent.mm/10138}
  Permission [com.tencent.mm.permission.C2D_MESSAGE] (6100003):
    sourcePackage=com.tencent.mm
    uid=10138 gids=null type=0 prot=signature
    perm=Permission{a231b80 com.tencent.mm.permission.C2D_MESSAGE}
    packageSetting=PackageSetting{c722f7c com.tencent.mm/10138}
  Permission [com.tencent.mm.plugin.permission.WRITE] (853e5b9):
    sourcePackage=com.tencent.mm
    uid=10138 gids=null type=0 prot=signature
    perm=Permission{1cd5dfe com.tencent.mm.plugin.permission.WRITE}
    packageSetting=PackageSetting{c722f7c com.tencent.mm/10138}
  Permission [com.tencent.mm.ext.permission.READ] (788995f):
    sourcePackage=com.tencent.mm
    uid=10138 gids=null type=0 prot=signature|privileged
    perm=Permission{25e6fac com.tencent.mm.ext.permission.READ}
    packageSetting=PackageSetting{c722f7c com.tencent.mm/10138}



第二段(很全的权限列表了):

declared permissions:
      com.tencent.mm.plugin.permission.WRITE: prot=signature, INSTALLED
      com.tencent.mm.plugin.permission.READ: prot=signature, INSTALLED
      com.tencent.mm.permission.MM_MESSAGE: prot=signature, INSTALLED
      com.tencent.mm.ext.permission.READ: prot=signature|privileged, INSTALLED
      com.tencent.mm.ext.permission.WRITE: prot=signature|privileged, INSTALLED
      com.tencent.mm.ext.permission.SPORT: prot=normal, INSTALLED
      com.tencent.mm.wear.message: prot=signature, INSTALLED
      com.tencent.mm.permission.C2D_MESSAGE: prot=signature, INSTALLED
      com.tencent.mm.matrix.strategynotify: prot=signature, INSTALLED
    requested permissions:
      android.permission.CHANGE_WIFI_MULTICAST_STATE
      com.tencent.mm.plugin.permission.READ
      com.tencent.mm.plugin.permission.WRITE
      com.tencent.mm.permission.MM_MESSAGE
      com.huawei.authentication.HW_ACCESS_AUTH_SERVICE
      android.permission.ACCESS_NETWORK_STATE
      android.permission.ACCESS_COARSE_LOCATION
      android.permission.ACCESS_FINE_LOCATION
      android.permission.CAMERA
      android.permission.GET_TASKS
      android.permission.INTERNET
      android.permission.MODIFY_AUDIO_SETTINGS
      android.permission.RECEIVE_BOOT_COMPLETED
      android.permission.RECORD_AUDIO
      android.permission.READ_CONTACTS
      android.permission.READ_SMS
      android.permission.VIBRATE
      android.permission.WAKE_LOCK
      android.permission.WRITE_EXTERNAL_STORAGE
      android.permission.WRITE_CONTACTS
      android.permission.WRITE_SETTINGS
      com.android.launcher.permission.INSTALL_SHORTCUT
      com.android.launcher.permission.UNINSTALL_SHORTCUT
      com.android.launcher.permission.READ_SETTINGS
      com.tencent.mm.location.permission.SEND_VIEW
      android.permission.BLUETOOTH
      android.permission.BLUETOOTH_ADMIN
      android.permission.BROADCAST_STICKY
      android.permission.SYSTEM_ALERT_WINDOW
      android.permission.CHANGE_WIFI_STATE
      android.permission.GET_PACKAGE_SIZE
      android.permission.DOWNLOAD_WITHOUT_NOTIFICATION
      android.permission.NFC
      com.huawei.android.launcher.permission.CHANGE_BADGE
      android.permission.WRITE_APP_BADGE
      android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS
      android.permission.READ_PHONE_STATE
      android.permission.READ_EXTERNAL_STORAGE
      com.tencent.mm.ext.permission.READ
      com.tencent.mm.ext.permission.WRITE
      android.permission.ACCESS_WIFI_STATE
      com.tencent.mm.wear.message
      android.permission.BODY_SENSORS
      com.google.android.c2dm.permission.RECEIVE
      android.permission.GET_ACCOUNTS
      com.tencent.mm.permission.C2D_MESSAGE
      com.android.vending.BILLING
      android.permission.MANAGE_ACCOUNTS
      android.permission.AUTHENTICATE_ACCOUNTS
      android.permission.READ_SYNC_SETTINGS
      android.permission.WRITE_SYNC_SETTINGS
      android.permission.READ_PROFILE
      android.permission.USE_FINGERPRINT
      com.tencent.mm.matrix.strategynotify
    install permissions:
      android.permission.DOWNLOAD_WITHOUT_NOTIFICATION: granted=true
      android.permission.MODIFY_AUDIO_SETTINGS: granted=true
      android.permission.MANAGE_ACCOUNTS: granted=true
      com.tencent.mm.matrix.strategynotify: granted=true
      android.permission.NFC: granted=true
      android.permission.WRITE_SYNC_SETTINGS: granted=true
      android.permission.RECEIVE_BOOT_COMPLETED: granted=true
      com.tencent.mm.permission.MM_MESSAGE: granted=true
      com.android.launcher.permission.UNINSTALL_SHORTCUT: granted=true
      android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS: granted=true
      android.permission.READ_PROFILE: granted=true
      android.permission.BLUETOOTH: granted=true
      android.permission.CHANGE_WIFI_MULTICAST_STATE: granted=true
      android.permission.GET_TASKS: granted=true
      android.permission.AUTHENTICATE_ACCOUNTS: granted=true
      android.permission.INTERNET: granted=true
      android.permission.BLUETOOTH_ADMIN: granted=true
      android.permission.GET_PACKAGE_SIZE: granted=true
      com.tencent.mm.plugin.permission.READ: granted=true
      com.tencent.mm.wear.message: granted=true
      com.tencent.mm.ext.permission.WRITE: granted=true
      com.android.launcher.permission.READ_SETTINGS: granted=true
      android.permission.BROADCAST_STICKY: granted=true
      android.permission.CHANGE_WIFI_STATE: granted=true
      android.permission.ACCESS_NETWORK_STATE: granted=true
      com.tencent.mm.permission.C2D_MESSAGE: granted=true
      android.permission.USE_FINGERPRINT: granted=true
      android.permission.READ_SYNC_SETTINGS: granted=true
      com.tencent.mm.plugin.permission.WRITE: granted=true
      android.permission.VIBRATE: granted=true
      android.permission.ACCESS_WIFI_STATE: granted=true
      com.android.launcher.permission.INSTALL_SHORTCUT: granted=true
      android.permission.WAKE_LOCK: granted=true
      com.tencent.mm.ext.permission.READ: granted=true
    User 0: ceDataInode=1425553 installed=true hidden=false suspended=false stopped=false notLaunched=false enabled=0 instant=false
      gids=[3002, 3003, 3001]
      runtime permissions:
        android.permission.ACCESS_FINE_LOCATION: granted=true
        android.permission.BODY_SENSORS: granted=true
        android.permission.READ_EXTERNAL_STORAGE: granted=true
        android.permission.ACCESS_COARSE_LOCATION: granted=true
        android.permission.READ_PHONE_STATE: granted=true
        android.permission.WRITE_CONTACTS: granted=true
        android.permission.CAMERA: granted=true
        android.permission.GET_ACCOUNTS: granted=true
        android.permission.WRITE_EXTERNAL_STORAGE: granted=true
        android.permission.RECORD_AUDIO: granted=true
        android.permission.READ_CONTACTS: granted=true
      disabledComponents:
        com.tencent.mm.plugin.nfc_open.ui.NfcWebViewUI


2. 权限概念

从上面dumpsys package 微信的结果来看我们可以抽象出下面四个权限概念:

declared permissions :自定义权限

requested permissions :请求权限

install permissions :安装权限

runtime permissions  : 运行时权限


2.1 declared permissions

自定义权限作用:与其他应用分享自己的资源和功能

(By defining custom permissions, an app can share its resources and capabilities with other apps. )

为了创建自定义权限,你需要在你应用的AndroidManifest.xml里用一个或多个<permission>来声明。

比如说,一个应用想控制启动它的activity对象,那么可以像下面一个声明一个自定义权限:

<manifest
  xmlns:android="http://schemas.android.com/apk/res/android"
  package="com.example.myapp" >
    
    <permission
      android:name="com.example.myapp.permission.DEADLY_ACTIVITY"
      android:label="@string/permlab_deadlyActivity"
      android:description="@string/permdesc_deadlyActivity"
      android:permissionGroup="android.permission-group.COST_MONEY"
      android:protectionLevel="dangerous" />
    ...
</manifest>

注意: 系统不允许许多应用声明相同的自定义权限,除非这些应用有相同的签名。如果一个包声明了一个权限,那么系统不允许用户安装其他声明该权限的应用,除非其他应用和第一个应用有相同的签名。为了避免命名冲突,我们推荐使用reverse-domain-style命名规则,比如说com.example.myapp.ENGAGE_HYPERSPACE。



protectionLevel:这个属性是必须的,告知系统如何提醒用户需要该权限的应用,或者谁允许来持有该权限。

permissionGroup:这个属性是可选的,只被用来帮助系统呈现权限给用户。在大多数情况,你应该将其设置为一个标准的系统权限组(在android.Manifest.permission_group中列出的),虽然你可以自己定义一个权限组,但是我们更建议使用存在的权限组,因为可以简化呈现给用户的UI。

label和description:你需要为自定义权限提供label和description。这些都是用户可以看到的字符串资源,label对应于标签,description对应于权限细节。label建议写的短一些,而description建议为几句话描述一下权限允许持有者可以做什么。我们推荐两段式描述,第一句描述一下权限,第二句描述一下如果应用获取了对应权限会有什么风险。

下面是一个CALL_PHONE的例子:

<string name="permlab_callPhone">directly call phone numbers</string>
<string name="permdesc_callPhone">Allows the app to call
    phone numbers without your intervention. Malicious apps may
    cause unexpected calls on your phone bill. Note that this does not
    allow the app to call emergency numbers.</string>



应用可以通过使用<uses-permission>来定义自定义权限和请求其他应用定义的权限。但是,你最好仔细评估是否需要这么做。

如果你这在设置一套暴露功能给其他应用的应用。如果这些应用没有相同的签名,那么每个权限仅会也仅能被定义一次。及时应用都具有相同的签名,我们也建议每个权限仅被定义一次。

如果功能只对具有相同签名的apps开放,那么你应用通过签名检查来避免自定义权限。当其中一个app请求你的其他app的时候,第二个app在应答请求之前可以校验一下两个app是否具有同样的签名。

如果你正在开发只在你自己设备上的app,你应该为你的apps开发并安装一个管理权限的包。这个包不需要提供任何服务,它仅仅声明所有的权限,并且其他应用使用<uses-permission>请求这些权限。

android 多个module权限 安卓dump权限_permissions


2.2 requested permissions


declared permissions :自定义权限

install permissions :安装权限

runtime permissions :运行时权限




2.3 install permissions 和 runtime permissions


我是这么理解的,Android 6.0之前的manifest里包含的所有权限声明都可以当做install permissions,Android 6.0即以后manifest里除了dangerous permissions即runtime permissions外则属于install permissions。



正如在(三十五) 默认授予预制应用运行时权限方法 所说

“Android 6.0 及更高版本中的 Android 应用权限模式旨在使权限更易于用户理解、更实用、更安全。该模式将需要危险权限(请参阅受影响的权限)的 Android 应用从安装时权限模式转移至运行时权限模式:



安装时权限(Android 5.1 及更低版本):用户在安装或更新应用时,向应用授予危险权限。OEM/运营商可以在不通知用户的情况下,预先安装具有预授权的应用。
运行时权限(Android 6.0 及更高版本):用户在应用运行时向应用授予危险权限。应用决定何时申请权限(例如,在应用启动或用户访问特定功能时申请权限),但必须允许用户授予/拒绝授予应用访问特定权限组的权限。 OEM/运营商可以预安装应用,但不得预先授予权限(请参阅创建例外情况)。
运行时权限可以为用户提供应用正在寻求或已被授予的权限的额外上下文和可视性。运行时模式还鼓励开发者帮助用户了解应用请求权限的原因,并向用户透明展示授予或拒绝权限的好处和危害。

用户可使用“设置”中的“应用”菜单撤消应用权限。”


正常权限和危险权限
系统权限分为几个保护级别。需要了解的两个最重要保护级别是正常权限和危险权限:

正常权限涵盖应用需要访问其沙盒外部数据或资源,但对用户隐私或其他应用操作风险很小的区域。例如,设置时区的权限就是正常权限。如果应用声明其需要正常权限,系统会自动向应用授予该权限。如需当前正常权限的完整列表,请参阅正常权限。
危险权限涵盖应用需要涉及用户隐私信息的数据或资源,或者可能对用户存储的数据或其他应用的操作产生影响的区域。例如,能够读取用户的联系人属于危险权限。如果应用声明其需要危险权限,则用户必须明确向应用授予该权限。
特殊权限
有许多权限其行为方式与正常权限及危险权限都不同。SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS 特别敏感,因此大多数应用不应该使用它们。如果某应用需要其中一种权限,必须在清单中声明该权限,并且发送请求用户授权的 intent。系统将向用户显示详细管理屏幕,以响应该 intent。

如需了解有关如何请求这些权限的详情,请参阅 SYSTEM_ALERT_WINDOW 和 WRITE_SETTINGS 参考条目。

权限组
所有危险的 Android 系统权限都属于权限组。如果设备运行的是 Android 6.0(API 级别 23),并且应用的 targetSdkVersion 是 23 或更高版本,则当用户请求危险权限时系统会发生以下行为:

如果应用请求其清单中列出的危险权限,而应用目前在权限组中没有任何权限,则系统会向用户显示一个对话框,描述应用要访问的权限组。对话框不描述该组内的具体权限。例如,如果应用请求 READ_CONTACTS 权限,系统对话框只说明该应用需要访问设备的联系信息。如果用户批准,系统将向应用授予其请求的权限。
如果应用请求其清单中列出的危险权限,而应用在同一权限组中已有另一项危险权限,则系统会立即授予该权限,而无需与用户进行任何交互。例如,如果某应用已经请求并且被授予了 READ_CONTACTS 权限,然后它又请求 WRITE_CONTACTS,系统将立即授予该权限。
任何权限都可属于一个权限组,包括正常权限和应用定义的权限。但权限组仅当权限危险时才影响用户体验。可以忽略正常权限的权限组。

如果设备运行的是 Android 5.1(API 级别 22)或更低版本,并且应用的 targetSdkVersion 是 22 或更低版本,则系统会在安装时要求用户授予权限。再次强调,系统只告诉用户应用需要的权限组,而不告知具体权限。

android 多个module权限 安卓dump权限_android_02


3. 总结

简单看起来权限分为三大块,自定义权限、正常权限和危险权限(或者说运行时权限),运行时权限比较特殊,在Android 6.0 以后应用需要在使用时弹框请求。自定义权限只接触了概念,下周写个demo玩一玩。