平台
Android 7.1 + RK3288
问题
为Activity添加组件优先级不生效, 如:
<activity android:name=".HomeLauncher" android:enabled="false"> <intent-filter android:priority="1000"> <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.HOME"/> <category android:name="android.intent.category.DEFAULT"/> <category android:name="android.intent.category.MONKEY"/> </intent-filter> </activity>
分析
android:priority=“1000” 提高优先级不行, 当把数值改成 < 0 是可以生效的.
尝试过许多方法得到的结果都是一样的, 从LOG中可看出, 都被重置为priority=0
D/PackageManager: chooseBestActivity:ResolveInfo{96d95e1 com.android.launcher3/.Launcher m=0x108000}, priority=0 D/PackageManager: chooseBestActivity:ResolveInfo{4598f06 com.test.launcher/.HomeLauncher m=0x108000}, priority=0 D/PackageManager: chooseBestActivity:ResolveInfo{4598f06 com.android.settings/.FallbackHome p=-1000 m=0x108000}, priority=-1000
原因以下代码的注释中已标注清楚:
|-- frameworks/base/services/core/java/com/android/server/pm/PackageManagerService.java
/** * Adjusts the priority of the given intent filter according to policy. * <p> * <ul> * <li>The priority for non privileged applications is capped to '0'</li> * <li>The priority for protected actions on privileged applications is capped to '0'</li> * <li>The priority for unbundled updates to privileged applications is capped to the * priority defined on the system partition</li> * </ul> * <p> * <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is * allowed to obtain any priority on any action. */ private void adjustPriority( List<PackageParser.Activity> systemActivities, ActivityIntentInfo intent) { // nothing to do; priority is fine as-is if (intent.getPriority() <= 0) { return; } final ActivityInfo activityInfo = intent.activity.info; final ApplicationInfo applicationInfo = activityInfo.applicationInfo; //可生效的地方: final boolean privilegedApp = ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0); if (!privilegedApp) { // non-privileged applications can never define a priority >0 Slog.w(TAG, "Non-privileged app; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); intent.setPriority(0); return; } if (systemActivities == null) { // the system package is not disabled; we're parsing the system partition if (isProtectedAction(intent)) { if (mDeferProtectedFilters) { // We can't deal with these just yet. No component should ever obtain a // >0 priority for a protected actions, with ONE exception -- the setup // wizard. The setup wizard, however, cannot be known until we're able to // query it for the category CATEGORY_SETUP_WIZARD. Which we can't do // until all intent filters have been processed. Chicken, meet egg. // Let the filter temporarily have a high priority and rectify the // priorities after all system packages have been scanned. mProtectedFilters.add(intent); if (DEBUG_FILTERS) { Slog.i(TAG, "Protected action; save for later;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } return; } else { if (DEBUG_FILTERS && mSetupWizardPackage == null) { Slog.i(TAG, "No setup wizard;" + " All protected intents capped to priority 0"); } if (intent.activity.info.packageName.equals(mSetupWizardPackage)) { if (DEBUG_FILTERS) { Slog.i(TAG, "Found setup wizard;" + " allow priority " + intent.getPriority() + ";" + " package: " + intent.activity.info.packageName + " activity: " + intent.activity.className + " priority: " + intent.getPriority()); } // setup wizard gets whatever it wants return; } Slog.w(TAG, "Protected action; cap priority to 0;" + " package: " + intent.activity.info.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); intent.setPriority(0); return; } } // privileged apps on the system image get whatever priority they request return; } // privileged app unbundled update ... try to find the same activity final PackageParser.Activity foundActivity = findMatchingActivity(systemActivities, activityInfo); if (foundActivity == null) { // this is a new activity; it cannot obtain >0 priority if (DEBUG_FILTERS) { Slog.i(TAG, "New activity; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); return; } // found activity, now check for filter equivalence // a shallow copy is enough; we modify the list, not its contents final List<ActivityIntentInfo> intentListCopy = new ArrayList<>(foundActivity.intents); final List<ActivityIntentInfo> foundFilters = findFilters(intent); // find matching action subsets final Iterator<String> actionsIterator = intent.actionsIterator(); if (actionsIterator != null) { getIntentListSubset( intentListCopy, new ActionIterGenerator(), actionsIterator); if (intentListCopy.size() == 0) { // no more intents to match; we're not equivalent if (DEBUG_FILTERS) { Slog.i(TAG, "Mismatched action; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); return; } } // find matching category subsets final Iterator<String> categoriesIterator = intent.categoriesIterator(); if (categoriesIterator != null) { getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), categoriesIterator); if (intentListCopy.size() == 0) { // no more intents to match; we're not equivalent if (DEBUG_FILTERS) { Slog.i(TAG, "Mismatched category; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); return; } } // find matching schemes subsets final Iterator<String> schemesIterator = intent.schemesIterator(); if (schemesIterator != null) { getIntentListSubset(intentListCopy, new SchemesIterGenerator(), schemesIterator); if (intentListCopy.size() == 0) { // no more intents to match; we're not equivalent if (DEBUG_FILTERS) { Slog.i(TAG, "Mismatched scheme; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); return; } } // find matching authorities subsets final Iterator<IntentFilter.AuthorityEntry> authoritiesIterator = intent.authoritiesIterator(); if (authoritiesIterator != null) { getIntentListSubset(intentListCopy, new AuthoritiesIterGenerator(), authoritiesIterator); if (intentListCopy.size() == 0) { // no more intents to match; we're not equivalent if (DEBUG_FILTERS) { Slog.i(TAG, "Mismatched authority; cap priority to 0;" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(0); return; } } // we found matching filter(s); app gets the max priority of all intents int cappedPriority = 0; for (int i = intentListCopy.size() - 1; i >= 0; --i) { cappedPriority = Math.max(cappedPriority, intentListCopy.get(i).getPriority()); } if (intent.getPriority() > cappedPriority) { if (DEBUG_FILTERS) { Slog.i(TAG, "Found matching filter(s);" + " cap priority to " + cappedPriority + ";" + " package: " + applicationInfo.packageName + " activity: " + intent.activity.className + " origPrio: " + intent.getPriority()); } intent.setPriority(cappedPriority); return; } // all this for nothing; the requested priority was <= what was on the system }
把应用内置到/system/priv-app后, 解决.
扩展
测试过的几种上不生效的情况
内置到/system/app 不生效
添加 android:sharedUserId=“android.uid.system” 不生效
手动安装方式不生效
目前仅测试过Launcher属性, 其它未测