Loading core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java +62 −0 Original line number Original line Diff line number Diff line Loading @@ -421,6 +421,8 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, @NonNull @NonNull private String[] mUsesStaticLibrariesSorted; private String[] mUsesStaticLibrariesSorted; private Map<String, Boolean> mFeatureFlagState = new ArrayMap<>(); @NonNull @NonNull public static PackageImpl forParsing(@NonNull String packageName, @NonNull String baseCodePath, public static PackageImpl forParsing(@NonNull String packageName, @NonNull String baseCodePath, @NonNull String codePath, @NonNull TypedArray manifestArray, boolean isCoreApp, @NonNull String codePath, @NonNull TypedArray manifestArray, boolean isCoreApp, Loading Loading @@ -2819,6 +2821,7 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, queriesProviders = Collections.unmodifiableSet(queriesProviders); queriesProviders = Collections.unmodifiableSet(queriesProviders); mimeGroups = Collections.unmodifiableSet(mimeGroups); mimeGroups = Collections.unmodifiableSet(mimeGroups); mKnownActivityEmbeddingCerts = Collections.unmodifiableSet(mKnownActivityEmbeddingCerts); mKnownActivityEmbeddingCerts = Collections.unmodifiableSet(mKnownActivityEmbeddingCerts); mFeatureFlagState = Collections.unmodifiableMap(mFeatureFlagState); } } @Override @Override Loading Loading @@ -3118,6 +3121,8 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, @Override @Override public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) { writeFeatureFlagState(dest); sForBoolean.parcel(this.supportsSmallScreens, dest, flags); sForBoolean.parcel(this.supportsSmallScreens, dest, flags); sForBoolean.parcel(this.supportsNormalScreens, dest, flags); sForBoolean.parcel(this.supportsNormalScreens, dest, flags); sForBoolean.parcel(this.supportsLargeScreens, dest, flags); sForBoolean.parcel(this.supportsLargeScreens, dest, flags); Loading Loading @@ -3267,6 +3272,27 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, dest.writeBoolean(this.mAllowCrossUidActivitySwitchFromBelow); dest.writeBoolean(this.mAllowCrossUidActivitySwitchFromBelow); } } private void writeFeatureFlagState(@NonNull Parcel dest) { // Use a string array to encode flag state. One string per flag in the form `<flag>=<value>` // where value is 0 (disabled), 1 (enabled) or ? (unknown flag or value). int featureFlagCount = this.mFeatureFlagState.size(); String[] featureFlagStateAsArray = new String[featureFlagCount]; var entryIterator = this.mFeatureFlagState.entrySet().iterator(); for (int i = 0; i < featureFlagCount; i++) { var entry = entryIterator.next(); Boolean flagValue = entry.getValue(); if (flagValue == null) { featureFlagStateAsArray[i] = entry.getKey() + "=?"; } else if (flagValue.booleanValue()) { featureFlagStateAsArray[i] = entry.getKey() + "=1"; } else { featureFlagStateAsArray[i] = entry.getKey() + "=0"; } } dest.writeStringArray(featureFlagStateAsArray); } public PackageImpl(Parcel in) { public PackageImpl(Parcel in) { this(in, /* callback */ null); this(in, /* callback */ null); } } Loading @@ -3275,6 +3301,9 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, mCallback = callback; mCallback = callback; // We use the boot classloader for all classes that we load. // We use the boot classloader for all classes that we load. final ClassLoader boot = Object.class.getClassLoader(); final ClassLoader boot = Object.class.getClassLoader(); readFeatureFlagState(in); this.supportsSmallScreens = sForBoolean.unparcel(in); this.supportsSmallScreens = sForBoolean.unparcel(in); this.supportsNormalScreens = sForBoolean.unparcel(in); this.supportsNormalScreens = sForBoolean.unparcel(in); this.supportsLargeScreens = sForBoolean.unparcel(in); this.supportsLargeScreens = sForBoolean.unparcel(in); Loading Loading @@ -3440,6 +3469,27 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, // to mutate this instance before it's finalized. // to mutate this instance before it's finalized. } } private void readFeatureFlagState(@NonNull Parcel in) { // See comment in writeFeatureFlagState() for encoding of flag state. String[] featureFlagStateAsArray = in.createStringArray(); for (String s : featureFlagStateAsArray) { int sepIndex = s.lastIndexOf('='); if (sepIndex >= 0 && sepIndex == s.length() - 2) { String flagPackageAndName = s.substring(0, sepIndex); char c = s.charAt(sepIndex + 1); Boolean flagValue = null; if (c == '1') { flagValue = Boolean.TRUE; } else if (c == '0') { flagValue = Boolean.FALSE; } else if (c != '?') { continue; } this.mFeatureFlagState.put(flagPackageAndName, flagValue); } } } @NonNull @NonNull public static final Creator<PackageImpl> CREATOR = new Creator<PackageImpl>() { public static final Creator<PackageImpl> CREATOR = new Creator<PackageImpl>() { @Override @Override Loading Loading @@ -3660,6 +3710,18 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, return mBaseAppDataDeviceProtectedDirForSystemUser; return mBaseAppDataDeviceProtectedDirForSystemUser; } } @Override public PackageImpl addFeatureFlag( @NonNull String flagPackageAndName, @Nullable Boolean flagValue) { mFeatureFlagState.put(flagPackageAndName, flagValue); return this; } public Map<String, Boolean> getFeatureFlagState() { return mFeatureFlagState; } /** /** * Flags used for a internal bitset. These flags should never be persisted or exposed outside * Flags used for a internal bitset. These flags should never be persisted or exposed outside * of this class. It is expected that PackageCacher explicitly clears itself whenever the * of this class. It is expected that PackageCacher explicitly clears itself whenever the Loading core/java/com/android/internal/pm/pkg/component/AconfigFlags.java +15 −8 Original line number Original line Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.util.Slog; import android.util.Xml; import android.util.Xml; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.pm.pkg.parsing.ParsingPackage; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlPullParser; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser; Loading Loading @@ -199,7 +200,7 @@ public class AconfigFlags { * @return the current value of the given Aconfig flag, or null if there is no such flag * @return the current value of the given Aconfig flag, or null if there is no such flag */ */ @Nullable @Nullable private Boolean getFlagValue(@NonNull String flagPackageAndName) { public Boolean getFlagValue(@NonNull String flagPackageAndName) { Boolean value = mFlagValues.get(flagPackageAndName); Boolean value = mFlagValues.get(flagPackageAndName); if (DEBUG) { if (DEBUG) { Slog.v(LOG_TAG, "Aconfig flag value for " + flagPackageAndName + " = " + value); Slog.v(LOG_TAG, "Aconfig flag value for " + flagPackageAndName + " = " + value); Loading @@ -209,10 +210,13 @@ public class AconfigFlags { /** /** * Check if the element in {@code parser} should be skipped because of the feature flag. * Check if the element in {@code parser} should be skipped because of the feature flag. * @param pkg The package being parsed * @param parser XML parser object currently parsing an element * @param parser XML parser object currently parsing an element * @return true if the element is disabled because of its feature flag * @return true if the element is disabled because of its feature flag */ */ public boolean skipCurrentElement(@NonNull XmlResourceParser parser) { public boolean skipCurrentElement( @NonNull ParsingPackage pkg, @NonNull XmlResourceParser parser) { if (!Flags.manifestFlagging()) { if (!Flags.manifestFlagging()) { return false; return false; } } Loading @@ -227,18 +231,21 @@ public class AconfigFlags { featureFlag = featureFlag.substring(1).strip(); featureFlag = featureFlag.substring(1).strip(); } } final Boolean flagValue = getFlagValue(featureFlag); final Boolean flagValue = getFlagValue(featureFlag); boolean shouldSkip = false; if (flagValue == null) { if (flagValue == null) { Slog.w(LOG_TAG, "Skipping element " + parser.getName() Slog.w(LOG_TAG, "Skipping element " + parser.getName() + " due to unknown feature flag " + featureFlag); + " due to unknown feature flag " + featureFlag); return true; shouldSkip = true; } } else if (flagValue == negated) { // Skip if flag==false && attr=="flag" OR flag==true && attr=="!flag" (negated) // Skip if flag==false && attr=="flag" OR flag==true && attr=="!flag" (negated) if (flagValue == negated) { Slog.i(LOG_TAG, "Skipping element " + parser.getName() Slog.i(LOG_TAG, "Skipping element " + parser.getName() + " behind feature flag " + featureFlag + " = " + flagValue); + " behind feature flag " + featureFlag + " = " + flagValue); return true; shouldSkip = true; } } return false; if (android.content.pm.Flags.includeFeatureFlagsInPackageCacher()) { pkg.addFeatureFlag(featureFlag, flagValue); } return shouldSkip; } } /** /** Loading core/java/com/android/internal/pm/pkg/component/ComponentParseUtils.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -61,7 +61,7 @@ public class ComponentParseUtils { if (type != XmlPullParser.START_TAG) { if (type != XmlPullParser.START_TAG) { continue; continue; } } if (ParsingPackageUtils.getAconfigFlags().skipCurrentElement(parser)) { if (ParsingPackageUtils.getAconfigFlags().skipCurrentElement(pkg, parser)) { continue; continue; } } Loading core/java/com/android/internal/pm/pkg/component/InstallConstraintsTagParser.java +3 −3 Original line number Original line Diff line number Diff line Loading @@ -54,7 +54,7 @@ public class InstallConstraintsTagParser { return input.skip("install-constraints cannot be used by this package"); return input.skip("install-constraints cannot be used by this package"); } } ParseResult<Set<String>> prefixes = parseFingerprintPrefixes(input, res, parser); ParseResult<Set<String>> prefixes = parseFingerprintPrefixes(input, pkg, res, parser); if (prefixes.isSuccess()) { if (prefixes.isSuccess()) { if (validateFingerprintPrefixes(prefixes.getResult())) { if (validateFingerprintPrefixes(prefixes.getResult())) { return input.success(pkg); return input.success(pkg); Loading @@ -68,7 +68,7 @@ public class InstallConstraintsTagParser { } } private static ParseResult<Set<String>> parseFingerprintPrefixes( private static ParseResult<Set<String>> parseFingerprintPrefixes( ParseInput input, Resources res, XmlResourceParser parser) ParseInput input, ParsingPackage pkg, Resources res, XmlResourceParser parser) throws XmlPullParserException, IOException { throws XmlPullParserException, IOException { Set<String> prefixes = new ArraySet<>(); Set<String> prefixes = new ArraySet<>(); int type; int type; Loading @@ -81,7 +81,7 @@ public class InstallConstraintsTagParser { } } return input.success(prefixes); return input.success(prefixes); } else if (type == XmlPullParser.START_TAG) { } else if (type == XmlPullParser.START_TAG) { if (ParsingPackageUtils.getAconfigFlags().skipCurrentElement(parser)) { if (ParsingPackageUtils.getAconfigFlags().skipCurrentElement(pkg, parser)) { continue; continue; } } if (parser.getName().equals(TAG_FINGERPRINT_PREFIX)) { if (parser.getName().equals(TAG_FINGERPRINT_PREFIX)) { Loading core/java/com/android/internal/pm/pkg/component/ParsedActivityUtils.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -393,7 +393,7 @@ public class ParsedActivityUtils { if (type != XmlPullParser.START_TAG) { if (type != XmlPullParser.START_TAG) { continue; continue; } } if (ParsingPackageUtils.getAconfigFlags().skipCurrentElement(parser)) { if (ParsingPackageUtils.getAconfigFlags().skipCurrentElement(pkg, parser)) { continue; continue; } } Loading Loading
core/java/com/android/internal/pm/parsing/pkg/PackageImpl.java +62 −0 Original line number Original line Diff line number Diff line Loading @@ -421,6 +421,8 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, @NonNull @NonNull private String[] mUsesStaticLibrariesSorted; private String[] mUsesStaticLibrariesSorted; private Map<String, Boolean> mFeatureFlagState = new ArrayMap<>(); @NonNull @NonNull public static PackageImpl forParsing(@NonNull String packageName, @NonNull String baseCodePath, public static PackageImpl forParsing(@NonNull String packageName, @NonNull String baseCodePath, @NonNull String codePath, @NonNull TypedArray manifestArray, boolean isCoreApp, @NonNull String codePath, @NonNull TypedArray manifestArray, boolean isCoreApp, Loading Loading @@ -2819,6 +2821,7 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, queriesProviders = Collections.unmodifiableSet(queriesProviders); queriesProviders = Collections.unmodifiableSet(queriesProviders); mimeGroups = Collections.unmodifiableSet(mimeGroups); mimeGroups = Collections.unmodifiableSet(mimeGroups); mKnownActivityEmbeddingCerts = Collections.unmodifiableSet(mKnownActivityEmbeddingCerts); mKnownActivityEmbeddingCerts = Collections.unmodifiableSet(mKnownActivityEmbeddingCerts); mFeatureFlagState = Collections.unmodifiableMap(mFeatureFlagState); } } @Override @Override Loading Loading @@ -3118,6 +3121,8 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, @Override @Override public void writeToParcel(Parcel dest, int flags) { public void writeToParcel(Parcel dest, int flags) { writeFeatureFlagState(dest); sForBoolean.parcel(this.supportsSmallScreens, dest, flags); sForBoolean.parcel(this.supportsSmallScreens, dest, flags); sForBoolean.parcel(this.supportsNormalScreens, dest, flags); sForBoolean.parcel(this.supportsNormalScreens, dest, flags); sForBoolean.parcel(this.supportsLargeScreens, dest, flags); sForBoolean.parcel(this.supportsLargeScreens, dest, flags); Loading Loading @@ -3267,6 +3272,27 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, dest.writeBoolean(this.mAllowCrossUidActivitySwitchFromBelow); dest.writeBoolean(this.mAllowCrossUidActivitySwitchFromBelow); } } private void writeFeatureFlagState(@NonNull Parcel dest) { // Use a string array to encode flag state. One string per flag in the form `<flag>=<value>` // where value is 0 (disabled), 1 (enabled) or ? (unknown flag or value). int featureFlagCount = this.mFeatureFlagState.size(); String[] featureFlagStateAsArray = new String[featureFlagCount]; var entryIterator = this.mFeatureFlagState.entrySet().iterator(); for (int i = 0; i < featureFlagCount; i++) { var entry = entryIterator.next(); Boolean flagValue = entry.getValue(); if (flagValue == null) { featureFlagStateAsArray[i] = entry.getKey() + "=?"; } else if (flagValue.booleanValue()) { featureFlagStateAsArray[i] = entry.getKey() + "=1"; } else { featureFlagStateAsArray[i] = entry.getKey() + "=0"; } } dest.writeStringArray(featureFlagStateAsArray); } public PackageImpl(Parcel in) { public PackageImpl(Parcel in) { this(in, /* callback */ null); this(in, /* callback */ null); } } Loading @@ -3275,6 +3301,9 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, mCallback = callback; mCallback = callback; // We use the boot classloader for all classes that we load. // We use the boot classloader for all classes that we load. final ClassLoader boot = Object.class.getClassLoader(); final ClassLoader boot = Object.class.getClassLoader(); readFeatureFlagState(in); this.supportsSmallScreens = sForBoolean.unparcel(in); this.supportsSmallScreens = sForBoolean.unparcel(in); this.supportsNormalScreens = sForBoolean.unparcel(in); this.supportsNormalScreens = sForBoolean.unparcel(in); this.supportsLargeScreens = sForBoolean.unparcel(in); this.supportsLargeScreens = sForBoolean.unparcel(in); Loading Loading @@ -3440,6 +3469,27 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, // to mutate this instance before it's finalized. // to mutate this instance before it's finalized. } } private void readFeatureFlagState(@NonNull Parcel in) { // See comment in writeFeatureFlagState() for encoding of flag state. String[] featureFlagStateAsArray = in.createStringArray(); for (String s : featureFlagStateAsArray) { int sepIndex = s.lastIndexOf('='); if (sepIndex >= 0 && sepIndex == s.length() - 2) { String flagPackageAndName = s.substring(0, sepIndex); char c = s.charAt(sepIndex + 1); Boolean flagValue = null; if (c == '1') { flagValue = Boolean.TRUE; } else if (c == '0') { flagValue = Boolean.FALSE; } else if (c != '?') { continue; } this.mFeatureFlagState.put(flagPackageAndName, flagValue); } } } @NonNull @NonNull public static final Creator<PackageImpl> CREATOR = new Creator<PackageImpl>() { public static final Creator<PackageImpl> CREATOR = new Creator<PackageImpl>() { @Override @Override Loading Loading @@ -3660,6 +3710,18 @@ public class PackageImpl implements ParsedPackage, AndroidPackageInternal, return mBaseAppDataDeviceProtectedDirForSystemUser; return mBaseAppDataDeviceProtectedDirForSystemUser; } } @Override public PackageImpl addFeatureFlag( @NonNull String flagPackageAndName, @Nullable Boolean flagValue) { mFeatureFlagState.put(flagPackageAndName, flagValue); return this; } public Map<String, Boolean> getFeatureFlagState() { return mFeatureFlagState; } /** /** * Flags used for a internal bitset. These flags should never be persisted or exposed outside * Flags used for a internal bitset. These flags should never be persisted or exposed outside * of this class. It is expected that PackageCacher explicitly clears itself whenever the * of this class. It is expected that PackageCacher explicitly clears itself whenever the Loading
core/java/com/android/internal/pm/pkg/component/AconfigFlags.java +15 −8 Original line number Original line Diff line number Diff line Loading @@ -33,6 +33,7 @@ import android.util.Slog; import android.util.Xml; import android.util.Xml; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.pm.pkg.parsing.ParsingPackage; import com.android.modules.utils.TypedXmlPullParser; import com.android.modules.utils.TypedXmlPullParser; import org.xmlpull.v1.XmlPullParser; import org.xmlpull.v1.XmlPullParser; Loading Loading @@ -199,7 +200,7 @@ public class AconfigFlags { * @return the current value of the given Aconfig flag, or null if there is no such flag * @return the current value of the given Aconfig flag, or null if there is no such flag */ */ @Nullable @Nullable private Boolean getFlagValue(@NonNull String flagPackageAndName) { public Boolean getFlagValue(@NonNull String flagPackageAndName) { Boolean value = mFlagValues.get(flagPackageAndName); Boolean value = mFlagValues.get(flagPackageAndName); if (DEBUG) { if (DEBUG) { Slog.v(LOG_TAG, "Aconfig flag value for " + flagPackageAndName + " = " + value); Slog.v(LOG_TAG, "Aconfig flag value for " + flagPackageAndName + " = " + value); Loading @@ -209,10 +210,13 @@ public class AconfigFlags { /** /** * Check if the element in {@code parser} should be skipped because of the feature flag. * Check if the element in {@code parser} should be skipped because of the feature flag. * @param pkg The package being parsed * @param parser XML parser object currently parsing an element * @param parser XML parser object currently parsing an element * @return true if the element is disabled because of its feature flag * @return true if the element is disabled because of its feature flag */ */ public boolean skipCurrentElement(@NonNull XmlResourceParser parser) { public boolean skipCurrentElement( @NonNull ParsingPackage pkg, @NonNull XmlResourceParser parser) { if (!Flags.manifestFlagging()) { if (!Flags.manifestFlagging()) { return false; return false; } } Loading @@ -227,18 +231,21 @@ public class AconfigFlags { featureFlag = featureFlag.substring(1).strip(); featureFlag = featureFlag.substring(1).strip(); } } final Boolean flagValue = getFlagValue(featureFlag); final Boolean flagValue = getFlagValue(featureFlag); boolean shouldSkip = false; if (flagValue == null) { if (flagValue == null) { Slog.w(LOG_TAG, "Skipping element " + parser.getName() Slog.w(LOG_TAG, "Skipping element " + parser.getName() + " due to unknown feature flag " + featureFlag); + " due to unknown feature flag " + featureFlag); return true; shouldSkip = true; } } else if (flagValue == negated) { // Skip if flag==false && attr=="flag" OR flag==true && attr=="!flag" (negated) // Skip if flag==false && attr=="flag" OR flag==true && attr=="!flag" (negated) if (flagValue == negated) { Slog.i(LOG_TAG, "Skipping element " + parser.getName() Slog.i(LOG_TAG, "Skipping element " + parser.getName() + " behind feature flag " + featureFlag + " = " + flagValue); + " behind feature flag " + featureFlag + " = " + flagValue); return true; shouldSkip = true; } } return false; if (android.content.pm.Flags.includeFeatureFlagsInPackageCacher()) { pkg.addFeatureFlag(featureFlag, flagValue); } return shouldSkip; } } /** /** Loading
core/java/com/android/internal/pm/pkg/component/ComponentParseUtils.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -61,7 +61,7 @@ public class ComponentParseUtils { if (type != XmlPullParser.START_TAG) { if (type != XmlPullParser.START_TAG) { continue; continue; } } if (ParsingPackageUtils.getAconfigFlags().skipCurrentElement(parser)) { if (ParsingPackageUtils.getAconfigFlags().skipCurrentElement(pkg, parser)) { continue; continue; } } Loading
core/java/com/android/internal/pm/pkg/component/InstallConstraintsTagParser.java +3 −3 Original line number Original line Diff line number Diff line Loading @@ -54,7 +54,7 @@ public class InstallConstraintsTagParser { return input.skip("install-constraints cannot be used by this package"); return input.skip("install-constraints cannot be used by this package"); } } ParseResult<Set<String>> prefixes = parseFingerprintPrefixes(input, res, parser); ParseResult<Set<String>> prefixes = parseFingerprintPrefixes(input, pkg, res, parser); if (prefixes.isSuccess()) { if (prefixes.isSuccess()) { if (validateFingerprintPrefixes(prefixes.getResult())) { if (validateFingerprintPrefixes(prefixes.getResult())) { return input.success(pkg); return input.success(pkg); Loading @@ -68,7 +68,7 @@ public class InstallConstraintsTagParser { } } private static ParseResult<Set<String>> parseFingerprintPrefixes( private static ParseResult<Set<String>> parseFingerprintPrefixes( ParseInput input, Resources res, XmlResourceParser parser) ParseInput input, ParsingPackage pkg, Resources res, XmlResourceParser parser) throws XmlPullParserException, IOException { throws XmlPullParserException, IOException { Set<String> prefixes = new ArraySet<>(); Set<String> prefixes = new ArraySet<>(); int type; int type; Loading @@ -81,7 +81,7 @@ public class InstallConstraintsTagParser { } } return input.success(prefixes); return input.success(prefixes); } else if (type == XmlPullParser.START_TAG) { } else if (type == XmlPullParser.START_TAG) { if (ParsingPackageUtils.getAconfigFlags().skipCurrentElement(parser)) { if (ParsingPackageUtils.getAconfigFlags().skipCurrentElement(pkg, parser)) { continue; continue; } } if (parser.getName().equals(TAG_FINGERPRINT_PREFIX)) { if (parser.getName().equals(TAG_FINGERPRINT_PREFIX)) { Loading
core/java/com/android/internal/pm/pkg/component/ParsedActivityUtils.java +1 −1 Original line number Original line Diff line number Diff line Loading @@ -393,7 +393,7 @@ public class ParsedActivityUtils { if (type != XmlPullParser.START_TAG) { if (type != XmlPullParser.START_TAG) { continue; continue; } } if (ParsingPackageUtils.getAconfigFlags().skipCurrentElement(parser)) { if (ParsingPackageUtils.getAconfigFlags().skipCurrentElement(pkg, parser)) { continue; continue; } } Loading