Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e48c137a authored by Fabrice Di Meglio's avatar Fabrice Di Meglio
Browse files

Add IntentFilter auto verification - part 5

- optimize IntentFilter verification: dont do stuff we dont want
if we dont need to do them.

- improve IntentFilter candidates filtering and also improve
at the same time fix for bug #20128771: we can return the candidates
list rigth the way if the Intent is not related to a Web data URI and
include the "undefined verification state" ones if the first filtering
pass does not leave any.

Change-Id: I19f5c060f58b93530e37b4425d19ed23d2a0f4c0
parent 53f35f4a
Loading
Loading
Loading
Loading
+2 −1
Original line number Diff line number Diff line
@@ -2778,7 +2778,7 @@ public class PackageParser {
    }

    /**
     * Check if one of the IntentFilter as an action VIEW and a HTTP/HTTPS data URI
     * Check if one of the IntentFilter as both actions DEFAULT / VIEW and a HTTP/HTTPS data URI
     */
    private static boolean hasDomainURLs(Package pkg) {
        if (pkg == null || pkg.activities == null) return false;
@@ -2792,6 +2792,7 @@ public class PackageParser {
            for (int m=0; m<countFilters; m++) {
                ActivityIntentInfo aii = filters.get(m);
                if (!aii.hasAction(Intent.ACTION_VIEW)) continue;
                if (!aii.hasAction(Intent.ACTION_DEFAULT)) continue;
                if (aii.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
                        aii.hasDataScheme(IntentFilter.SCHEME_HTTPS)) {
                    Slog.d(TAG, "hasDomainURLs:true for package:" + pkg.packageName);
+41 −17
Original line number Diff line number Diff line
@@ -3967,10 +3967,9 @@ public class PackageManagerService extends IPackageManager.Stub {
                    Collections.sort(result, mResolvePrioritySorter);
                }
                result = filterIfNotPrimaryUser(result, userId);
                if (result.size() > 1) {
                if (result.size() > 1 && hasWebURI(intent)) {
                    return filterCandidatesWithDomainPreferedActivitiesLPr(result);
                }
                return result;
            }
            final PackageParser.Package pkg = mPackages.get(pkgName);
@@ -4002,16 +4001,30 @@ public class PackageManagerService extends IPackageManager.Stub {
        return resolveInfos;
    }
    private static boolean hasWebURI(Intent intent) {
        if (intent.getData() == null) {
            return false;
        }
        final String scheme = intent.getScheme();
        if (TextUtils.isEmpty(scheme)) {
            return false;
        }
        return scheme.equals(IntentFilter.SCHEME_HTTP) || scheme.equals(IntentFilter.SCHEME_HTTPS);
    }
    private List<ResolveInfo> filterCandidatesWithDomainPreferedActivitiesLPr(
            List<ResolveInfo> candidates) {
        if (DEBUG_PREFERRED) {
            Slog.v("TAG", "Filtering results with prefered activities. Candidates count: " +
                    candidates.size());
        }
        final int userId = UserHandle.getCallingUserId();
        ArrayList<ResolveInfo> result = new ArrayList<ResolveInfo>();
        ArrayList<ResolveInfo> undefinedList = new ArrayList<ResolveInfo>();
        ArrayList<ResolveInfo> neverList = new ArrayList<ResolveInfo>();
        ArrayList<ResolveInfo> matchAllList = new ArrayList<ResolveInfo>();
        synchronized (mPackages) {
            final int count = candidates.size();
            // First, try to use the domain prefered App
@@ -4022,11 +4035,12 @@ public class PackageManagerService extends IPackageManager.Stub {
                if (ps != null) {
                    // Try to get the status from User settings first
                    int status = getDomainVerificationStatusLPr(ps, userId);
                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS ||
                            status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
                    if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_ALWAYS) {
                        result.add(info);
                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER) {
                        neverList.add(info);
                    } else if (status == INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED) {
                        undefinedList.add(info);
                    }
                    // Add to the special match all list (Browser use case)
                    if (info.handleAllWebDataURI) {
@@ -4036,15 +4050,16 @@ public class PackageManagerService extends IPackageManager.Stub {
            }
            // If there is nothing selected, add all candidates and remove the ones that the User
            // has explicitely put into the INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_NEVER state and
            // also remove any .
            // If there is still none after this pass, add all Browser Apps and let the User decide
            // with the Disambiguation dialog if there are several ones.
            // also remove any Browser Apps ones.
            // If there is still none after this pass, add all undefined one and Browser Apps and
            // let the User decide with the Disambiguation dialog if there are several ones.
            if (result.size() == 0) {
                result.addAll(candidates);
            }
            result.removeAll(neverList);
            result.removeAll(matchAllList);
            if (result.size() == 0) {
                result.addAll(undefinedList);
                result.addAll(matchAllList);
            }
        }
@@ -11296,6 +11311,12 @@ public class PackageManagerService extends IPackageManager.Stub {
            return;
        }
        final boolean hasDomainURLs = hasDomainURLs(pkg);
        if (!hasDomainURLs) {
            Slog.d(TAG, "No domain URLs, so no need to verify any IntentFilter!");
            return;
        }
        Slog.d(TAG, "Checking for userId:" + userId + " if any IntentFilter from the " + size
                + " Activities needs verification ...");
@@ -11303,21 +11324,25 @@ public class PackageManagerService extends IPackageManager.Stub {
        int count = 0;
        final String packageName = pkg.packageName;
        ArrayList<String> allHosts = new ArrayList<>();
        synchronized (mPackages) {
            for (PackageParser.Activity a : pkg.activities) {
                for (ActivityIntentInfo filter : a.intents) {
                    boolean needFilterVerification = filter.needsVerification() &&
                            !filter.isVerified();
                    if (needFilterVerification && needNetworkVerificationLPr(filter)) {
                    boolean needsFilterVerification = filter.needsVerification();
                    if (needsFilterVerification && needsNetworkVerificationLPr(filter)) {
                        Slog.d(TAG, "Verification needed for IntentFilter:" + filter.toString());
                        mIntentFilterVerifier.addOneIntentFilterVerification(
                                verifierUid, userId, verificationId, filter, packageName);
                        count++;
                    } else {
                        Slog.d(TAG, "No verification needed for IntentFilter:" + filter.toString());
                    } else if (!needsFilterVerification) {
                        Slog.d(TAG, "No verification needed for IntentFilter:"
                                + filter.toString());
                        if (hasValidDomains(filter)) {
                            allHosts.addAll(filter.getHostsList());
                        }
                    } else {
                        Slog.d(TAG, "Verification already done for IntentFilter:"
                                + filter.toString());
                    }
                }
            }
@@ -11329,15 +11354,14 @@ public class PackageManagerService extends IPackageManager.Stub {
                    + (count > 1 ? "s" : "") +  " for userId:" + userId + "!");
        } else {
            Slog.d(TAG, "No need to start any IntentFilter verification!");
            if (allHosts.size() > 0 && hasDomainURLs(pkg) &&
                    mSettings.createIntentFilterVerificationIfNeededLPw(
            if (allHosts.size() > 0 && mSettings.createIntentFilterVerificationIfNeededLPw(
                    packageName, allHosts) != null) {
                scheduleWriteSettingsLocked();
            }
        }
    }
    private boolean needNetworkVerificationLPr(ActivityIntentInfo filter) {
    private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
        final ComponentName cn  = filter.activity.getComponentName();
        final String packageName = cn.getPackageName();