AI豆包手机权限文章补充:Mainfest中某个权限的protectionLevel具体是如何被系统定义的?

背景:

经常我们在做framework开发时候,看到某些权限时候会有对权限定义进行深入查看,例如上一篇文章:
聊一聊豆包AI手机助手高度敏感权限CAPTURE_SECURE_VIDEO_OUTPUT

中就有看到关键字保护级别:android:protectionLevel="signature|role"。

也有其他权限看到是android:protectionLevel="normal":

看到这里就有vip学员朋友提出针对这个xml保护级别protectionLevel到底代表什么意思,除了常见的signature这个级别属于我们常见知道的的外又还有哪些protectionLevel呢?

这个问题确实是个好问题,要解答这个问题就需要深入看一下这块的源码分析,下面马哥带大家来一起解答。

源码剖析

protectionLevel对应的xml部分

先看看权限及保护级别的定义:

frameworks/base/core/res/AndroidManifest.xml

xml 复制代码
<!-- @SystemApi @TestApi @hide Allows an application to change to remove/kill tasks -->
<permission android:name="android.permission.REMOVE_TASKS"
    android:protectionLevel="signature|recents|role" />

<!-- @deprecated Use MANAGE_ACTIVITY_TASKS instead.
     @SystemApi @TestApi @hide Allows an application to create/manage/remove stacks -->
<permission android:name="android.permission.MANAGE_ACTIVITY_STACKS"
    android:protectionLevel="signature" />

一般这里里面的关键signature,recents,role一般都是有在对应attrs.xml中有定义,是不可以随意对写一个字符signaturexxx,role1xxx的,这样写的不对会直接报错。那么是在哪里进行定义的呢?

这里可以如果大家不知道具体在哪个attrs的xml文件定义,可以通过grep来查找定位:

在frameworks/base/core/res/res/values目录进行查找关键字"protectionLevel"。

bash 复制代码
test@test:~/disk_2T/aosp16/frameworks/base/core/res/res/values$ grep "protectionLevel" ./ -rn
./public-final.xml:37:  <public type="attr" name="protectionLevel" id="0x01010009" />
./attrs_manifest.xml:183:         permanent protectionLevel. If you are creating a custom permission in an
./attrs_manifest.xml:184:         application, you can define a protectionLevel attribute with one of the
./attrs_manifest.xml:185:         values listed below. If no protectionLevel is defined for a custom
./attrs_manifest.xml:194:    <attr name="protectionLevel">
./attrs_manifest.xml:2438:        <attr name="protectionLevel" />

可以看到这里查找到了,原来是在attrs_manifest.xml中进行的定义。

这里看看对应的xml定义部分:

frameworks/base/core/res/res/values/attrs_manifest.xml

