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

Commit 4ee8a655 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

PersistableBundle for Ravenwood, with CTS.

We have the XML interfaces from libcore, but the implementations
there are tied closely to things like StringPool.  We thankfully
have our own human-readable XML serializer that we could use, but
there's unfortunately not a good pull parser.

To get us unstuck for the moment, pivot the internals to
unconditionally use the binary XML format, which at least we
know is thoroughly tested, and any data written through this path
can then also be parsed.

This is enough to support PersistableBundle, and we'll circle back
to get ourselves a human-readable XML implementation in the future.

Bug: 292141694
Test: atest-dev CtsOsTestCasesRavenwood CtsOsTestCases
Change-Id: I875a3a2b0e95e52861afe187e2a5e9f1e740d8d5
parent 9e4b2c12
Loading
Loading
Loading
Loading
+68 −0
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import com.android.internal.util.ArtBinaryXmlPullParser;
import com.android.internal.util.ArtBinaryXmlSerializer;
import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.XmlUtils;
import com.android.modules.utils.BinaryXmlPullParser;
import com.android.modules.utils.BinaryXmlSerializer;
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
@@ -38,6 +39,7 @@ import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlPullParserFactory;
import org.xmlpull.v1.XmlSerializer;

import java.io.BufferedInputStream;
@@ -115,6 +117,7 @@ public class Xml {
    /**
     * Returns a new pull parser with namespace support.
     */
    @android.ravenwood.annotation.RavenwoodReplace
    public static XmlPullParser newPullParser() {
        try {
            XmlPullParser parser = XmlObjectFactory.newXmlPullParser();
@@ -126,6 +129,12 @@ public class Xml {
        }
    }

    /** @hide */
    public static XmlPullParser newPullParser$ravenwood() {
        // TODO: remove once we're linking against libcore
        return new BinaryXmlPullParser();
    }

    /**
     * Creates a new {@link TypedXmlPullParser} which is optimized for use
     * inside the system, typically by supporting only a basic set of features.
@@ -136,10 +145,17 @@ public class Xml {
     * @hide
     */
    @SuppressWarnings("AndroidFrameworkEfficientXml")
    @android.ravenwood.annotation.RavenwoodReplace
    public static @NonNull TypedXmlPullParser newFastPullParser() {
        return XmlUtils.makeTyped(newPullParser());
    }

    /** @hide */
    public static TypedXmlPullParser newFastPullParser$ravenwood() {
        // TODO: remove once we're linking against libcore
        return new BinaryXmlPullParser();
    }

    /**
     * Creates a new {@link XmlPullParser} that reads XML documents using a
     * custom binary wire protocol which benchmarking has shown to be 8.5x
@@ -148,10 +164,17 @@ public class Xml {
     *
     * @hide
     */
    @android.ravenwood.annotation.RavenwoodReplace
    public static @NonNull TypedXmlPullParser newBinaryPullParser() {
        return new ArtBinaryXmlPullParser();
    }

    /** @hide */
    public static TypedXmlPullParser newBinaryPullParser$ravenwood() {
        // TODO: remove once we're linking against libcore
        return new BinaryXmlPullParser();
    }

    /**
     * Creates a new {@link XmlPullParser} which is optimized for use inside the
     * system, typically by supporting only a basic set of features.
@@ -166,6 +189,7 @@ public class Xml {
     *
     * @hide
     */
    @android.ravenwood.annotation.RavenwoodReplace
    public static @NonNull TypedXmlPullParser resolvePullParser(@NonNull InputStream in)
            throws IOException {
        final byte[] magic = new byte[4];
@@ -198,13 +222,33 @@ public class Xml {
        return xml;
    }

    /** @hide */
    public static @NonNull TypedXmlPullParser resolvePullParser$ravenwood(@NonNull InputStream in)
            throws IOException {
        // TODO: remove once we're linking against libcore
        final TypedXmlPullParser xml = new BinaryXmlPullParser();
        try {
            xml.setInput(in, StandardCharsets.UTF_8.name());
        } catch (XmlPullParserException e) {
            throw new IOException(e);
        }
        return xml;
    }

    /**
     * Creates a new xml serializer.
     */
    @android.ravenwood.annotation.RavenwoodReplace
    public static XmlSerializer newSerializer() {
        return XmlObjectFactory.newXmlSerializer();
    }

    /** @hide */
    public static XmlSerializer newSerializer$ravenwood() {
        // TODO: remove once we're linking against libcore
        return new BinaryXmlSerializer();
    }

    /**
     * Creates a new {@link XmlSerializer} which is optimized for use inside the
     * system, typically by supporting only a basic set of features.
@@ -215,10 +259,17 @@ public class Xml {
     * @hide
     */
    @SuppressWarnings("AndroidFrameworkEfficientXml")
    @android.ravenwood.annotation.RavenwoodReplace
    public static @NonNull TypedXmlSerializer newFastSerializer() {
        return XmlUtils.makeTyped(new FastXmlSerializer());
    }

    /** @hide */
    public static @NonNull TypedXmlSerializer newFastSerializer$ravenwood() {
        // TODO: remove once we're linking against libcore
        return new BinaryXmlSerializer();
    }

    /**
     * Creates a new {@link XmlSerializer} that writes XML documents using a
     * custom binary wire protocol which benchmarking has shown to be 4.4x
@@ -227,10 +278,17 @@ public class Xml {
     *
     * @hide
     */
    @android.ravenwood.annotation.RavenwoodReplace
    public static @NonNull TypedXmlSerializer newBinarySerializer() {
        return new ArtBinaryXmlSerializer();
    }

    /** @hide */
    public static @NonNull TypedXmlSerializer newBinarySerializer$ravenwood() {
        // TODO: remove once we're linking against libcore
        return new BinaryXmlSerializer();
    }

    /**
     * Creates a new {@link XmlSerializer} which is optimized for use inside the
     * system, typically by supporting only a basic set of features.
@@ -245,6 +303,7 @@ public class Xml {
     *
     * @hide
     */
    @android.ravenwood.annotation.RavenwoodReplace
    public static @NonNull TypedXmlSerializer resolveSerializer(@NonNull OutputStream out)
            throws IOException {
        final TypedXmlSerializer xml;
@@ -257,6 +316,15 @@ public class Xml {
        return xml;
    }

    /** @hide */
    public static @NonNull TypedXmlSerializer resolveSerializer$ravenwood(@NonNull OutputStream out)
            throws IOException {
        // TODO: remove once we're linking against libcore
        final TypedXmlSerializer xml = new BinaryXmlSerializer();
        xml.setOutput(out, StandardCharsets.UTF_8.name());
        return xml;
    }

    /**
     * Copy the first XML document into the second document.
     * <p>
+12 −3
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import android.util.CharsetUtils;

import com.android.modules.utils.FastDataInput;

import dalvik.system.VMRuntime;

import java.io.DataInput;
import java.io.IOException;
import java.io.InputStream;
@@ -35,13 +37,14 @@ import java.util.concurrent.atomic.AtomicReference;
 */
public class ArtFastDataInput extends FastDataInput {
    private static AtomicReference<ArtFastDataInput> sInCache = new AtomicReference<>();
    private static VMRuntime sRuntime = VMRuntime.getRuntime();

    private final long mBufferPtr;

    public ArtFastDataInput(@NonNull InputStream in, int bufferSize) {
        super(in, bufferSize);

        mBufferPtr = mRuntime.addressOf(mBuffer);
        mBufferPtr = sRuntime.addressOf(mBuffer);
    }

    /**
@@ -66,6 +69,7 @@ public class ArtFastDataInput extends FastDataInput {
     * Release a {@link ArtFastDataInput} to potentially be recycled. You must not
     * interact with the object after releasing it.
     */
    @Override
    public void release() {
        super.release();

@@ -75,6 +79,11 @@ public class ArtFastDataInput extends FastDataInput {
        }
    }

    @Override
    public byte[] newByteArray(int bufferSize) {
        return (byte[]) sRuntime.newNonMovableArray(byte.class, bufferSize);
    }

    @Override
    public String readUTF() throws IOException {
        // Attempt to read directly from buffer space if there's enough room,
@@ -86,9 +95,9 @@ public class ArtFastDataInput extends FastDataInput {
            mBufferPos += len;
            return res;
        } else {
            final byte[] tmp = (byte[]) mRuntime.newNonMovableArray(byte.class, len + 1);
            final byte[] tmp = (byte[]) sRuntime.newNonMovableArray(byte.class, len + 1);
            readFully(tmp, 0, len);
            return CharsetUtils.fromModifiedUtf8Bytes(mRuntime.addressOf(tmp), 0, len);
            return CharsetUtils.fromModifiedUtf8Bytes(sRuntime.addressOf(tmp), 0, len);
        }
    }
}
+11 −3
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import android.util.CharsetUtils;

import com.android.modules.utils.FastDataOutput;

import dalvik.system.VMRuntime;

import java.io.DataOutput;
import java.io.IOException;
import java.io.OutputStream;
@@ -35,13 +37,14 @@ import java.util.concurrent.atomic.AtomicReference;
 */
public class ArtFastDataOutput extends FastDataOutput {
    private static AtomicReference<ArtFastDataOutput> sOutCache = new AtomicReference<>();
    private static VMRuntime sRuntime = VMRuntime.getRuntime();

    private final long mBufferPtr;

    public ArtFastDataOutput(@NonNull OutputStream out, int bufferSize) {
        super(out, bufferSize);

        mBufferPtr = mRuntime.addressOf(mBuffer);
        mBufferPtr = sRuntime.addressOf(mBuffer);
    }

    /**
@@ -72,6 +75,11 @@ public class ArtFastDataOutput extends FastDataOutput {
        }
    }

    @Override
    public byte[] newByteArray(int bufferSize) {
        return (byte[]) sRuntime.newNonMovableArray(byte.class, bufferSize);
    }

    @Override
    public void writeUTF(String s) throws IOException {
        // Attempt to write directly to buffer space if there's enough room,
@@ -94,8 +102,8 @@ public class ArtFastDataOutput extends FastDataOutput {
            // Negative value indicates buffer was too small and we need to
            // allocate a temporary buffer for encoding
            len = -len;
            final byte[] tmp = (byte[]) mRuntime.newNonMovableArray(byte.class, len + 1);
            CharsetUtils.toModifiedUtf8Bytes(s, mRuntime.addressOf(tmp), 0, tmp.length);
            final byte[] tmp = (byte[]) sRuntime.newNonMovableArray(byte.class, len + 1);
            CharsetUtils.toModifiedUtf8Bytes(s, sRuntime.addressOf(tmp), 0, tmp.length);
            writeShort(len);
            write(tmp, 0, len);
        }
+7 −0
Original line number Diff line number Diff line
@@ -33,3 +33,10 @@ java_library {
    ],
    visibility: ["//visibility:public"],
}

java_host_for_device {
    name: "core-xml-for-device",
    libs: [
        "core-xml-for-host",
    ],
}
+14 −0
Original line number Diff line number Diff line
@@ -103,7 +103,21 @@ class android.os.TransactionTooLargeException stubclass
# Containers
class android.os.BaseBundle stubclass
class android.os.Bundle stubclass
class android.os.PersistableBundle stubclass

# Misc
class android.os.PatternMatcher stubclass
class android.os.ParcelUuid stubclass

# XML
class com.android.internal.util.XmlPullParserWrapper stubclass
class com.android.internal.util.XmlSerializerWrapper stubclass
class com.android.internal.util.XmlUtils stubclass

class com.android.modules.utils.BinaryXmlPullParser stubclass
class com.android.modules.utils.BinaryXmlSerializer stubclass
class com.android.modules.utils.FastDataInput stubclass
class com.android.modules.utils.FastDataOutput stubclass
class com.android.modules.utils.ModifiedUtf8 stubclass
class com.android.modules.utils.TypedXmlPullParser stubclass
class com.android.modules.utils.TypedXmlSerializer stubclass
Loading