Permiso de tiempo de ejecución de Android Análisis de código fuente de permiso de tiempo de ejecución

Seguimiento del código fuente del permiso de tiempo de ejecución

androide 8.1.0

Código de ventana emergente al solicitar permiso

Cuando la aplicación utiliza requestPermissions para solicitar permisos, el sistema abrirá una ventana de selección de permisos.
inserte la descripción de la imagen aquí

El código fuente está en el archivo packages/apps/PackageInstaller/.
GrantPermissionsActivity.java es una ventana emergente para la asignación de permisos. GrantPermissionsDefaultViewHandler se utiliza para controlar la vista de interfaz de usuario de GrantPermissionsActivity. El
evento de clic de botón se maneja a través de la interfaz GrantPermissionsViewHandler.ResultListener , que es implementado por GrantPermissionsActivity

public class GrantPermissionsActivity extends OverlayTouchActivity
        implements GrantPermissionsViewHandler.ResultListener {
    
    
            mViewHandler = new com.android.packageinstaller.permission.ui.handheld
                    .GrantPermissionsViewHandlerImpl(this, getCallingPackage())
                    .setResultListener(this);
}

GrantPermissionsActivity.java
llama a groupState.mGroup.grantRuntimePermissions para obtener permisos, mGroup es un objeto AppPermissionGroup.java y el proceso de implementación de grantRuntimePermissions se describirá más adelante.

Hablemos primero de la interfaz de usuario en la ventana de solicitud de permiso, como la pantalla "¿Desea permitir que xx haga y administre llamadas?" Este texto es para llamar
a la actualizaciónUi de GrantPermissionsViewHandlerImpl para la visualización de la interfaz

    private boolean showNextPermissionGroupGrantRequest() {
    
    
        final int groupCount = mRequestGrantPermissionGroups.size();

        int currentIndex = 0;
        for (GroupState groupState : mRequestGrantPermissionGroups.values()) {
    
    
            if (groupState.mState == GroupState.STATE_UNKNOWN) {
    
    
                // 应用名称
                CharSequence appLabel = mAppPermissions.getAppLabel();
                
                // groupState.mGroup.getDescription()是权限对应的中文描述
                // 由AppPermissionGroup.java获取,比如“拨打电话和管理通话”
                // 注意就算请求的是一个子权限,但是获取到的将是子项对应的整个组
                // 比如申请android.permission.CALL_PHONE,允许后,会把它对应的整个电话组
                // 权限都获取到(包含拔打电话、读取通话记录、读取手机状态和身份、修改通话记录)
                Spanned message = Html.fromHtml(getString(R.string.permission_warning_template,
                        appLabel, groupState.mGroup.getDescription()), 0); 
                // Set the permission message as the title so it can be announced.
                setTitle(message);
                
                // 此updateUi会进行UI更新,比如请求权限的应用名,请求的权限对应名称,请求应用的应用图标等
                mViewHandler.updateUi(groupState.mGroup.getName(), groupCount, currentIndex,Icon.createWithResource(resources, icon), message,
                groupState.mGroup.isUserSet());
                //......
            }
        }
    }

La clase correspondiente de mViewHandler es GrantPermissionsViewHandlerImpl.java

mMessageView = (TextView) mCurrentDesc.findViewById(R.id.permission_message);

    private void updateDescription() {
    
     // 由updateUi调用
        mIconView.setImageDrawable(mGroupIcon.loadDrawable(mActivity));
        mMessageView.setText(mGroupMessage); // 比如显示“要允许xx拔打电话吗?”
    }

El código de la ventana emergente ha finalizado cuando se solicita el permiso aquí.

A continuación, hablemos de la ventana de permisos de la aplicación en la configuración.

Análisis de la ventana de permiso de la aplicación en la configuración

Configuración – Aplicaciones y notificaciones – Información de la aplicación – xx Aplicaciones – Permisos
inserte la descripción de la imagen aquí
El código fuente de esta ventana es
packages/apps/PackageInstaller/src/com/android/packageinstaller/permission/ui/handheld/AppPermissionsFragment.java

