intcheckComponentPermission(String permission,int pid,int uid,int owningUid,boolean exported){// We might be performing an operation on behalf of an indirect binder// invocation, e.g. via {@link #openContentUri}. Check and adjust the// client identity accordingly before proceeding.Identity tlsIdentity = sCallerIdentity.get();if(tlsIdentity !=null){Slog.d(TAG,"checkComponentPermission() adjusting {pid,uid} to {"+ tlsIdentity.pid +","+ tlsIdentity.uid +"}");
uid = tlsIdentity.uid;
pid = tlsIdentity.pid;}if(pid == MY_PID){returnPackageManager.PERMISSION_GRANTED;}returnActivityManager.checkComponentPermission(permission, uid,
owningUid, exported);}
接着进入到 ActivityManager.checkComponentPermission;
publicstaticintcheckComponentPermission(String permission,int uid,int owningUid,boolean exported){// Root, system server get to do everything.if(uid ==0|| uid ==Process.SYSTEM_UID){returnPackageManager.PERMISSION_GRANTED;}// Isolated processes don't get any permissions.if(UserHandle.isIsolated(uid)){returnPackageManager.PERMISSION_DENIED;}// If there is a uid that owns whatever is being accessed, it has// blanket access to it regardless of the permissions it requires.if(owningUid >=0&&UserHandle.isSameApp(uid, owningUid)){returnPackageManager.PERMISSION_GRANTED;}// If the target is not exported, then nobody else can get to it.if(!exported){/*
RuntimeException here = new RuntimeException("here");
here.fillInStackTrace();
Slog.w(TAG, "Permission denied: checkComponentPermission() owningUid=" + owningUid,
here);
*/returnPackageManager.PERMISSION_DENIED;}if(permission ==null){returnPackageManager.PERMISSION_GRANTED;}try{returnAppGlobals.getPackageManager().checkUidPermission(permission, uid);}catch(RemoteException e){// Should never happen, but if it does... deny!Slog.e(TAG,"PackageManager is dead?!?", e);}returnPackageManager.PERMISSION_DENIED;}
privatevoidgrantPermissionsLPw(PackageParser.Package pkg,boolean replace){finalPackageSetting ps =(PackageSetting) pkg.mExtras;if(ps ==null){return;}//.....以上部分代码省略boolean allowed;boolean allowedSig =false;finalint level = bp.protectionLevel &PermissionInfo.PROTECTION_MASK_BASE;if(level ==PermissionInfo.PROTECTION_NORMAL
|| level ==PermissionInfo.PROTECTION_DANGEROUS){// We grant a normal or dangerous permission if any of the following// are true:// 1) The permission is required// 2) The permission is optional, but was granted in the past// 3) The permission is optional, but was requested by an// app in /system (not /data)//// Otherwise, reject the permission.
allowed =(required || origPermissions.contains(perm)||(isSystemApp(ps)&&!isUpdatedSystemApp(ps)));}elseif(bp.packageSetting ==null){// This permission is invalid; skip it.
allowed =false;}elseif(level ==PermissionInfo.PROTECTION_SIGNATURE){
allowed =grantSignaturePermission(perm, pkg, bp, origPermissions);if(allowed){
allowedSig =true;}}else{
allowed =false;}if(DEBUG_INSTALL){if(gp != ps){}}if(allowed){if(!isSystemApp(ps)&& ps.permissionsFixed){// If this is an existing, non-system package, then// we can't add any new permissions to it.if(!allowedSig &&!gp.grantedPermissions.contains(perm)){// Except... if this is a permission that was added// to the platform (note: need to only do this when// updating the platform).
allowed =isNewPlatformPermissionForPackage(perm, pkg);}}if(allowed){if(!gp.grantedPermissions.contains(perm)){
changedPermission =true;
gp.grantedPermissions.add(perm);
gp.gids =appendInts(gp.gids, bp.gids);}elseif(!ps.haveGids){
gp.gids =appendInts(gp.gids, bp.gids);}}else{Slog.w(TAG,"Not granting permission "+ perm
+" to package "+ pkg.packageName
+" because it was previously installed without");}}//....以下代码省略}
privatebooleangrantSignaturePermission(String perm,PackageParser.Package pkg,BasePermission bp,HashSet<String> origPermissions){boolean allowed;// 这里检查被安装的app的签名(pkg.mSignatures)与声明权限的app的签名(bp.packageSetting.signatures.mSignatures)是否一致,// 如果不一致,则再检查被安装app的签名是否与系统签名(mPlatformPackage.mSignatures)一致。// 如果其中一个是一致的,则赋予被安装app signature权限。// 注意:只要被安装的app的签名是系统签名,则其可以访问任意第三方声明的signature权限。
allowed =(compareSignatures(
bp.packageSetting.signatures.mSignatures, pkg.mSignatures)==PackageManager.SIGNATURE_MATCH)||(compareSignatures(mPlatformPackage.mSignatures, pkg.mSignatures)==PackageManager.SIGNATURE_MATCH);Log.d("PM_DEBUG","allowed1 is "+ allowed +" for pkg "+ pkg.packageName +" permission is "+ perm);// 如果被安装app的签名既不是声明权限的app的签名,也不是系统签名,则继续检查其他标志位。// 首先检查声明的权限是否是privileged权限(也就是signatureOrSystem中的System权限),如果权限是privileged的,//那么对于系统应用(满足isSystemApp(pkg))并且是privileged应用(满足isPrivilegedApp(pkg)),就会赋予if(!allowed &&(bp.protectionLevel
&PermissionInfo.PROTECTION_FLAG_SYSTEM)!=0){if(isSystemApp(pkg)){//是否是系统应用// For updated system applications, a system permission// is granted only if it had been defined by the original application.Log.d("PM_DEBUG","isUpdatedSystemApp(akg) ->"+isUpdatedSystemApp(pkg)+"perm ->"+ perm);if(isUpdatedSystemApp(pkg)){//是否是更新系统的app 比如使用adb install的appfinalPackageSetting sysPs = mSettings
.getDisabledSystemPkgLPr(pkg.packageName);finalGrantedPermissions origGp = sysPs.sharedUser !=null? sysPs.sharedUser : sysPs;if(origGp.grantedPermissions.contains(perm)){// If the original was granted this permission, we take// that grant decision as read and propagate it to the// update.
allowed =true;Log.d("PM_DEBUG","allowed2 is "+ allowed +" for pkg "+ pkg.packageName +" permission is "+ perm);}else{// The system apk may have been updated with an older// version of the one on the data partition, but which// granted a new system permission that it didn't have// before. In this case we do want to allow the app to// now get the new permission if the ancestral apk is// privileged to get it.if(sysPs.pkg !=null&& sysPs.isPrivileged()){for(int j=0;
j<sysPs.pkg.requestedPermissions.size(); j++){if(perm.equals(
sysPs.pkg.requestedPermissions.get(j))){
allowed =true;Log.d("PM_DEBUG","allowed3 is "+ allowed +" for pkg "+ pkg.packageName +" permission is "+ perm);break;}}}}}else{// 不是更新系统app,如果被安装的app是privileged的,则赋予其权限。也就是说,//对于/system/priv-app目录中的app,会获取到权限。这种情况发生在privileged app第一次被安装时,[或者系统被root后,//强行push apk到system/priv-app目录?(有待验证)]。
allowed =isPrivilegedApp(pkg);Log.d("PM_DEBUG","allowed4 is "+ allowed +" for pkg "+ pkg.packageName +" permission is "+ perm);}}}if(!allowed &&(bp.protectionLevel
&PermissionInfo.PROTECTION_FLAG_DEVELOPMENT)!=0){// For development permissions, a development permission// is granted only if it was already granted.
allowed = origPermissions.contains(perm);Log.d("PM_DEBUG","allowed5 is "+ allowed +" for pkg "+ pkg.packageName +" permission is "+ perm);}return allowed;}