Android 11.0 pms中关于启动app时获取app的ActivityInfo信息相关源码分析

news/2024/11/23 2:15:15/

1.前言

在11.0的系统rom定制化开发中,在对于app启动时,通过Launcher调用pms来查询app的相关ActivityInfo的相关信息,然后调用
ams来启动activity,这篇来分析pms中获取app的ActivityInfo的相关信息的相关源码分析

2.pms中关于启动app时获取app的ActivityInfo信息相关源码分析的核心类

frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java

3.pms中关于启动app时获取app的ActivityInfo信息相关源码分析的核心功能分析和实现

private class PackageManagerInternalImpl extends PackageManagerInternal {@Overridepublic ResolveInfo resolveIntent(Intent intent, String resolvedType,int flags, int userId, boolean resolveForStart, int filterCallingUid) {return resolveIntentInternal(intent, resolvedType, flags, userId, resolveForStart, filterCallingUid);}@Overridepublic ResolveInfo resolveService(Intent intent, String resolvedType,int flags, int userId, int callingUid) {return resolveServiceInternal(intent, resolvedType, flags, userId, callingUid);}...}

在PackageManagerService的内部私有类PackageManagerInternalImpl中的相关源码中可以看出,在对
PackageManagerInternal抽象类的实现,PackageManager的接口实现,PMS对外接口实现
resolveIntent(Intent intent, String resolvedType,
                int flags, int userId, boolean resolveForStart, int filterCallingUid)
是具体调用pms的resolveIntentInternal(Intent intent, String resolvedType,
            int flags, int userId, boolean resolveForStart, int filterCallingUid)