// 设置的权限窗口中改变某应用的权限时,会触发此函数
public boolean onPreferenceChange(final Preference preference, Object newValue) {
    
    
// 只展试部分关键代码
     // key是权限,比如android.permission.CALL_PHONE
     PermissionInfo permInfo = pm.getPermissionInfo(key, 0);
     
     // AppPermissions mAppPermissions
     final AppPermissionGroup title_group
            = mAppPermissions.getPermissionGroup(permInfo.group);
    if (newValue == Boolean.TRUE) {
    
    
        title_group.grantRuntimePermissions(false, filterPermissions); // 取得权限
    } else {
    
    
        title_group.revokeRuntimePermissions(false, filterPermissions); // 取消权限
    }
}

El mAppPermissions anterior es el objeto AppPermissions
title_group proporcionado por mAppPermissions en el código AppPermissions.java

Tanto la clase AppPermissionGroup se usa en la ventana emergente de solicitud de permiso como la interfaz de usuario de permiso solicita permiso en la configuración, y se llama a la función grantRuntimePermissions en la clase.

AppPermissionGroup

paquetes/aplicaciones/PackageInstaller/src/com/android/packageinstaller/permiso/modelo/AppPermissions.java

    // 在构造时在loadPermissionGroups初始化AppPermissionGroup数组
    public AppPermissions(Context context, PackageInfo packageInfo, String[] filterPermissions,
            boolean sortGroups, Runnable onErrorCallback) {
    
    
        mContext = context;
        mPackageInfo = packageInfo;
        mFilterPermissions = filterPermissions;
        mAppLabel = BidiFormatter.getInstance().unicodeWrap(
                packageInfo.applicationInfo.loadSafeLabel(
                context.getPackageManager()).toString());
        mSortGroups = sortGroups;
        mOnErrorCallback = onErrorCallback;
        loadPermissionGroups(); // 调用addPermissionGroupIfNeeded
    }

    private void addPermissionGroupIfNeeded(String permission) {
    
    
        if (getGroupForPermission(permission) != null) {
    
    
            return;
        }

        // AppPermissionGroup对应AppPermissionGroup.java
        AppPermissionGroup group = AppPermissionGroup.create(mContext,
                mPackageInfo, permission);
        if (group == null) {
    
    
            return;
        }

        mGroups.add(group);
    }

title_group corresponde a AppPermissionGroup.java, y AppPermissionGroup.grantRuntimePermissions se llama en esta función

private final PackageManager mPackageManager;
 mPackageManager.grantRuntimePermission(mPackageInfo.packageName,permission.getName(), mUserHandle);
 
 // 会跳到PackageManger中, 最终调用到PMS中
frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
 ```java
     @Override
    public void grantRuntimePermission(String packageName, String name, final int userId) {
    
    
        grantRuntimePermission(packageName, name, userId, false /* Only if not fixed by policy */);
    }

El permiso obtenido por el permiso de tiempo de ejecución se actualizará
a este archivo /data/system/users/0/runtime-permissions.xml a través de privado void writePermissionsSync(int userId)
Para una aplicación, el permiso de grupo telefónico no está autorizado de la siguiente manera

  <pkg name="com.android.sdk23ApiTest.wangyong">
    <item name="android.permission.READ_CALL_LOG" granted="false" flags="1" />
    <item name="android.permission.READ_PHONE_STATE" granted="false" flags="1" />
    <item name="android.permission.CALL_PHONE" granted="false" flags="1" />
    <item name="android.permission.WRITE_CALL_LOG" granted="false" flags="1" />
  </pkg>

Después de permitir el permiso del grupo telefónico, se vuelve así

  <pkg name="com.android.sdk23ApiTest.wangyong">
    <item name="android.permission.READ_CALL_LOG" granted="true" flags="0" />
    <item name="android.permission.READ_PHONE_STATE" granted="true" flags="0" />
    <item name="android.permission.CALL_PHONE" granted="true" flags="0" />
    <item name="android.permission.WRITE_CALL_LOG" granted="true" flags="0" />
  </pkg>

Las versiones anteriores a Android 6 se guardan en el archivo de configuración data/system/packages.xml y el código de la versión anterior no se analizará.
Autor: Demasiado guapo para salir y negarse a reimprimir

Supongo que te gusta

Origin blog.csdn.net/zmlovelx/article/details/129218703
Recomendado
Clasificación