Android7.1 應用組件添加intent-filter priority(優先級)不生效

平臺

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屬性, 其它未測
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章