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

Commit b76f745b authored by Jeremy Meyer's avatar Jeremy Meyer
Browse files

Only check for xml flags when we know there are any

Test: Automation
Fixes: 377974898
Fixes: 398541237
Fixes: 398086579
Fixes: 396884481
Fixes: 396992602
Flag: android.content.res.layout_readwrite_flags
Change-Id: Ibdabb27689a95eba7b53490ea8651c947beca226
parent adfd1c77
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -408,7 +408,7 @@ public final class ApkAssets {
        Objects.requireNonNull(fileName, "fileName");
        synchronized (this) {
            long nativeXmlPtr = nativeOpenXml(mNativePtr, fileName);
            try (XmlBlock block = new XmlBlock(null, nativeXmlPtr)) {
            try (XmlBlock block = new XmlBlock(null, nativeXmlPtr, true)) {
                XmlResourceParser parser = block.newParser();
                // If nativeOpenXml doesn't throw, it will always return a valid native pointer,
                // which makes newParser always return non-null. But let's be careful.
+7 −4
Original line number Diff line number Diff line
@@ -1190,7 +1190,7 @@ public final class AssetManager implements AutoCloseable {
     */
    public @NonNull XmlResourceParser openXmlResourceParser(int cookie, @NonNull String fileName)
            throws IOException {
        try (XmlBlock block = openXmlBlockAsset(cookie, fileName)) {
        try (XmlBlock block = openXmlBlockAsset(cookie, fileName, true)) {
            XmlResourceParser parser = block.newParser(ID_NULL, new Validator());
            // If openXmlBlockAsset doesn't throw, it will always return an XmlBlock object with
            // a valid native pointer, which makes newParser always return non-null. But let's
@@ -1209,7 +1209,7 @@ public final class AssetManager implements AutoCloseable {
     * @hide
     */
    @NonNull XmlBlock openXmlBlockAsset(@NonNull String fileName) throws IOException {
        return openXmlBlockAsset(0, fileName);
        return openXmlBlockAsset(0, fileName, true);
    }

    /**
@@ -1218,9 +1218,11 @@ public final class AssetManager implements AutoCloseable {
     *
     * @param cookie Identifier of the package to be opened.
     * @param fileName Name of the asset to retrieve.
     * @param usesFeatureFlags Whether the resources uses feature flags
     * @hide
     */
    @NonNull XmlBlock openXmlBlockAsset(int cookie, @NonNull String fileName) throws IOException {
    @NonNull XmlBlock openXmlBlockAsset(int cookie, @NonNull String fileName,
            boolean usesFeatureFlags) throws IOException {
        Objects.requireNonNull(fileName, "fileName");
        synchronized (this) {
            ensureOpenLocked();
@@ -1229,7 +1231,8 @@ public final class AssetManager implements AutoCloseable {
            if (xmlBlock == 0) {
                throw new FileNotFoundException("Asset XML file: " + fileName);
            }
            final XmlBlock block = new XmlBlock(this, xmlBlock);

            final XmlBlock block = new XmlBlock(this, xmlBlock, usesFeatureFlags);
            incRefsLocked(block.hashCode());
            return block;
        }
+21 −2
Original line number Diff line number Diff line
@@ -2568,7 +2568,7 @@ public class Resources {
            impl.getValue(id, value, true);
            if (value.type == TypedValue.TYPE_STRING) {
                return loadXmlResourceParser(value.string.toString(), id,
                        value.assetCookie, type);
                        value.assetCookie, type, value.usesFeatureFlags);
            }
            throw new NotFoundException("Resource ID #0x" + Integer.toHexString(id)
                    + " type #0x" + Integer.toHexString(value.type) + " is not valid");
@@ -2591,7 +2591,26 @@ public class Resources {
    @UnsupportedAppUsage
    XmlResourceParser loadXmlResourceParser(String file, int id, int assetCookie,
                                            String type) throws NotFoundException {
        return mResourcesImpl.loadXmlResourceParser(file, id, assetCookie, type);
        return loadXmlResourceParser(file, id, assetCookie, type, true);
    }

    /**
     * Loads an XML parser for the specified file.
     *
     * @param file the path for the XML file to parse
     * @param id the resource identifier for the file
     * @param assetCookie the asset cookie for the file
     * @param type the type of resource (used for logging)
     * @param usesFeatureFlags whether the xml has read/write feature flags
     * @return a parser for the specified XML file
     * @throws NotFoundException if the file could not be loaded
     * @hide
     */
    @NonNull
    @VisibleForTesting
    public XmlResourceParser loadXmlResourceParser(String file, int id, int assetCookie,
            String type, boolean usesFeatureFlags) throws NotFoundException {
        return mResourcesImpl.loadXmlResourceParser(file, id, assetCookie, type, usesFeatureFlags);
    }

    /**
+10 −7
Original line number Diff line number Diff line
@@ -276,7 +276,8 @@ public class ResourcesImpl {
    }

    @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
    void getValue(@AnyRes int id, TypedValue outValue, boolean resolveRefs)
    @VisibleForTesting
    public void getValue(@AnyRes int id, TypedValue outValue, boolean resolveRefs)
            throws NotFoundException {
        boolean found = mAssets.getResourceValue(id, 0, outValue, resolveRefs);
        if (found) {
@@ -1057,8 +1058,8 @@ public class ResourcesImpl {
            int id, int density, String file)
            throws IOException, XmlPullParserException {
        try (
                XmlResourceParser rp =
                        loadXmlResourceParser(file, id, value.assetCookie, "drawable")
                XmlResourceParser rp = loadXmlResourceParser(
                        file, id, value.assetCookie, "drawable", value.usesFeatureFlags)
        ) {
            return Drawable.createFromXmlForDensity(wrapper, rp, density, null);
        }
@@ -1092,7 +1093,7 @@ public class ResourcesImpl {
        try {
            if (file.endsWith("xml")) {
                final XmlResourceParser rp = loadXmlResourceParser(
                        file, id, value.assetCookie, "font");
                        file, id, value.assetCookie, "font", value.usesFeatureFlags);
                final FontResourcesParser.FamilyResourceEntry familyEntry =
                        FontResourcesParser.parse(rp, wrapper);
                if (familyEntry == null) {
@@ -1286,7 +1287,7 @@ public class ResourcesImpl {
        if (file.endsWith(".xml")) {
            try {
                final XmlResourceParser parser = loadXmlResourceParser(
                        file, id, value.assetCookie, "ComplexColor");
                        file, id, value.assetCookie, "ComplexColor", value.usesFeatureFlags);

                final AttributeSet attrs = Xml.asAttributeSet(parser);
                int type;
@@ -1331,12 +1332,13 @@ public class ResourcesImpl {
     * @param id the resource identifier for the file
     * @param assetCookie the asset cookie for the file
     * @param type the type of resource (used for logging)
     * @param usesFeatureFlags whether the xml has read/write feature flags
     * @return a parser for the specified XML file
     * @throws NotFoundException if the file could not be loaded
     */
    @NonNull
    XmlResourceParser loadXmlResourceParser(@NonNull String file, @AnyRes int id, int assetCookie,
            @NonNull String type)
            @NonNull String type, boolean usesFeatureFlags)
            throws NotFoundException {
        if (id != 0) {
            try {
@@ -1355,7 +1357,8 @@ public class ResourcesImpl {

                    // Not in the cache, create a new block and put it at
                    // the next slot in the cache.
                    final XmlBlock block = mAssets.openXmlBlockAsset(assetCookie, file);
                    final XmlBlock block =
                            mAssets.openXmlBlockAsset(assetCookie, file, usesFeatureFlags);
                    if (block != null) {
                        final int pos = (mLastCachedXmlBlockIndex + 1) % num;
                        mLastCachedXmlBlockIndex = pos;
+8 −2
Original line number Diff line number Diff line
@@ -59,12 +59,14 @@ public final class XmlBlock implements AutoCloseable {
        mAssets = null;
        mNative = nativeCreate(data, 0, data.length);
        mStrings = new StringBlock(nativeGetStringBlock(mNative), false);
        mUsesFeatureFlags = true;
    }

    public XmlBlock(byte[] data, int offset, int size) {
        mAssets = null;
        mNative = nativeCreate(data, offset, size);
        mStrings = new StringBlock(nativeGetStringBlock(mNative), false);
        mUsesFeatureFlags = true;
    }

    @Override
@@ -346,7 +348,8 @@ public final class XmlBlock implements AutoCloseable {
            if (ev == ERROR_BAD_DOCUMENT) {
                throw new XmlPullParserException("Corrupt XML binary file");
            }
            if (useLayoutReadwrite() && ev == START_TAG) {

            if (useLayoutReadwrite() && mUsesFeatureFlags && ev == START_TAG) {
                AconfigFlags flags = ParsingPackageUtils.getAconfigFlags();
                if (flags.skipCurrentElement(/* pkg= */ null, this)) {
                    int depth = 1;
@@ -678,10 +681,11 @@ public final class XmlBlock implements AutoCloseable {
     *  are doing!  The given native object must exist for the entire lifetime
     *  of this newly creating XmlBlock.
     */
    XmlBlock(@Nullable AssetManager assets, long xmlBlock) {
    XmlBlock(@Nullable AssetManager assets, long xmlBlock, boolean usesFeatureFlags) {
        mAssets = assets;
        mNative = xmlBlock;
        mStrings = new StringBlock(nativeGetStringBlock(xmlBlock), false);
        mUsesFeatureFlags = usesFeatureFlags;
    }

    private @Nullable final AssetManager mAssets;
@@ -690,6 +694,8 @@ public final class XmlBlock implements AutoCloseable {
    private boolean mOpen = true;
    private int mOpenCount = 1;

    private final boolean mUsesFeatureFlags;

    private static final native long nativeCreate(byte[] data,
                                                 int offset,
                                                 int size);
Loading