@Nullable ResolveInfo filterCandidates(final OutboundType type, final Intent original_intent, final @Nullable List<ResolveInfo> candidates,
										   final String tag, final boolean remove) {
		if (candidates == null || candidates.isEmpty()) return null;

		final int my_uid = Process.myUid();
		BackgroundUidFilter bg_uid_filter = null;
		ResolveInfo match = null;
		for (final Iterator<ResolveInfo> iterator = candidates.iterator(); iterator.hasNext(); match = null) {
			final ResolveInfo candidate = iterator.next();
			final ApplicationInfo app_info = candidate.serviceInfo.applicationInfo;
			final int uid = app_info.uid;
			if (uid == my_uid) match = candidate;        // Self UID is always allowed
			else if (mOutboundJudge == null || mOutboundJudge.shouldAllow(type, original_intent, app_info.packageName)) {
				if (mExcludeBackgroundServices) {
					if (bg_uid_filter == null) bg_uid_filter = new BackgroundUidFilter();
					if (bg_uid_filter.isUidNotBackground(uid)) match = candidate;
				} else match = candidate;
			}

			if (match == null) log(tag, CondomEvent.FILTER_BG_SERVICE, app_info.packageName, original_intent.toString());
			if (mDryRun) return candidate;        // Always touch nothing and return the first candidate in dry-run mode.
			if (remove) {
				if (match == null) iterator.remove();
			} else if (match != null) return match;
		}
		return null;
	}
The shared functionality for condom wrappers.

Created by Oasis on 2017/4/21.
library/src/main/java/com/oasisfeng/condom/CondomCore.java