众所周知,Android app的权限,可以由系统预定义(大多数使用的权限都是这样),也可以app自己定义一个权限,别的app来申请。官方说明:<权限> | Android Developers
权限保护具有不同等级:
值 | 含义 |
---|---|
"normal" | 默认值。具有较低风险的权限,此类权限允许请求授权的应用访问隔离的应用级功能,对其他应用、系统或用户的风险非常小。系统会自动向在安装时请求授权的应用授予此类权限,无需征得用户的明确许可(但用户始终可以选择在安装之前查看这些权限)。 |
"dangerous" | 具有较高风险的权限,此类权限允许请求授权的应用访问用户私人数据或获取可对用户造成不利影响的设备控制权。由于此类权限会带来潜在风险,因此系统可能不会自动向请求授权的应用授予此类权限。例如,应用请求的任何危险权限都可能会向用户显示并且获得确认才会继续执行操作,或者系统会采取一些其他方法来避免用户自动授予使用此类功能的权限。 |
"signature" | 只有在请求授权的应用使用与声明权限的应用相同的证书进行签名时系统才会授予的权限。如果证书匹配,系统会在不通知用户或征得用户明确许可的情况下自动授予权限。 |
"knownSigner" | 只有在请求授权的应用使用允许使用的证书进行签名时系统才会授予的权限。如果请求者的证书已列出,系统会在不通知用户或征得用户明确许可的情况下自动授予权限。 |
"signatureOrSystem" |
系统仅向位于 Android 系统映像的专用文件夹中的应用或使用与声明权限的应用相同的证书进行签名的应用授予的权限。不要使用此选项,因为
|
尤其注意保护等级是signature|privileged的权限,当使用该权限的app与定义该权限的app签名一致时,可以获得权限;或者如果APP是privileged APP也会获得该权限。
那什么是privileged APP呢?privileged APP首先是System APP,即预置在system分区(不要求是系统签名)。不过同在system分区,/system/app和/system/priv-app下的apk,其权限也是不同的。
通过 adb shell dumpsys package <APP包名> 可以看到,前者的flags中有一个SYSTEM,但是后者在privateFlags中,还多了一个PRIVILEGED
因此对于signature|privileged的权限,可以把三方app放到/system/priv-app下,就可以获取privileged保护的权限了。
不过实测发现:
对于系统预定义的privileged保护的权限,如INTERACT_ACROSS_USERS,定义在framework/base/core/res/AndroidManifest.xml中:
<!-- @SystemApi @hide Allows an application to call APIs that allow it to do interactionsacross the users on the device, using singleton services anduser-targeted broadcasts. This permission is not available tothird party applications. --><permission android:name="android.permission.INTERACT_ACROSS_USERS"android:protectionLevel="signature|privileged|development" />
如果APP声明了该权限,除了将apk放到/system/priv-app下之外,还需要在/system/etc/permissions/xxx.xml(名字随意)中显式声明:
<permissions>
<privapp-permissions package="com.example.test">
<permission name="android.permission.INTERACT_ACROSS_USERS"/>
</privapp-permissions>
</permissions>
否则系统无法启动,system_server一直崩溃,报错:
java.lang.IllegalStateException: Signature|privileged permissions not in privapp-permissions whitelist: {com.example.test (/system/priv-app/Test): android.permission.INTERACT_ACROSS_USERS}
但对于其他apk(如CarService)中声明的权限,如android.car.permission.CAR_VENDOR_EXTENSION,定义在packages/services/Car/service/AndroidManifest.xml:
<permissionandroid:name="android.car.permission.CAR_VENDOR_EXTENSION"android:protectionLevel="signature|privileged"android:label="@string/car_permission_label_vendor_extension"android:description="@string/car_permission_desc_vendor_extension" />
尽管也是signature|privileged保护,却并不需要在/system/etc/permissions/xxx.xml中显式声明,只要把apk放到/system/priv-app下即可