xml 复制代码
    <!-- Characterizes the potential risk implied in a permission and
         indicates the procedure the system should follow when determining
         whether to grant the permission to an application requesting it. {@link
         android.Manifest.permission Standard permissions} have a predefined and
         permanent protectionLevel. If you are creating a custom permission in an
         application, you can define a protectionLevel attribute with one of the
         values listed below. If no protectionLevel is defined for a custom
         permission, the system assigns the default ("normal").
         <p>Each protection level consists of a base permission type and zero or
         more flags. Use the following functions to extract those.
         <pre>
         int basePermissionType = permissionInfo.getProtection();
         int permissionFlags = permissionInfo.getProtectionFlags();
         </pre>
         -->
    <attr name="protectionLevel">
        <!-- <strong>Base permission type</strong>: a lower-risk permission that gives
             an application access to isolated application-level features, with minimal
             risk to other applications, the system, or the user. The system
             automatically grants this type of permission to a requesting application at
             installation, without asking for the user's explicit approval (though the
             user always has the option to review these permissions before installing). -->
        <flag name="normal" value="0" />
        <!-- <strong>Base permission type</strong>: a higher-risk permission that
             would give a requesting application access to private user data or
             control over the device that can negatively impact the user.  Because
             this type of permission introduces potential risk, the system may
             not automatically grant it to the requesting application.  For example,
             any dangerous permissions requested by an application may be displayed
             to the user and require confirmation before proceeding, or some other
             approach may be taken to avoid the user automatically allowing
             the use of such facilities.  -->
        <flag name="dangerous" value="1" />
        <!-- <strong>Base permission type</strong>: a permission that the system is
             to grant only if the requesting application is signed with the same
             certificate as the application that declared the permission. If the
             certificates match, the system automatically grants the permission
             without notifying the user or asking for the user's explicit approval. -->
        <flag name="signature" value="2" />
        <!-- Old synonym for "signature|privileged". Deprecated in API level 23.
             Base permission type: a permission that the system is to grant only
             to packages in the Android system image <em>or</em> that are signed
             with the same certificates. Please avoid using this option, as the
             signature protection level should be sufficient for most needs and
             works regardless of exactly where applications are installed.  This
             permission is used for certain special situations where multiple
             vendors have applications built in to a system image which need
             to share specific features explicitly because they are being built
             together. -->
        <flag name="signatureOrSystem" value="3" />
        <!-- <strong>Base permission type</strong>: a permission that is managed internally by the
             system and only granted according to the protection flags. -->
        <flag name="internal" value="4" />
        <!-- Additional flag from base permission type: this permission can also
             be granted to any applications installed as privileged apps on the system image.
             Please avoid using this option, as the
             signature protection level should be sufficient for most needs and
             works regardless of exactly where applications are installed.  This
             permission flag is used for certain special situations where multiple
             vendors have applications built in to a system image which need
             to share specific features explicitly because they are being built
             together. -->
        <flag name="privileged" value="0x10" />
        <!-- Old synonym for "privileged". Deprecated in API level 23. -->
        <flag name="system" value="0x10" />
        <!-- Additional flag from base permission type: this permission can also
             (optionally) be granted to development applications. Although undocumented, the
              permission state used to be shared by all users (including future users), but it is
              managed per-user since API level 31. -->
        <flag name="development" value="0x20" />
        <!-- Additional flag from base permission type: this permission is closely
             associated with an app op for controlling access. -->
        <flag name="appop" value="0x40" />
        <!-- Additional flag from base permission type: this permission can be automatically
             granted to apps that target API levels below
             {@link android.os.Build.VERSION_CODES#M} (before runtime permissions
             were introduced). -->
        <flag name="pre23" value="0x80" />
        <!-- Additional flag from base permission type: this permission can be automatically
            granted to system apps that install packages. -->
        <flag name="installer" value="0x100" />
        <!-- Additional flag from base permission type: this permission can be automatically
            granted to system apps that verify packages. -->
        <flag name="verifier" value="0x200" />
        <!-- Additional flag from base permission type: this permission can be automatically
            granted any application pre-installed on the system image (not just privileged
            apps). -->
        <flag name="preinstalled" value="0x400" />
        <!-- Additional flag from base permission type: this permission can be automatically
            granted to the setup wizard app -->
        <flag name="setup" value="0x800" />
        <!-- Additional flag from base permission type: this permission can be granted to instant
             apps -->
        <flag name="instant" value="0x1000" />
        <!-- Additional flag from base permission type: this permission can only be granted to apps
             that target runtime permissions ({@link android.os.Build.VERSION_CODES#M} and above)
             -->
        <flag name="runtime" value="0x2000" />
        <!-- Additional flag from base permission type: this permission can be granted only
             if its protection level is signature, the requesting app resides on the OEM partition,
             and the OEM has allowlisted the app to receive this permission by the OEM.
         -->
        <flag name="oem" value="0x4000" />
        <!-- Additional flag from base permission type: this permission can be granted to
             privileged apps in vendor partition. -->
        <flag name="vendorPrivileged" value="0x8000" />
        <!-- Additional flag from base permission type: this permission can be automatically
            granted to the system default text classifier -->
        <flag name="textClassifier" value="0x10000" />
        <!-- Additional flag from base permission type: this permission automatically
            granted to device configurator -->
        <flag name="configurator" value="0x80000" />
        <!-- Additional flag from base permission type: this permission designates the app
            that will approve the sharing of incident reports. -->
        <flag name="incidentReportApprover" value="0x100000" />
        <!-- Additional flag from base permission type: this permission can be automatically
            granted to the system app predictor -->
        <flag name="appPredictor" value="0x200000" />
        <!-- Additional flag from base permission type: this permission can also be granted if the
             requesting application is included in the mainline module}. -->
        <flag name="module" value="0x400000" />
        <!-- Additional flag from base permission type: this permission can be automatically
            granted to the system companion device manager service -->
        <flag name="companion" value="0x800000" />
        <!-- Additional flag from base permission type: this permission will be granted to the
             retail demo app, as defined by the OEM.
             This flag has been replaced by the retail demo role and is a no-op since Android V.
          -->
        <flag name="retailDemo" value="0x1000000" />
        <!-- Additional flag from base permission type: this permission will be granted to the
             recents app. -->
        <flag name="recents" value="0x2000000" />
        <!-- Additional flag from base permission type: this permission is managed by role. -->
        <flag name="role" value="0x4000000" />
        <!-- Additional flag from base permission type: this permission can also be granted if the
             requesting application is signed by, or has in its signing lineage, any of the
             certificate digests declared in {@link android.R.attr#knownCerts}. -->
        <flag name="knownSigner" value="0x8000000" />
    </attr>

上面xml其实也自带了相关的注释非常详细,大概意思就是protectionLevel中在xml中的只可以是上面这些,每个保护字符都是有自己的含义,具体含义可以看注释哈,这些字符都会变成一个个的int类型的数字。

比如name="signature",这种最后就被转换成数字2。

bash 复制代码
 <flag name="signature" value="2" />

那么数字2又被谁使用呢?这里注释中可以看看出来是PermissionInfo的getProtectionFlags方法:

cpp 复制代码
/**
 * Return the additional flags in {@link #protectionLevel}.
 */
@ProtectionFlags
public int getProtectionFlags() {
    return protectionLevel & ~PROTECTION_MASK_BASE;
}

protectionLevel代码部分

frameworks/base/core/java/android/content/pm/PermissionInfo.java

代表权限保护级别的变量:

java 复制代码
    /**
     * The level of access this permission is protecting, as per
     * {@link android.R.attr#protectionLevel}. Consists of
     * a base permission type and zero or more flags. Use the following functions
     * to extract them.
     *
     * <pre>
     * int basePermissionType = permissionInfo.getProtection();
     * int permissionFlags = permissionInfo.getProtectionFlags();
     * </pre>
     *
     * <p></p>Base permission types are {@link #PROTECTION_NORMAL},
     * {@link #PROTECTION_DANGEROUS}, {@link #PROTECTION_SIGNATURE}, {@link #PROTECTION_INTERNAL}
     * and the deprecated {@link #PROTECTION_SIGNATURE_OR_SYSTEM}.
     * Flags are listed under {@link android.R.attr#protectionLevel}.
     *
     * @deprecated Use #getProtection() and #getProtectionFlags() instead.
     */
    @Deprecated
    public int protectionLevel;

一般这个变量值有以下这些:

java 复制代码
/**
 * Information you can retrieve about a particular security permission
 * known to the system.  This corresponds to information collected from the
 * AndroidManifest.xml's &lt;permission&gt; tags.
 */
public class PermissionInfo extends PackageItemInfo implements Parcelable {
    /**
     * A normal application value for {@link #protectionLevel}, corresponding
     * to the <code>normal</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_NORMAL = 0;

    /**
     * Dangerous value for {@link #protectionLevel}, corresponding
     * to the <code>dangerous</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_DANGEROUS = 1;

    /**
     * System-level value for {@link #protectionLevel}, corresponding
     * to the <code>signature</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_SIGNATURE = 2;

    /**
     * @deprecated Use {@link #PROTECTION_SIGNATURE}|{@link #PROTECTION_FLAG_PRIVILEGED}
     * instead.
     */
    @Deprecated
    public static final int PROTECTION_SIGNATURE_OR_SYSTEM = 3;

    /**
     * System-level value for {@link #protectionLevel}, corresponding
     * to the <code>internal</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_INTERNAL = 4;

    /** @hide */
    @IntDef(flag = false, prefix = { "PROTECTION_" }, value = {
            PROTECTION_NORMAL,
            PROTECTION_DANGEROUS,
            PROTECTION_SIGNATURE,
            PROTECTION_SIGNATURE_OR_SYSTEM,
            PROTECTION_INTERNAL,
    })
    @Retention(RetentionPolicy.SOURCE)
    public @interface Protection {}

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>privileged</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_FLAG_PRIVILEGED = 0x10;

    /**
     * @deprecated Old name for {@link #PROTECTION_FLAG_PRIVILEGED}, which
     * is now very confusing because it only applies to privileged apps, not all
     * apps on the system image.
     */
    @Deprecated
    public static final int PROTECTION_FLAG_SYSTEM = 0x10;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>development</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_FLAG_DEVELOPMENT = 0x20;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>appop</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_FLAG_APPOP = 0x40;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>pre23</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_FLAG_PRE23 = 0x80;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>installer</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_FLAG_INSTALLER = 0x100;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>verifier</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_FLAG_VERIFIER = 0x200;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>preinstalled</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_FLAG_PREINSTALLED = 0x400;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>setup</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_FLAG_SETUP = 0x800;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>instant</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_FLAG_INSTANT = 0x1000;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>runtime</code> value of
     * {@link android.R.attr#protectionLevel}.
     */
    public static final int PROTECTION_FLAG_RUNTIME_ONLY = 0x2000;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>oem</code> value of
     * {@link android.R.attr#protectionLevel}.
     *
     * @hide
     */
    @SystemApi
    public static final int PROTECTION_FLAG_OEM = 0x4000;

    /**
     * Additional flag for {${link #protectionLevel}, corresponding
     * to the <code>vendorPrivileged</code> value of
     * {@link android.R.attr#protectionLevel}.
     *
     * @hide
     */
    @SystemApi
    public static final int PROTECTION_FLAG_VENDOR_PRIVILEGED = 0x8000;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>text_classifier</code> value of
     * {@link android.R.attr#protectionLevel}.
     *
     * @hide
     */
    @SystemApi
    public static final int PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER = 0x10000;

    /**
     * Additional flag for {${link #protectionLevel}, corresponding
     * to the <code>wellbeing</code> value of
     * {@link android.R.attr#protectionLevel}.
     *
     * @deprecated this protectionLevel is obsolete. Permissions previously granted through this
     * protectionLevel have been migrated to use <code>role</code> instead
     * @hide
     */
    @SystemApi
    public static final int PROTECTION_FLAG_WELLBEING = 0x20000;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding to the
     * {@code documenter} value of {@link android.R.attr#protectionLevel}.
     *
     * @deprecated this protectionLevel is obsolete. Permissions previously granted
     * through this protectionLevel have been migrated to use <code>role</code> instead
     * @hide
     */
    @SystemApi
    public static final int PROTECTION_FLAG_DOCUMENTER = 0x40000;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding to the
     * {@code configurator} value of {@link android.R.attr#protectionLevel}.
     *
     * @hide
     */
    @SystemApi
    public static final int PROTECTION_FLAG_CONFIGURATOR = 0x80000;

    /**
     * Additional flag for {${link #protectionLevel}, corresponding
     * to the <code>incident_report_approver</code> value of
     * {@link android.R.attr#protectionLevel}.
     *
     * @hide
     */
    @SystemApi
    public static final int PROTECTION_FLAG_INCIDENT_REPORT_APPROVER = 0x100000;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>app_predictor</code> value of
     * {@link android.R.attr#protectionLevel}.
     *
     * @hide
     */
    @SystemApi
    public static final int PROTECTION_FLAG_APP_PREDICTOR = 0x200000;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>module</code> value of
     * {@link android.R.attr#protectionLevel}.
     *
     * @hide
     */
    @SystemApi
    public static final int PROTECTION_FLAG_MODULE = 0x400000;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>companion</code> value of
     * {@link android.R.attr#protectionLevel}.
     *
     * @hide
     */
    @SystemApi
    public static final int PROTECTION_FLAG_COMPANION = 0x800000;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>retailDemo</code> value of
     * {@link android.R.attr#protectionLevel}.
     *
     * @deprecated This flag has been replaced by the
     *             {@link android.R.string#config_defaultRetailDemo retail demo role} and is a
     *             no-op since {@link Build.VERSION_CODES#VANILLA_ICE_CREAM}.
     *
     * @hide
     */
    @SystemApi
    public static final int PROTECTION_FLAG_RETAIL_DEMO = 0x1000000;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding
     * to the <code>recents</code> value of
     * {@link android.R.attr#protectionLevel}.
     *
     * @hide
     */
    @SystemApi
    public static final int PROTECTION_FLAG_RECENTS = 0x2000000;

    /**
     * Additional flag for {@link #protectionLevel}, corresponding to the <code>role</code> value of
     * {@link android.R.attr#protectionLevel}.
     *
     * @hide
     */
    @SystemApi
    public static final int PROTECTION_FLAG_ROLE = 0x4000000;

    /**
     * Additional flag for {@link #protectionLevel}, correspoinding to the {@code knownSigner} value
     * of {@link android.R.attr#protectionLevel}.
     *
     * @hide
     */
    @SystemApi
    public static final int PROTECTION_FLAG_KNOWN_SIGNER = 0x8000000;

    /** @hide */
    @IntDef(flag = true, prefix = { "PROTECTION_FLAG_" }, value = {
            PROTECTION_FLAG_PRIVILEGED,
            PROTECTION_FLAG_SYSTEM,
            PROTECTION_FLAG_DEVELOPMENT,
            PROTECTION_FLAG_APPOP,
            PROTECTION_FLAG_PRE23,
            PROTECTION_FLAG_INSTALLER,
            PROTECTION_FLAG_VERIFIER,
            PROTECTION_FLAG_PREINSTALLED,
            PROTECTION_FLAG_SETUP,
            PROTECTION_FLAG_INSTANT,
            PROTECTION_FLAG_RUNTIME_ONLY,
            PROTECTION_FLAG_OEM,
            PROTECTION_FLAG_VENDOR_PRIVILEGED,
            PROTECTION_FLAG_SYSTEM_TEXT_CLASSIFIER,
            PROTECTION_FLAG_CONFIGURATOR,
            PROTECTION_FLAG_INCIDENT_REPORT_APPROVER,
            PROTECTION_FLAG_APP_PREDICTOR,
            PROTECTION_FLAG_COMPANION,
            PROTECTION_FLAG_RETAIL_DEMO,
            PROTECTION_FLAG_RECENTS,
            PROTECTION_FLAG_ROLE,
            PROTECTION_FLAG_KNOWN_SIGNER,
            PROTECTION_FLAG_MODULE,
    })

xml中值如何转换成java的protectionLevel变量,这块可以看一下如下代码:
到此就把学员关于权限的protectionLevel保护级别部分进行了全面的剖析。

原文参考:
https://mp.weixin.qq.com/s/3GNkarfoiab7akLtdtZanA

相关推荐
鹏多多6 小时前
flutter使用package_info_plus库获取应用信息的教程
android·前端·flutter
走在路上的菜鸟6 小时前
Android学Dart学习笔记第十五节 类
android·笔记·学习·flutter
2501_916008896 小时前
IOScer 证书到底是什么和怎么使用的完整说明
android·ios·小程序·https·uni-app·iphone·webview
TheNextByte16 小时前
如何将HTC手机中的短信传输到电脑?
智能手机·电脑
00后程序员张7 小时前
iOS 抓包工具实战指南,从代理到数据流,全流程工具分工解析
android·ios·小程序·https·uni-app·iphone·webview
TheNextByte17 小时前
如何将Android短信导出到CSV/TEXT/Excel
android·excel
suki_lynn7 小时前
云手机自动化是什么?2025 年行业真实现状
智能手机
泡泡以安10 小时前
【Android逆向工程】第3章:Java 字节码与 Smali 语法基础
android·java·安卓逆向