来实现对app详细信息的查询

      @Overridepublic ResolveInfo resolveIntent(Intent intent, String resolvedType,int flags, int userId) {return resolveIntentInternal(intent, resolvedType, flags, userId, false,Binder.getCallingUid());}/*** Normally instant apps can only be resolved when they're visible to the caller.* However, if {@code resolveForStart} is {@code true}, all instant apps are visible* since we need to allow the system to start any installed application.*/private ResolveInfo resolveIntentInternal(Intent intent, String resolvedType,int flags, int userId, boolean resolveForStart, int filterCallingUid) {try {Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "resolveIntent");if (!sUserManager.exists(userId)) return null;final int callingUid = Binder.getCallingUid(); system用户// 更新flags,和instant app和direct app有关;flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart);mPermissionManager.enforceCrossUserPermission(callingUid, userId,false /*requireFullPermission*/, false /*checkShell*/, "resolve intent");Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "queryIntentActivities");// 1. 查询安装的应用,看是否有匹配的intentfinal List<ResolveInfo> query = queryIntentActivitiesInternal(intent, resolvedType,flags, filterCallingUid, userId, resolveForStart, true /*allowDynamicSplits*/);Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);// 选择最匹配的activity,因为query是个list;但是这里list大小为1,所以直接返回了final ResolveInfo bestChoice =chooseBestActivity(intent, resolvedType, flags, query, userId);return bestChoice;} finally {Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);}}

通过上述在PackageManagerService.java中的相关源码的分析得知,在
 resolveIntentInternal(Intent intent, String resolvedType,
            int flags, int userId, boolean resolveForStart, int filterCallingUid)
中来查询app的相关详细信息,在chooseBestActivity(intent, resolvedType, flags, query, userId);中来选择最合适的app详细返回,在queryIntentActivitiesInternal中,具体查询app的详细信息

       private @NonNull List<ResolveInfo> queryIntentActivitiesInternal(Intent intent,String resolvedType, int flags, int filterCallingUid, int userId,boolean resolveForStart, boolean allowDynamicSplits) {if (!sUserManager.exists(userId)) return Collections.emptyList();final String instantAppPkgName = getInstantAppPackageName(filterCallingUid);    //为nullmPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,false /* requireFullPermission */, false /* checkShell */,"query intent activities");final String pkgName = intent.getPackage();// com.android.gallery3dComponentName comp = intent.getComponent();// ComponentInfo{com.android.gallery3d/com.android.gallery3d.app.GalleryActivity}if (comp == null) {if (intent.getSelector() != null) {intent = intent.getSelector();comp = intent.getComponent();}}flags = updateFlagsForResolve(flags, userId, intent, filterCallingUid, resolveForStart,comp != null || pkgName != null /*onlyExposedExplicitly*/);// 852992if (comp != null) {final List<ResolveInfo> list = new ArrayList<>(1);// 1. 这里获取activityInfo信息final ActivityInfo ai = getActivityInfo(comp, flags, userId);if (ai != null) {// When specifying an explicit component, we prevent the activity from being// used when either 1) the calling package is normal and the activity is within// an ephemeral application or 2) the calling package is ephemeral and the// activity is not visible to ephemeral applications.final boolean matchInstantApp =(flags & PackageManager.MATCH_INSTANT) != 0;final boolean matchVisibleToInstantAppOnly =(flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0;final boolean matchExplicitlyVisibleOnly =(flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0;final boolean isCallerInstantApp =instantAppPkgName != null;final boolean isTargetSameInstantApp =comp.getPackageName().equals(instantAppPkgName);final boolean isTargetInstantApp =(ai.applicationInfo.privateFlags& ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;final boolean isTargetVisibleToInstantApp =(ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;final boolean isTargetExplicitlyVisibleToInstantApp =isTargetVisibleToInstantApp&& (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;final boolean isTargetHiddenFromInstantApp =!isTargetVisibleToInstantApp|| (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp);final boolean blockResolution =!isTargetSameInstantApp&& ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp)|| (matchVisibleToInstantAppOnly && isCallerInstantApp&& isTargetHiddenFromInstantApp));if (!blockResolution) {final ResolveInfo ri = new ResolveInfo();// 根据activityInfo信息,新建了ResolveInfo信息ri.activityInfo = ai;list.add(ri);}}// 过滤resolveInfo信息,在这里直接返回了return applyPostResolutionFilter(list, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,userId, intent);}// 当cmp不为null的时候,不走下面// readerboolean sortResult = false;boolean addInstant = false;List<ResolveInfo> result;synchronized (mPackages) {if (pkgName == null) {List<CrossProfileIntentFilter> matchingFilters =getMatchingCrossProfileIntentFilters(intent, resolvedType, userId);// Check for results that need to skip the current profile.ResolveInfo xpResolveInfo  = querySkipCurrentProfileIntents(matchingFilters, intent,resolvedType, flags, userId);if (xpResolveInfo != null) {List<ResolveInfo> xpResult = new ArrayList<>(1);xpResult.add(xpResolveInfo);return applyPostResolutionFilter(filterIfNotSystemUser(xpResult, userId), instantAppPkgName,allowDynamicSplits, filterCallingUid, resolveForStart, userId, intent);}....// We have more than one candidate (combining results from current and parent// profile), so we need filtering and sorting.result = filterCandidatesWithDomainPreferredActivitiesLPr(intent, flags, result, xpDomainInfo, userId);sortResult = true;}} else {final PackageParser.Package pkg = mPackages.get(pkgName);result = null;if (pkg != null) {result = filterIfNotSystemUser(mComponentResolver.queryActivities(intent, resolvedType, flags, pkg.activities, userId), userId);}if (result == null || result.size() == 0) {// the caller wants to resolve for a particular package; however, there// were no installed results, so, try to find an ephemeral resultaddInstant = isInstantAppResolutionAllowed(intent, null /*result*/, userId, true /*skipPackageCheck*/);if (result == null) {result = new ArrayList<>();}}}}if (addInstant) {result = maybeAddInstantAppInstaller(result, intent, resolvedType, flags, userId, resolveForStart);}if (sortResult) {Collections.sort(result, RESOLVE_PRIORITY_SORTER);}return applyPostResolutionFilter(result, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,userId, intent);}

在PackageManagerService.java中的相关源码的分析得知,在queryIntentActivitiesInternal()中查询某个app的信息
会在comp != null的时候,调用getActivityInfo(comp, flags, userId);来查询具体信息,
接下来看下getActivityInfo(comp, flags, userId);的相关方法

     @Overridepublic ActivityInfo getActivityInfo(ComponentName component, int flags, int userId) {return getActivityInfoInternal(component, flags, Binder.getCallingUid(), userId);}private ActivityInfo getActivityInfoInternal(ComponentName component, int flags,int filterCallingUid, int userId) {if (!sUserManager.exists(userId)) return null;flags = updateFlagsForComponent(flags, userId, component);if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) {mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId,false /* requireFullPermission */, false /* checkShell */, "get activity info");}synchronized (mPackages) {// 所有的安装包信息都解析到mComponentResolver中了,只要获取下就好了// 1. Activity{e6ed46 com.android.gallery3d/.app.GalleryActivity}PackageParser.Activity a = mComponentResolver.getActivity(component);if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);// 2. 看是否匹配if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {// 3. PackageSetting很重要,包的位置信息;PackageSetting ps = mSettings.mPackages.get(component.getPackageName());if (ps == null) return null;if (filterAppAccessLPr(ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {return null;}// 4. 根据PackageParser.Activity的信息构建ActivityInfo信息,这里返回return PackageParser.generateActivityInfo(a, flags, ps.readUserState(userId), userId);}if (mResolveComponentName.equals(component)) {return PackageParser.generateActivityInfo(mResolveActivity, flags, new PackageUserState(), userId);}}return null;}

在PackageManagerService.java中的相关源码的分析得知,在getActivityInfoInternal(ComponentName component, int flags,
            int filterCallingUid, int userId)中,获取当前的app的相关信息,然后返回一个ActivityInfo对象,就可以在
这里获取app启动的相关详细信息了


http://www.ppmy.cn/news/595406.html

相关文章

【css总结--持续更新中】

一、线性渐变 background : linear - gradient (to left&#xff0c;red ,green ) 1&#xff0e;支持多颜色渐变 2&#xff0e;支持方向&#xff0c; to left ,,,,, to bottom right ,,,,, 3&#xff0e;支持角度的写法90deg 二、径向渐变 径向渐变不同于线性渐变&#xff0c;…

机器学习(二)逻辑回归

Logistic Regression 虽然被称为回归&#xff0c;但其实际上是分类模型&#xff0c;并常用于二分类。 Logistic 回归的本质是&#xff1a;假设数据服从这个分布&#xff0c;然后使用极大似然估计做参数的估计。 逻辑回归API介绍 sklearn.linear_model.LogisticRegression(sol…

LinkedList的底层实现原理(JDK8)

目录 一、知识点回顾二、LinkedList 的 add() 和 remove() 的实现2.1 list.add(e) 实现原理2.2 list.remove(e) 实现原理 一、知识点回顾 双向链表特点&#xff1a; 区间离散&#xff0c;占用内存宽松&#xff0c;空间复杂度小&#xff0c;时间复杂度 O(n)。优点&#xff1a;…

多元分类预测 | Matlab粒子群算法(PSO)优化极限学习机(ELM)的分类预测,多特征输入模型。PSO-ELM分类预测模型

文章目录 效果一览文章概述部分源码参考资料效果一览 文章概述 多元分类预测 | Matlab粒子群算法(PSO)优化极限学习机(ELM)的分类预测,多特征输入模型。PSO-ELM分类预测模型 多特征输入单输出的二分类及多分类模型。程序内注释详细,直接替换数据就可以用。程序语言为matlab,…

浏览器F12开发者工具

浏览器F12开发者工具 1.介绍2.工具附录 1.介绍 F12常用于网站界面测试、调试&#xff0c;分析问题&#xff0c;查看HTML元素、查看响应事件和数据等&#xff0c;还可帮助测试工程师定位前后端Bug&#xff1b; 其中使用最多的功能页面是&#xff1a;元素&#xff08;Elements&…

电影《孤胆特工》看后小记

秀秀推荐的&#xff0c;说把自己感动得哭了。本想看一看星爷或发哥的作品。之前韩剧看过《雏菊》和《初恋这点小事儿》。 这个电影有点像《这个杀手不太冷》&#xff0c;小女孩都是光明与爱的象征&#xff0c;杀手/特工们都是一身绝技&#xff0c;以前杀人众多&#xff0…

进化:从孤胆极客到高效团队_极客学校:学习Windows 7 –无线网络

进化:从孤胆极客到高效团队 In the last two articles, we looked at how to prepare your PC for network access. In this installment, we are going to look at wireless network configuration. 在最后两篇文章中&#xff0c;我们介绍了如何准备您的PC以进行网络访问。 在…

oracle sql 转换成 hive sql -子查询转关联查询(十八),least和greatest函数,时间格式

其他sql格式也在更新中&#xff0c;可直接查看这个系列&#xff0c;要是没有你需要的格式&#xff0c;可在评论或私信我 个人目录 hive的nvl中的子查询 least和greatest函数理论案例&#xff0c;用时间格式格外笔记 least和greatest函数理论 函数例子作用结果leastselect lea…