/**
* This is a permission policy that governs over all permission mechanism
* such as permissions, app ops, etc. For example, the policy ensures that
* permission state and app ops is synchronized for cases where there is a
* dependency between permission state (permissions or permission flags)
* and app ops - and vise versa.
*/publicfinalclassPermissionPolicyServiceextendsSystemService{publicPermissionPolicyService(@NonNullContextcontext){super(context);LocalServices.addService(PermissionPolicyInternal.class,newInternal());}}
/**
* Manages all permissions and handles permissions related tasks.
*/publicclassPermissionManagerServiceextendsIPermissionManager.Stub{publicstaticPermissionManagerServiceInternalcreate(Contextcontext,@NonNullObjectexternalLock){finalPermissionManagerServiceInternalpermMgrInt=LocalServices.getService(PermissionManagerServiceInternal.class);if(permMgrInt!=null){returnpermMgrInt;}PermissionManagerServicepermissionService=(PermissionManagerService)ServiceManager.getService("permissionmgr");if(permissionService==null){permissionService=newPermissionManagerService(context,externalLock);ServiceManager.addService("permissionmgr",permissionService);}returnLocalServices.getService(PermissionManagerServiceInternal.class);}@Overridepublicvoiddump(FileDescriptorfd,PrintWriterpw,String[]args){if(!DumpUtils.checkDumpPermission(mContext,TAG,pw)){return;}mContext.getSystemService(PermissionControllerManager.class).dump(fd,args);}}
PermissionControllerManager
publicfinalclassPermissionControllerManager{publicPermissionControllerManager(@NonNullContextcontext,@NonNullHandlerhandler){synchronized(sLock){Pair<Integer,Thread>key=newPair<>(context.getUserId(),handler.getLooper().getThread());ServiceConnector<IPermissionController>remoteService=sRemoteServices.get(key);if(remoteService==null){Intentintent=newIntent(SERVICE_INTERFACE);intent.setPackage(context.getPackageManager().getPermissionControllerPackageName());ResolveInfoserviceInfo=context.getPackageManager().resolveService(intent,0);remoteService=newServiceConnector.Impl<IPermissionController>(ActivityThread.currentApplication()/* context */,newIntent(SERVICE_INTERFACE).setComponent(serviceInfo.getComponentInfo().getComponentName()),0/* bindingFlags */,context.getUserId(),IPermissionController.Stub::asInterface){@OverrideprotectedHandlergetJobHandler(){returnhandler;}@OverrideprotectedlonggetRequestTimeoutMs(){returnREQUEST_TIMEOUT_MILLIS;}@OverrideprotectedlonggetAutoDisconnectTimeoutMs(){returnUNBIND_TIMEOUT_MILLIS;}};sRemoteServices.put(key,remoteService);}mRemoteService=remoteService;}mContext=context;mHandler=handler;}/**
* Dump permission controller state.
*
* @hide
*/publicvoiddump(@NonNullFileDescriptorfd,@NullableString[]args){try{mRemoteService.post(service->service.asBinder().dump(fd,args)).get(REQUEST_TIMEOUT_MILLIS,TimeUnit.MILLISECONDS);}catch(Exceptione){Log.e(TAG,"Could not get dump",e);}}}
PermissionControllerService
publicabstractclassPermissionControllerServiceextendsService{}// packages/apps/PermissionController/src/com/android/permissioncontroller/permission/service/PermissionControllerServiceImpl.javapublicfinalclassPermissionControllerServiceImplextendsPermissionControllerLifecycleService{@Overridepublicvoiddump(FileDescriptorfd,PrintWriterwriter,String[]args){PermissionControllerDumpProtodump;try{dump=BuildersKt.runBlocking(GlobalScope.INSTANCE.getCoroutineContext(),(coroutineScope,continuation)->mServiceModel.onDump(continuation));}catch(Exceptione){Log.e(LOG_TAG,"Cannot produce dump",e);return;}if(ArrayUtils.contains(args,"--proto")){try(OutputStreamout=newFileOutputStream(fd)){dump.writeTo(out);}catch(IOExceptione){Log.e(LOG_TAG,"Cannot write dump",e);}}else{writer.println(dump.toString());writer.flush();}}}
SystemServiceRegistry
publicfinalclassSystemServiceRegistry{/**
* Official published name of the (internal) permission controller service.
*
* @see #getSystemService(String)
* @hide
*/publicstaticfinalStringPERMISSION_CONTROLLER_SERVICE="permission_controller";static{registerService(Context.PERMISSION_CONTROLLER_SERVICE,PermissionControllerManager.class,newCachedServiceFetcher<PermissionControllerManager>(){@OverridepublicPermissionControllerManagercreateService(ContextImplctx){returnnewPermissionControllerManager(ctx.getOuterContext(),ctx.getMainThreadHandler());}});}/**
* Statically registers a system service with the context.
* This method must be called during static initialization only.
*/privatestatic<T>voidregisterService(@NonNullStringserviceName,@NonNullClass<T>serviceClass,@NonNullServiceFetcher<T>serviceFetcher){SYSTEM_SERVICE_NAMES.put(serviceClass,serviceName);SYSTEM_SERVICE_FETCHERS.put(serviceName,serviceFetcher);SYSTEM_SERVICE_CLASS_NAMES.put(serviceName,serviceClass.getSimpleName());}}
android 11 权限校验变更
ContextImpl
classContextImplextendsContext{@OverridepublicintcheckPermission(Stringpermission,intpid,intuid){if(permission==null){thrownewIllegalArgumentException("permission is null");}returnPermissionManager.checkPermission(permission,pid,uid);}}
PermissionManager
publicfinalclassPermissionManager{/** @hide */privatestaticfinalPropertyInvalidatedCache<PermissionQuery,Integer>sPermissionCache=newPropertyInvalidatedCache<PermissionQuery,Integer>(16,CACHE_KEY_PACKAGE_INFO){@OverrideprotectedIntegerrecompute(PermissionQueryquery){returncheckPermissionUncached(query.permission,query.pid,query.uid);}};/** @hide */publicstaticintcheckPermission(@NullableStringpermission,intpid,intuid){returnsPermissionCache.query(newPermissionQuery(permission,pid,uid));}privatestaticfinalclassPermissionQuery{finalStringpermission;finalintpid;finalintuid;PermissionQuery(@NullableStringpermission,intpid,intuid){this.permission=permission;this.pid=pid;this.uid=uid;}}/* @hide */privatestaticintcheckPermissionUncached(@NullableStringpermission,intpid,intuid){finalIActivityManageram=ActivityManager.getService();if(am==null){// Well this is super awkward; we somehow don't have an active ActivityManager// instance. If we're testing a root or system UID, then they totally have whatever// permission this is.finalintappId=UserHandle.getAppId(uid);if(appId==Process.ROOT_UID||appId==Process.SYSTEM_UID){Slog.w(TAG,"Missing ActivityManager; assuming "+uid+" holds "+permission);returnPackageManager.PERMISSION_GRANTED;}Slog.w(TAG,"Missing ActivityManager; assuming "+uid+" does not hold "+permission);returnPackageManager.PERMISSION_DENIED;}try{returnam.checkPermission(permission,pid,uid);}catch(RemoteExceptione){throwe.rethrowFromSystemServer();}}}
PropertyInvalidatedCache
publicabstractclassPropertyInvalidatedCache<Query,Result>{privatefinalLinkedHashMap<Query,Result>mCache;/**
* Get a value from the cache or recompute it.
*/publicResultquery(Queryquery){------------------------------------------------------------------------------for(;;){--------------------------------------------------------------------------finalResultresult=recompute(query);synchronized(mLock){// If someone else invalidated the cache while we did the recomputation, don't// update the cache with a potentially stale result.if(mLastSeenNonce==currentNonce&&result!=null){mCache.put(query,result);}mMisses++;}returnmaybeCheckConsistency(query,result);}}}
ActivityManagerService
publicclassActivityManagerServiceextendsIActivityManager.StubimplementsWatchdog.Monitor,BatteryStatsImpl.BatteryCallback{@OverridepublicintcheckPermission(Stringpermission,intpid,intuid){if(permission==null){returnPackageManager.PERMISSION_DENIED;}returncheckComponentPermission(permission,pid,uid,-1,true);}publicstaticintcheckComponentPermission(Stringpermission,intpid,intuid,intowningUid,booleanexported){if(pid==MY_PID){returnPackageManager.PERMISSION_GRANTED;}// If there is an explicit permission being checked, and this is coming from a process// that has been denied access to that permission, then just deny. Ultimately this may// not be quite right -- it means that even if the caller would have access for another// reason (such as being the owner of the component it is trying to access), it would still// fail. This also means the system and root uids would be able to deny themselves// access to permissions, which... well okay. ¯\_(ツ)_/¯if(permission!=null){synchronized(sActiveProcessInfoSelfLocked){ProcessInfoprocInfo=sActiveProcessInfoSelfLocked.get(pid);if(procInfo!=null&&procInfo.deniedPermissions!=null&&procInfo.deniedPermissions.contains(permission)){returnPackageManager.PERMISSION_DENIED;}}}returnActivityManager.checkComponentPermission(permission,uid,owningUid,exported);}}
publicclassPackageManagerServiceextendsIPackageManager.StubimplementsPackageSender{// NOTE: Can't remove without a major refactor. Keep around for now.@OverridepublicintcheckUidPermission(StringpermName,intuid){try{// Because this is accessed via the package manager service AIDL,// go through the permission manager service AIDLreturnmPermissionManagerService.checkUidPermission(permName,uid);}catch(RemoteExceptionignore){}returnPackageManager.PERMISSION_DENIED;}}
PermissionManagerService
publicclassPermissionManagerServiceextendsIPermissionManager.Stub{@OverridepublicintcheckUidPermission(StringpermName,intuid){// Not using Objects.requireNonNull() here for compatibility reasons.if(permName==null){returnPackageManager.PERMISSION_DENIED;}finalintuserId=UserHandle.getUserId(uid);if(!mUserManagerInt.exists(userId)){returnPackageManager.PERMISSION_DENIED;}finalCheckPermissionDelegatecheckPermissionDelegate;synchronized(mLock){checkPermissionDelegate=mCheckPermissionDelegate;}if(checkPermissionDelegate==null){returncheckUidPermissionImpl(permName,uid);}returncheckPermissionDelegate.checkUidPermission(permName,uid,this::checkUidPermissionImpl);}}
publicfinalclassSettings{privatestaticfinalStringTAG="PackageSettings";privatefinalFilemSettingsFilename;// data/system/packages.xmlprivatefinalFilemBackupSettingsFilename;privatefinalFilemPackageListFilename;privatefinalFilemStoppedPackagesFilename;privatefinalFilemBackupStoppedPackagesFilename;/** The top level directory in configfs for sdcardfs to push the package->uid,userId mappings */privatefinalFilemKernelMappingFilename;/** Map from package name to settings */finalArrayMap<String,PackageSetting>mPackages=newArrayMap<>();// 所有应用的配置信息Settings(FiledataDir,PermissionSettingspermission,Objectlock){mLock=lock;mPermissions=permission;mRuntimePermissionsPersistence=newRuntimePermissionPersistence(mLock);mSystemDir=newFile(dataDir,"system");mSystemDir.mkdirs();FileUtils.setPermissions(mSystemDir.toString(),FileUtils.S_IRWXU|FileUtils.S_IRWXG|FileUtils.S_IROTH|FileUtils.S_IXOTH,-1,-1);mSettingsFilename=newFile(mSystemDir,"packages.xml");// data/system/packages.xmlmBackupSettingsFilename=newFile(mSystemDir,"packages-backup.xml");mPackageListFilename=newFile(mSystemDir,"packages.list");FileUtils.setPermissions(mPackageListFilename,0640,SYSTEM_UID,PACKAGE_INFO_GID);finalFilekernelDir=newFile("/config/sdcardfs");mKernelMappingFilename=kernelDir.exists()?kernelDir:null;// Deprecated: Needed for migrationmStoppedPackagesFilename=newFile(mSystemDir,"packages-stopped.xml");mBackupStoppedPackagesFilename=newFile(mSystemDir,"packages-stopped-backup.xml");}}
PackageSetting
publicclassPackageSettingextendsPackageSettingBase{intappId;@NullablepublicAndroidPackagepkg;/**
* WARNING. The object reference is important. We perform integer equality and NOT
* object equality to check whether shared user settings are the same.
*/SharedUserSettingsharedUser;/**
* Temporary holding space for the shared user ID. While parsing package settings, the
* shared users tag may come after the packages. In this case, we must delay linking the
* shared user setting with the package setting. The shared user ID lets us link the
* two objects.
*/privateintsharedUserId;@VisibleForTesting(visibility=VisibleForTesting.Visibility.PACKAGE)publicPackageSetting(Stringname,StringrealName,FilecodePath,FileresourcePath,StringlegacyNativeLibraryPathString,StringprimaryCpuAbiString,StringsecondaryCpuAbiString,StringcpuAbiOverrideString,longpVersionCode,intpkgFlags,intprivateFlags,intsharedUserId,String[]usesStaticLibraries,long[]usesStaticLibrariesVersions,Map<String,ArraySet<String>>mimeGroups){super(name,realName,codePath,resourcePath,legacyNativeLibraryPathString,primaryCpuAbiString,secondaryCpuAbiString,cpuAbiOverrideString,pVersionCode,pkgFlags,privateFlags,usesStaticLibraries,usesStaticLibrariesVersions);this.sharedUserId=sharedUserId;copyMimeGroups(mimeGroups);}publicbooleanisPrivileged(){return(pkgPrivateFlags&ApplicationInfo.PRIVATE_FLAG_PRIVILEGED)!=0;}publicbooleanisSystem(){return(pkgFlags&ApplicationInfo.FLAG_SYSTEM)!=0;}@OverridepublicPermissionsStategetPermissionsState(){return(sharedUser!=null)?sharedUser.getPermissionsState():super.getPermissionsState();}}
generic_x86_arm:/ $ dumpsys package -h
Package manager dump options:
[-h] [-f] [--checkin] [--all-components] [cmd] ...
--checkin: dump for a checkin
-f: print details of intent filters
-h: print this help
--all-components: include all component names in package dump
cmd may be one of:
apex: list active APEXes and APEX session state
l[ibraries]: list known shared libraries
f[eatures]: list device features
k[eysets]: print known keysets
r[esolvers] [activity|service|receiver|content]: dump intent resolvers
perm[issions]: dump permissions
permission [name ...]: dump declaration and use of given permission
pref[erred]: print preferred package settings
preferred-xml [--full]: print preferred package settings as xml
prov[iders]: dump content providers
p[ackages]: dump installed packages
q[ueries]: dump app queryability calculations
s[hared-users]: dump shared user IDs
m[essages]: print collected runtime messages
v[erifiers]: print package verifier info
d[omain-preferred-apps]: print domains preferred apps
i[ntent-filter-verifiers]|ifv: print intent filter verifier info
version: print database version info
write: write current settings now
installs: details about install sessions
check-permission <permission> <package> [<user>]: does pkg hold perm?
dexopt: dump dexopt state
compiler-stats: dump compiler statistics
service-permissions: dump permissions required by services
<package.name>: info about given package