Support StatsD Java API on Ravenwood (f/b)

For now, no actual logging happens. We just make the Java APIs
available.

Flag: EXEMPT host test change only
Bug: 375042206
Test: $ANDROID_BUILD_TOP/frameworks/base/ravenwood/scripts/run-ravenwood-tests.sh
Change-Id: Id60fe9009852e01a7a40d99a2cd205cec868ae90
diff --git a/ravenwood/Android.bp b/ravenwood/Android.bp
index ff2abd2..090ec65 100644
--- a/ravenwood/Android.bp
+++ b/ravenwood/Android.bp
@@ -319,6 +319,16 @@
         ":services.core.ravenwood-base{hoststubgen_services.core_apis.csv}",
         ":services.core.ravenwood-base{hoststubgen_services.core_keep_all.txt}",
         ":services.core.ravenwood-base{hoststubgen_services.core_dump.txt}",
+
+        ":framework-configinfrastructure.ravenwood-base{framework-configinfrastructure_stats.csv}",
+        ":framework-configinfrastructure.ravenwood-base{framework-configinfrastructure_apis.csv}",
+        ":framework-configinfrastructure.ravenwood-base{framework-configinfrastructure_keep_all.txt}",
+        ":framework-configinfrastructure.ravenwood-base{framework-configinfrastructure_dump.txt}",
+
+        ":framework-statsd.ravenwood-base{framework-statsd_stats.csv}",
+        ":framework-statsd.ravenwood-base{framework-statsd_apis.csv}",
+        ":framework-statsd.ravenwood-base{framework-statsd_keep_all.txt}",
+        ":framework-statsd.ravenwood-base{framework-statsd_dump.txt}",
     ],
 }
 
@@ -403,6 +413,9 @@
         // DeviceConfig
         "framework-configinfrastructure.ravenwood",
 
+        // StatsD
+        "framework-statsd.ravenwood",
+
         // Provide runtime versions of utils linked in below
         "junit",
         "truth",
diff --git a/ravenwood/Framework.bp b/ravenwood/Framework.bp
index 1bea434..d207738 100644
--- a/ravenwood/Framework.bp
+++ b/ravenwood/Framework.bp
@@ -344,3 +344,57 @@
         "framework-configinfrastructure.ravenwood.jar",
     ],
 }
+
+///////////////////////////////////
+// framework-statsd
+///////////////////////////////////
+
+java_genrule {
+    name: "framework-statsd.ravenwood-base",
+    tools: ["hoststubgen"],
+    cmd: "$(location hoststubgen) " +
+        "@$(location :ravenwood-standard-options) " +
+
+        "--debug-log $(location framework-statsd.log) " +
+        "--stats-file $(location framework-statsd_stats.csv) " +
+        "--supported-api-list-file $(location framework-statsd_apis.csv) " +
+        "--gen-keep-all-file $(location framework-statsd_keep_all.txt) " +
+        "--gen-input-dump-file $(location framework-statsd_dump.txt) " +
+
+        "--out-impl-jar $(location ravenwood.jar) " +
+        "--in-jar $(location :framework-statsd.impl{.jar}) " +
+
+        "--policy-override-file $(location :ravenwood-common-policies) " +
+        "--policy-override-file $(location :framework-statsd-ravenwood-policies) ",
+    srcs: [
+        ":framework-statsd.impl{.jar}",
+
+        ":ravenwood-common-policies",
+        ":framework-statsd-ravenwood-policies",
+        ":ravenwood-standard-options",
+    ],
+    out: [
+        "ravenwood.jar",
+
+        // Following files are created just as FYI.
+        "framework-statsd_keep_all.txt",
+        "framework-statsd_dump.txt",
+
+        "framework-statsd.log",
+        "framework-statsd_stats.csv",
+        "framework-statsd_apis.csv",
+    ],
+    visibility: ["//visibility:private"],
+}
+
+java_genrule {
+    name: "framework-statsd.ravenwood",
+    defaults: ["ravenwood-internal-only-visibility-genrule"],
+    cmd: "cp $(in) $(out)",
+    srcs: [
+        ":framework-statsd.ravenwood-base{ravenwood.jar}",
+    ],
+    out: [
+        "framework-statsd.ravenwood.jar",
+    ],
+}
diff --git a/ravenwood/runtime-helper-src/framework/android/util/StatsEvent.java b/ravenwood/runtime-helper-src/framework/android/util/StatsEvent.java
deleted file mode 100644
index 1e3b3fc..0000000
--- a/ravenwood/runtime-helper-src/framework/android/util/StatsEvent.java
+++ /dev/null
@@ -1,1035 +0,0 @@
-/*
- * Copyright (C) 2019 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-// [ravenwood] This is an exact copy from StatsD, until we make StatsD available on Ravenwood.
-
-import static java.nio.charset.StandardCharsets.UTF_8;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Build;
-import android.os.SystemClock;
-
-import androidx.annotation.RequiresApi;
-
-import com.android.internal.annotations.GuardedBy;
-import com.android.internal.annotations.VisibleForTesting;
-
-import java.nio.ByteBuffer;
-import java.util.Arrays;
-
-/**
- * StatsEvent builds and stores the buffer sent over the statsd socket.
- * This class defines and encapsulates the socket protocol.
- *
- * <p>Usage:</p>
- * <pre>
- *      // Pushed event
- *      StatsEvent statsEvent = StatsEvent.newBuilder()
- *          .setAtomId(atomId)
- *          .writeBoolean(false)
- *          .writeString("annotated String field")
- *          .addBooleanAnnotation(annotationId, true)
- *          .usePooledBuffer()
- *          .build();
- *      StatsLog.write(statsEvent);
- *
- *      // Pulled event
- *      StatsEvent statsEvent = StatsEvent.newBuilder()
- *          .setAtomId(atomId)
- *          .writeBoolean(false)
- *          .writeString("annotated String field")
- *          .addBooleanAnnotation(annotationId, true)
- *          .build();
- * </pre>
- * @hide
- **/
-@SystemApi
-public final class StatsEvent {
-    // Type Ids.
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_INT = 0x00;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_LONG = 0x01;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_STRING = 0x02;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_LIST = 0x03;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_FLOAT = 0x04;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_BOOLEAN = 0x05;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_BYTE_ARRAY = 0x06;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_OBJECT = 0x07;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_KEY_VALUE_PAIRS = 0x08;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_ATTRIBUTION_CHAIN = 0x09;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final byte TYPE_ERRORS = 0x0F;
-
-    // Error flags.
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_NO_TIMESTAMP = 0x1;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_NO_ATOM_ID = 0x2;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_OVERFLOW = 0x4;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_ATTRIBUTION_CHAIN_TOO_LONG = 0x8;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_TOO_MANY_KEY_VALUE_PAIRS = 0x10;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD = 0x20;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_INVALID_ANNOTATION_ID = 0x40;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_ANNOTATION_ID_TOO_LARGE = 0x80;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_TOO_MANY_ANNOTATIONS = 0x100;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_TOO_MANY_FIELDS = 0x200;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_ATTRIBUTION_UIDS_TAGS_SIZES_NOT_EQUAL = 0x1000;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int ERROR_ATOM_ID_INVALID_POSITION = 0x2000;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting public static final int ERROR_LIST_TOO_LONG = 0x4000;
-
-    // Size limits.
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int MAX_ANNOTATION_COUNT = 15;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int MAX_ATTRIBUTION_NODES = 127;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int MAX_NUM_ELEMENTS = 127;
-
-    /**
-     * @hide
-     **/
-    @VisibleForTesting
-    public static final int MAX_KEY_VALUE_PAIRS = 127;
-
-    private static final int LOGGER_ENTRY_MAX_PAYLOAD = 4068;
-
-    // Max payload size is 4 bytes less as 4 bytes are reserved for statsEventTag.
-    // See android_util_StatsLog.cpp.
-    private static final int MAX_PUSH_PAYLOAD_SIZE = LOGGER_ENTRY_MAX_PAYLOAD - 4;
-
-    private static final int MAX_PULL_PAYLOAD_SIZE = 50 * 1024; // 50 KB
-
-    private final int mAtomId;
-    private final byte[] mPayload;
-    private Buffer mBuffer;
-    private final int mNumBytes;
-
-    private StatsEvent(final int atomId, @Nullable final Buffer buffer,
-            @NonNull final byte[] payload, final int numBytes) {
-        mAtomId = atomId;
-        mBuffer = buffer;
-        mPayload = payload;
-        mNumBytes = numBytes;
-    }
-
-    /**
-     * Returns a new StatsEvent.Builder for building StatsEvent object.
-     **/
-    @NonNull
-    public static Builder newBuilder() {
-        return new Builder(Buffer.obtain());
-    }
-
-    /**
-     * Get the atom Id of the atom encoded in this StatsEvent object.
-     *
-     * @hide
-     **/
-    public int getAtomId() {
-        return mAtomId;
-    }
-
-    /**
-     * Get the byte array that contains the encoded payload that can be sent to statsd.
-     *
-     * @hide
-     **/
-    @NonNull
-    public byte[] getBytes() {
-        return mPayload;
-    }
-
-    /**
-     * Get the number of bytes used to encode the StatsEvent payload.
-     *
-     * @hide
-     **/
-    public int getNumBytes() {
-        return mNumBytes;
-    }
-
-    /**
-     * Recycle resources used by this StatsEvent object.
-     * No actions should be taken on this StatsEvent after release() is called.
-     *
-     * @hide
-     **/
-    public void release() {
-        if (mBuffer != null) {
-            mBuffer.release();
-            mBuffer = null;
-        }
-    }
-
-    /**
-     * Builder for constructing a StatsEvent object.
-     *
-     * <p>This class defines and encapsulates the socket encoding for the
-     *buffer. The write methods must be called in the same order as the order of
-     *fields in the atom definition.</p>
-     *
-     * <p>setAtomId() must be called immediately after
-     *StatsEvent.newBuilder().</p>
-     *
-     * <p>Example:</p>
-     * <pre>
-     *     // Atom definition.
-     *     message MyAtom {
-     *         optional int32 field1 = 1;
-     *         optional int64 field2 = 2;
-     *         optional string field3 = 3 [(annotation1) = true];
-     *         optional repeated int32 field4 = 4;
-     *     }
-     *
-     *     // StatsEvent construction for pushed event.
-     *     StatsEvent.newBuilder()
-     *     StatsEvent statsEvent = StatsEvent.newBuilder()
-     *         .setAtomId(atomId)
-     *         .writeInt(3) // field1
-     *         .writeLong(8L) // field2
-     *         .writeString("foo") // field 3
-     *         .addBooleanAnnotation(annotation1Id, true)
-     *         .writeIntArray({ 1, 2, 3 });
-     *         .usePooledBuffer()
-     *         .build();
-     *
-     *     // StatsEvent construction for pulled event.
-     *     StatsEvent.newBuilder()
-     *     StatsEvent statsEvent = StatsEvent.newBuilder()
-     *         .setAtomId(atomId)
-     *         .writeInt(3) // field1
-     *         .writeLong(8L) // field2
-     *         .writeString("foo") // field 3
-     *         .addBooleanAnnotation(annotation1Id, true)
-     *         .writeIntArray({ 1, 2, 3 });
-     *         .build();
-     * </pre>
-     **/
-    public static final class Builder {
-        // Fixed positions.
-        private static final int POS_NUM_ELEMENTS = 1;
-        private static final int POS_TIMESTAMP_NS = POS_NUM_ELEMENTS + Byte.BYTES;
-        private static final int POS_ATOM_ID = POS_TIMESTAMP_NS + Byte.BYTES + Long.BYTES;
-
-        private final Buffer mBuffer;
-        private long mTimestampNs;
-        private int mAtomId;
-        private byte mCurrentAnnotationCount;
-        private int mPos;
-        private int mPosLastField;
-        private byte mLastType;
-        private int mNumElements;
-        private int mErrorMask;
-        private boolean mUsePooledBuffer = false;
-
-        private Builder(final Buffer buffer) {
-            mBuffer = buffer;
-            mCurrentAnnotationCount = 0;
-            mAtomId = 0;
-            mTimestampNs = SystemClock.elapsedRealtimeNanos();
-            mNumElements = 0;
-
-            // Set mPos to 0 for writing TYPE_OBJECT at 0th position.
-            mPos = 0;
-            writeTypeId(TYPE_OBJECT);
-
-            // Write timestamp.
-            mPos = POS_TIMESTAMP_NS;
-            writeLong(mTimestampNs);
-        }
-
-        /**
-         * Sets the atom id for this StatsEvent.
-         *
-         * This should be called immediately after StatsEvent.newBuilder()
-         * and should only be called once.
-         * Not calling setAtomId will result in ERROR_NO_ATOM_ID.
-         * Calling setAtomId out of order will result in ERROR_ATOM_ID_INVALID_POSITION.
-         **/
-        @NonNull
-        public Builder setAtomId(final int atomId) {
-            if (0 == mAtomId) {
-                mAtomId = atomId;
-
-                if (1 == mNumElements) { // Only timestamp is written so far.
-                    writeInt(atomId);
-                } else {
-                    // setAtomId called out of order.
-                    mErrorMask |= ERROR_ATOM_ID_INVALID_POSITION;
-                }
-            }
-
-            return this;
-        }
-
-        /**
-         * Write a boolean field to this StatsEvent.
-         **/
-        @NonNull
-        public Builder writeBoolean(final boolean value) {
-            // Write boolean typeId byte followed by boolean byte representation.
-            writeTypeId(TYPE_BOOLEAN);
-            mPos += mBuffer.putBoolean(mPos, value);
-            mNumElements++;
-            return this;
-        }
-
-        /**
-         * Write an integer field to this StatsEvent.
-         **/
-        @NonNull
-        public Builder writeInt(final int value) {
-            // Write integer typeId byte followed by 4-byte representation of value.
-            writeTypeId(TYPE_INT);
-            mPos += mBuffer.putInt(mPos, value);
-            mNumElements++;
-            return this;
-        }
-
-        /**
-         * Write a long field to this StatsEvent.
-         **/
-        @NonNull
-        public Builder writeLong(final long value) {
-            // Write long typeId byte followed by 8-byte representation of value.
-            writeTypeId(TYPE_LONG);
-            mPos += mBuffer.putLong(mPos, value);
-            mNumElements++;
-            return this;
-        }
-
-        /**
-         * Write a float field to this StatsEvent.
-         **/
-        @NonNull
-        public Builder writeFloat(final float value) {
-            // Write float typeId byte followed by 4-byte representation of value.
-            writeTypeId(TYPE_FLOAT);
-            mPos += mBuffer.putFloat(mPos, value);
-            mNumElements++;
-            return this;
-        }
-
-        /**
-         * Write a String field to this StatsEvent.
-         **/
-        @NonNull
-        public Builder writeString(@NonNull final String value) {
-            // Write String typeId byte, followed by 4-byte representation of number of bytes
-            // in the UTF-8 encoding, followed by the actual UTF-8 byte encoding of value.
-            final byte[] valueBytes = stringToBytes(value);
-            writeByteArray(valueBytes, TYPE_STRING);
-            return this;
-        }
-
-        /**
-         * Write a byte array field to this StatsEvent.
-         **/
-        @NonNull
-        public Builder writeByteArray(@NonNull final byte[] value) {
-            // Write byte array typeId byte, followed by 4-byte representation of number of bytes
-            // in value, followed by the actual byte array.
-            writeByteArray(value, TYPE_BYTE_ARRAY);
-            return this;
-        }
-
-        private void writeByteArray(@NonNull final byte[] value, final byte typeId) {
-            writeTypeId(typeId);
-            final int numBytes = value.length;
-            mPos += mBuffer.putInt(mPos, numBytes);
-            mPos += mBuffer.putByteArray(mPos, value);
-            mNumElements++;
-        }
-
-        /**
-         * Write an attribution chain field to this StatsEvent.
-         *
-         * The sizes of uids and tags must be equal. The AttributionNode at position i is
-         * made up of uids[i] and tags[i].
-         *
-         * @param uids array of uids in the attribution nodes.
-         * @param tags array of tags in the attribution nodes.
-         **/
-        @NonNull
-        public Builder writeAttributionChain(
-                @NonNull final int[] uids, @NonNull final String[] tags) {
-            final byte numUids = (byte) uids.length;
-            final byte numTags = (byte) tags.length;
-
-            if (numUids != numTags) {
-                mErrorMask |= ERROR_ATTRIBUTION_UIDS_TAGS_SIZES_NOT_EQUAL;
-            } else if (numUids > MAX_ATTRIBUTION_NODES) {
-                mErrorMask |= ERROR_ATTRIBUTION_CHAIN_TOO_LONG;
-            } else {
-                // Write attribution chain typeId byte, followed by 1-byte representation of
-                // number of attribution nodes, followed by encoding of each attribution node.
-                writeTypeId(TYPE_ATTRIBUTION_CHAIN);
-                mPos += mBuffer.putByte(mPos, numUids);
-                for (int i = 0; i < numUids; i++) {
-                    // Each uid is encoded as 4-byte representation of its int value.
-                    mPos += mBuffer.putInt(mPos, uids[i]);
-
-                    // Each tag is encoded as 4-byte representation of number of bytes in its
-                    // UTF-8 encoding, followed by the actual UTF-8 bytes.
-                    final byte[] tagBytes = stringToBytes(tags[i]);
-                    mPos += mBuffer.putInt(mPos, tagBytes.length);
-                    mPos += mBuffer.putByteArray(mPos, tagBytes);
-                }
-                mNumElements++;
-            }
-            return this;
-        }
-
-        /**
-         * Write KeyValuePairsAtom entries to this StatsEvent.
-         *
-         * @param intMap Integer key-value pairs.
-         * @param longMap Long key-value pairs.
-         * @param stringMap String key-value pairs.
-         * @param floatMap Float key-value pairs.
-         **/
-        @NonNull
-        public Builder writeKeyValuePairs(
-                @Nullable final SparseIntArray intMap,
-                @Nullable final SparseLongArray longMap,
-                @Nullable final SparseArray<String> stringMap,
-                @Nullable final SparseArray<Float> floatMap) {
-            final int intMapSize = null == intMap ? 0 : intMap.size();
-            final int longMapSize = null == longMap ? 0 : longMap.size();
-            final int stringMapSize = null == stringMap ? 0 : stringMap.size();
-            final int floatMapSize = null == floatMap ? 0 : floatMap.size();
-            final int totalCount = intMapSize + longMapSize + stringMapSize + floatMapSize;
-
-            if (totalCount > MAX_KEY_VALUE_PAIRS) {
-                mErrorMask |= ERROR_TOO_MANY_KEY_VALUE_PAIRS;
-            } else {
-                writeTypeId(TYPE_KEY_VALUE_PAIRS);
-                mPos += mBuffer.putByte(mPos, (byte) totalCount);
-
-                for (int i = 0; i < intMapSize; i++) {
-                    final int key = intMap.keyAt(i);
-                    final int value = intMap.valueAt(i);
-                    mPos += mBuffer.putInt(mPos, key);
-                    writeTypeId(TYPE_INT);
-                    mPos += mBuffer.putInt(mPos, value);
-                }
-
-                for (int i = 0; i < longMapSize; i++) {
-                    final int key = longMap.keyAt(i);
-                    final long value = longMap.valueAt(i);
-                    mPos += mBuffer.putInt(mPos, key);
-                    writeTypeId(TYPE_LONG);
-                    mPos += mBuffer.putLong(mPos, value);
-                }
-
-                for (int i = 0; i < stringMapSize; i++) {
-                    final int key = stringMap.keyAt(i);
-                    final String value = stringMap.valueAt(i);
-                    mPos += mBuffer.putInt(mPos, key);
-                    writeTypeId(TYPE_STRING);
-                    final byte[] valueBytes = stringToBytes(value);
-                    mPos += mBuffer.putInt(mPos, valueBytes.length);
-                    mPos += mBuffer.putByteArray(mPos, valueBytes);
-                }
-
-                for (int i = 0; i < floatMapSize; i++) {
-                    final int key = floatMap.keyAt(i);
-                    final float value = floatMap.valueAt(i);
-                    mPos += mBuffer.putInt(mPos, key);
-                    writeTypeId(TYPE_FLOAT);
-                    mPos += mBuffer.putFloat(mPos, value);
-                }
-
-                mNumElements++;
-            }
-
-            return this;
-        }
-
-        /**
-         * Write a repeated boolean field to this StatsEvent.
-         *
-         * The list size must not exceed 127. Otherwise, the array isn't written
-         * to the StatsEvent and ERROR_LIST_TOO_LONG is appended to the
-         * StatsEvent errors field.
-         *
-         * @param elements array of booleans.
-         **/
-        @RequiresApi(Build.VERSION_CODES.TIRAMISU)
-        @NonNull
-        public Builder writeBooleanArray(@NonNull final boolean[] elements) {
-            final byte numElements = (byte)elements.length;
-
-            if (writeArrayInfo(numElements, TYPE_BOOLEAN)) {
-                // Write encoding of each element.
-                for (int i = 0; i < numElements; i++) {
-                    mPos += mBuffer.putBoolean(mPos, elements[i]);
-                }
-                mNumElements++;
-            }
-            return this;
-        }
-
-        /**
-         * Write a repeated int field to this StatsEvent.
-         *
-         * The list size must not exceed 127. Otherwise, the array isn't written
-         * to the StatsEvent and ERROR_LIST_TOO_LONG is appended to the
-         * StatsEvent errors field.
-         *
-         * @param elements array of ints.
-         **/
-        @RequiresApi(Build.VERSION_CODES.TIRAMISU)
-        @NonNull
-        public Builder writeIntArray(@NonNull final int[] elements) {
-            final byte numElements = (byte)elements.length;
-
-            if (writeArrayInfo(numElements, TYPE_INT)) {
-              // Write encoding of each element.
-              for (int i = 0; i < numElements; i++) {
-                mPos += mBuffer.putInt(mPos, elements[i]);
-                }
-                mNumElements++;
-            }
-            return this;
-        }
-
-        /**
-         * Write a repeated long field to this StatsEvent.
-         *
-         * The list size must not exceed 127. Otherwise, the array isn't written
-         * to the StatsEvent and ERROR_LIST_TOO_LONG is appended to the
-         * StatsEvent errors field.
-         *
-         * @param elements array of longs.
-         **/
-        @RequiresApi(Build.VERSION_CODES.TIRAMISU)
-        @NonNull
-        public Builder writeLongArray(@NonNull final long[] elements) {
-            final byte numElements = (byte)elements.length;
-
-            if (writeArrayInfo(numElements, TYPE_LONG)) {
-                // Write encoding of each element.
-                for (int i = 0; i < numElements; i++) {
-                    mPos += mBuffer.putLong(mPos, elements[i]);
-                }
-                mNumElements++;
-            }
-            return this;
-        }
-
-        /**
-         * Write a repeated float field to this StatsEvent.
-         *
-         * The list size must not exceed 127. Otherwise, the array isn't written
-         * to the StatsEvent and ERROR_LIST_TOO_LONG is appended to the
-         * StatsEvent errors field.
-         *
-         * @param elements array of floats.
-         **/
-        @RequiresApi(Build.VERSION_CODES.TIRAMISU)
-        @NonNull
-        public Builder writeFloatArray(@NonNull final float[] elements) {
-            final byte numElements = (byte)elements.length;
-
-            if (writeArrayInfo(numElements, TYPE_FLOAT)) {
-                // Write encoding of each element.
-                for (int i = 0; i < numElements; i++) {
-                  mPos += mBuffer.putFloat(mPos, elements[i]);
-                }
-                mNumElements++;
-            }
-            return this;
-        }
-
-        /**
-         * Write a repeated string field to this StatsEvent.
-         *
-         * The list size must not exceed 127. Otherwise, the array isn't written
-         * to the StatsEvent and ERROR_LIST_TOO_LONG is appended to the
-         * StatsEvent errors field.
-         *
-         * @param elements array of strings.
-         **/
-        @RequiresApi(Build.VERSION_CODES.TIRAMISU)
-        @NonNull
-        public Builder writeStringArray(@NonNull final String[] elements) {
-            final byte numElements = (byte)elements.length;
-
-            if (writeArrayInfo(numElements, TYPE_STRING)) {
-                // Write encoding of each element.
-                for (int i = 0; i < numElements; i++) {
-                    final byte[] elementBytes = stringToBytes(elements[i]);
-                    mPos += mBuffer.putInt(mPos, elementBytes.length);
-                    mPos += mBuffer.putByteArray(mPos, elementBytes);
-                }
-                mNumElements++;
-            }
-            return this;
-        }
-
-        /**
-         * Write a boolean annotation for the last field written.
-         **/
-        @NonNull
-        public Builder addBooleanAnnotation(
-                final byte annotationId, final boolean value) {
-            // Ensure there's a field written to annotate.
-            if (mNumElements < 2) {
-                mErrorMask |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD;
-            } else if (mCurrentAnnotationCount >= MAX_ANNOTATION_COUNT) {
-                mErrorMask |= ERROR_TOO_MANY_ANNOTATIONS;
-            } else {
-                mPos += mBuffer.putByte(mPos, annotationId);
-                mPos += mBuffer.putByte(mPos, TYPE_BOOLEAN);
-                mPos += mBuffer.putBoolean(mPos, value);
-                mCurrentAnnotationCount++;
-                writeAnnotationCount();
-            }
-
-            return this;
-        }
-
-        /**
-         * Write an integer annotation for the last field written.
-         **/
-        @NonNull
-        public Builder addIntAnnotation(final byte annotationId, final int value) {
-            if (mNumElements < 2) {
-                mErrorMask |= ERROR_ANNOTATION_DOES_NOT_FOLLOW_FIELD;
-            } else if (mCurrentAnnotationCount >= MAX_ANNOTATION_COUNT) {
-                mErrorMask |= ERROR_TOO_MANY_ANNOTATIONS;
-            } else {
-                mPos += mBuffer.putByte(mPos, annotationId);
-                mPos += mBuffer.putByte(mPos, TYPE_INT);
-                mPos += mBuffer.putInt(mPos, value);
-                mCurrentAnnotationCount++;
-                writeAnnotationCount();
-            }
-
-            return this;
-        }
-
-        /**
-         * Indicates to reuse Buffer's byte array as the underlying payload in StatsEvent.
-         * This should be called for pushed events to reduce memory allocations and garbage
-         * collections.
-         **/
-        @NonNull
-        public Builder usePooledBuffer() {
-            mUsePooledBuffer = true;
-            mBuffer.setMaxSize(MAX_PUSH_PAYLOAD_SIZE, mPos);
-            return this;
-        }
-
-        /**
-         * Builds a StatsEvent object with values entered in this Builder.
-         **/
-        @NonNull
-        public StatsEvent build() {
-            if (0L == mTimestampNs) {
-                mErrorMask |= ERROR_NO_TIMESTAMP;
-            }
-            if (0 == mAtomId) {
-                mErrorMask |= ERROR_NO_ATOM_ID;
-            }
-            if (mBuffer.hasOverflowed()) {
-                mErrorMask |= ERROR_OVERFLOW;
-            }
-            if (mNumElements > MAX_NUM_ELEMENTS) {
-                mErrorMask |= ERROR_TOO_MANY_FIELDS;
-            }
-
-            if (0 == mErrorMask) {
-                mBuffer.putByte(POS_NUM_ELEMENTS, (byte) mNumElements);
-            } else {
-                // Write atom id and error mask. Overwrite any annotations for atom Id.
-                mPos = POS_ATOM_ID;
-                mPos += mBuffer.putByte(mPos, TYPE_INT);
-                mPos += mBuffer.putInt(mPos, mAtomId);
-                mPos += mBuffer.putByte(mPos, TYPE_ERRORS);
-                mPos += mBuffer.putInt(mPos, mErrorMask);
-                mBuffer.putByte(POS_NUM_ELEMENTS, (byte) 3);
-            }
-
-            final int size = mPos;
-
-            if (mUsePooledBuffer) {
-                return new StatsEvent(mAtomId, mBuffer, mBuffer.getBytes(), size);
-            } else {
-                // Create a copy of the buffer with the required number of bytes.
-                final byte[] payload = new byte[size];
-                System.arraycopy(mBuffer.getBytes(), 0, payload, 0, size);
-
-                // Return Buffer instance to the pool.
-                mBuffer.release();
-
-                return new StatsEvent(mAtomId, null, payload, size);
-            }
-        }
-
-        private void writeTypeId(final byte typeId) {
-            mPosLastField = mPos;
-            mLastType = typeId;
-            mCurrentAnnotationCount = 0;
-            final byte encodedId = (byte) (typeId & 0x0F);
-            mPos += mBuffer.putByte(mPos, encodedId);
-        }
-
-        private void writeAnnotationCount() {
-            // Use first 4 bits for annotation count and last 4 bits for typeId.
-            final byte encodedId = (byte) ((mCurrentAnnotationCount << 4) | (mLastType & 0x0F));
-            mBuffer.putByte(mPosLastField, encodedId);
-        }
-
-        @NonNull
-        private static byte[] stringToBytes(@Nullable final String value) {
-            return (null == value ? "" : value).getBytes(UTF_8);
-        }
-
-        private boolean writeArrayInfo(final byte numElements,
-                                       final byte elementTypeId) {
-            if (numElements > MAX_NUM_ELEMENTS) {
-                mErrorMask |= ERROR_LIST_TOO_LONG;
-                return false;
-            }
-            // Write list typeId byte, 1-byte representation of number of
-            // elements, and element typeId byte.
-            writeTypeId(TYPE_LIST);
-            mPos += mBuffer.putByte(mPos, numElements);
-            // Write element typeId byte without setting mPosLastField and mLastType (i.e. don't use
-            // #writeTypeId)
-            final byte encodedId = (byte) (elementTypeId & 0x0F);
-            mPos += mBuffer.putByte(mPos, encodedId);
-            return true;
-        }
-    }
-
-    private static final class Buffer {
-        private static Object sLock = new Object();
-
-        @GuardedBy("sLock")
-        private static Buffer sPool;
-
-        private byte[] mBytes;
-        private boolean mOverflow = false;
-        private int mMaxSize = MAX_PULL_PAYLOAD_SIZE;
-
-        @NonNull
-        private static Buffer obtain() {
-            final Buffer buffer;
-            synchronized (sLock) {
-                buffer = null == sPool ? new Buffer() : sPool;
-                sPool = null;
-            }
-            buffer.reset();
-            return buffer;
-        }
-
-        private Buffer() {
-            final ByteBuffer tempBuffer = ByteBuffer.allocateDirect(MAX_PUSH_PAYLOAD_SIZE);
-            mBytes = tempBuffer.hasArray() ? tempBuffer.array() : new byte [MAX_PUSH_PAYLOAD_SIZE];
-        }
-
-        @NonNull
-        private byte[] getBytes() {
-            return mBytes;
-        }
-
-        private void release() {
-            // Recycle this Buffer if its size is MAX_PUSH_PAYLOAD_SIZE or under.
-            if (mMaxSize <= MAX_PUSH_PAYLOAD_SIZE) {
-                synchronized (sLock) {
-                    if (null == sPool) {
-                        sPool = this;
-                    }
-                }
-            }
-        }
-
-        private void reset() {
-            mOverflow = false;
-            mMaxSize = MAX_PULL_PAYLOAD_SIZE;
-        }
-
-        private void setMaxSize(final int maxSize, final int numBytesWritten) {
-            mMaxSize = maxSize;
-            if (numBytesWritten > maxSize) {
-                mOverflow = true;
-            }
-        }
-
-        private boolean hasOverflowed() {
-            return mOverflow;
-        }
-
-        /**
-         * Checks for available space in the byte array.
-         *
-         * @param index starting position in the buffer to start the check.
-         * @param numBytes number of bytes to check from index.
-         * @return true if space is available, false otherwise.
-         **/
-        private boolean hasEnoughSpace(final int index, final int numBytes) {
-            final int totalBytesNeeded = index + numBytes;
-
-            if (totalBytesNeeded > mMaxSize) {
-                mOverflow = true;
-                return false;
-            }
-
-            // Expand buffer if needed.
-            if (mBytes.length < mMaxSize && totalBytesNeeded > mBytes.length) {
-                int newSize = mBytes.length;
-                do {
-                    newSize *= 2;
-                } while (newSize <= totalBytesNeeded);
-
-                if (newSize > mMaxSize) {
-                    newSize = mMaxSize;
-                }
-
-                mBytes = Arrays.copyOf(mBytes, newSize);
-            }
-
-            return true;
-        }
-
-        /**
-         * Writes a byte into the buffer.
-         *
-         * @param index position in the buffer where the byte is written.
-         * @param value the byte to write.
-         * @return number of bytes written to buffer from this write operation.
-         **/
-        private int putByte(final int index, final byte value) {
-            if (hasEnoughSpace(index, Byte.BYTES)) {
-                mBytes[index] = (byte) (value);
-                return Byte.BYTES;
-            }
-            return 0;
-        }
-
-        /**
-         * Writes a boolean into the buffer.
-         *
-         * @param index position in the buffer where the boolean is written.
-         * @param value the boolean to write.
-         * @return number of bytes written to buffer from this write operation.
-         **/
-        private int putBoolean(final int index, final boolean value) {
-            return putByte(index, (byte) (value ? 1 : 0));
-        }
-
-        /**
-         * Writes an integer into the buffer.
-         *
-         * @param index position in the buffer where the integer is written.
-         * @param value the integer to write.
-         * @return number of bytes written to buffer from this write operation.
-         **/
-        private int putInt(final int index, final int value) {
-            if (hasEnoughSpace(index, Integer.BYTES)) {
-                // Use little endian byte order.
-                mBytes[index] = (byte) (value);
-                mBytes[index + 1] = (byte) (value >> 8);
-                mBytes[index + 2] = (byte) (value >> 16);
-                mBytes[index + 3] = (byte) (value >> 24);
-                return Integer.BYTES;
-            }
-            return 0;
-        }
-
-        /**
-         * Writes a long into the buffer.
-         *
-         * @param index position in the buffer where the long is written.
-         * @param value the long to write.
-         * @return number of bytes written to buffer from this write operation.
-         **/
-        private int putLong(final int index, final long value) {
-            if (hasEnoughSpace(index, Long.BYTES)) {
-                // Use little endian byte order.
-                mBytes[index] = (byte) (value);
-                mBytes[index + 1] = (byte) (value >> 8);
-                mBytes[index + 2] = (byte) (value >> 16);
-                mBytes[index + 3] = (byte) (value >> 24);
-                mBytes[index + 4] = (byte) (value >> 32);
-                mBytes[index + 5] = (byte) (value >> 40);
-                mBytes[index + 6] = (byte) (value >> 48);
-                mBytes[index + 7] = (byte) (value >> 56);
-                return Long.BYTES;
-            }
-            return 0;
-        }
-
-        /**
-         * Writes a float into the buffer.
-         *
-         * @param index position in the buffer where the float is written.
-         * @param value the float to write.
-         * @return number of bytes written to buffer from this write operation.
-         **/
-        private int putFloat(final int index, final float value) {
-            return putInt(index, Float.floatToIntBits(value));
-        }
-
-        /**
-         * Copies a byte array into the buffer.
-         *
-         * @param index position in the buffer where the byte array is copied.
-         * @param value the byte array to copy.
-         * @return number of bytes written to buffer from this write operation.
-         **/
-        private int putByteArray(final int index, @NonNull final byte[] value) {
-            final int numBytes = value.length;
-            if (hasEnoughSpace(index, numBytes)) {
-                System.arraycopy(value, 0, mBytes, index, numBytes);
-                return numBytes;
-            }
-            return 0;
-        }
-    }
-}
diff --git a/ravenwood/runtime-helper-src/framework/android/util/StatsLog.java b/ravenwood/runtime-helper-src/framework/android/util/StatsLog.java
deleted file mode 100644
index c1c20cf..0000000
--- a/ravenwood/runtime-helper-src/framework/android/util/StatsLog.java
+++ /dev/null
@@ -1,478 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.util;
-
-/*
- * [Ravenwood] This is copied from StatsD, with the following changes:
- * - The static {} is commented out.
- * - All references to IStatsD and StatsdStatsLog are commented out.
- * - The native method is no-oped.
- */
-
-import static android.Manifest.permission.DUMP;
-import static android.Manifest.permission.PACKAGE_USAGE_STATS;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.RequiresPermission;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.os.Build;
-//import android.os.IStatsd;
-import android.os.Process;
-import android.util.proto.ProtoOutputStream;
-
-import androidx.annotation.RequiresApi;
-
-//import com.android.internal.statsd.StatsdStatsLog;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * StatsLog provides an API for developers to send events to statsd. The events can be used to
- * define custom metrics in side statsd.
- */
-public final class StatsLog {
-
-//    // Load JNI library
-//    static {
-//        System.loadLibrary("stats_jni");
-//    }
-    private static final String TAG = "StatsLog";
-    private static final boolean DEBUG = false;
-    private static final int EXPERIMENT_IDS_FIELD_ID = 1;
-
-    /**
-     * Annotation ID constant for logging UID field.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    public static final byte ANNOTATION_ID_IS_UID = 1;
-
-    /**
-     * Annotation ID constant to indicate logged atom event's timestamp should be truncated.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    public static final byte ANNOTATION_ID_TRUNCATE_TIMESTAMP = 2;
-
-    /**
-     * Annotation ID constant for a state atom's primary field.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    public static final byte ANNOTATION_ID_PRIMARY_FIELD = 3;
-
-    /**
-     * Annotation ID constant for state atom's state field.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    public static final byte ANNOTATION_ID_EXCLUSIVE_STATE = 4;
-
-    /**
-     * Annotation ID constant to indicate the first UID in the attribution chain
-     * is a primary field.
-     * Should only be used for attribution chain fields.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    public static final byte ANNOTATION_ID_PRIMARY_FIELD_FIRST_UID = 5;
-
-    /**
-     * Annotation ID constant to indicate which state is default for the state atom.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    public static final byte ANNOTATION_ID_DEFAULT_STATE = 6;
-
-    /**
-     * Annotation ID constant to signal all states should be reset to the default state.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    public static final byte ANNOTATION_ID_TRIGGER_STATE_RESET = 7;
-
-    /**
-     * Annotation ID constant to indicate state changes need to account for nesting.
-     * This should only be used with binary state atoms.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    public static final byte ANNOTATION_ID_STATE_NESTED = 8;
-
-    /**
-     * Annotation ID constant to indicate the restriction category of an atom.
-     * This annotation must only be attached to the atom id. This is an int annotation.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-    public static final byte ANNOTATION_ID_RESTRICTION_CATEGORY = 9;
-
-    /**
-     * Annotation ID to indicate that a field of an atom contains peripheral device info.
-     * This is a bool annotation.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-    public static final byte ANNOTATION_ID_FIELD_RESTRICTION_PERIPHERAL_DEVICE_INFO = 10;
-
-    /**
-     * Annotation ID to indicate that a field of an atom contains app usage information.
-     * This is a bool annotation.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-    public static final byte ANNOTATION_ID_FIELD_RESTRICTION_APP_USAGE = 11;
-
-    /**
-     * Annotation ID to indicate that a field of an atom contains app activity information.
-     * This is a bool annotation.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-    public static final byte ANNOTATION_ID_FIELD_RESTRICTION_APP_ACTIVITY = 12;
-
-    /**
-     * Annotation ID to indicate that a field of an atom contains health connect information.
-     * This is a bool annotation.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-    public static final byte ANNOTATION_ID_FIELD_RESTRICTION_HEALTH_CONNECT = 13;
-
-    /**
-     * Annotation ID to indicate that a field of an atom contains accessibility information.
-     * This is a bool annotation.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-    public static final byte ANNOTATION_ID_FIELD_RESTRICTION_ACCESSIBILITY = 14;
-
-    /**
-     * Annotation ID to indicate that a field of an atom contains system search information.
-     * This is a bool annotation.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-    public static final byte ANNOTATION_ID_FIELD_RESTRICTION_SYSTEM_SEARCH = 15;
-
-    /**
-     * Annotation ID to indicate that a field of an atom contains user engagement information.
-     * This is a bool annotation.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-    public static final byte ANNOTATION_ID_FIELD_RESTRICTION_USER_ENGAGEMENT = 16;
-
-    /**
-     * Annotation ID to indicate that a field of an atom contains ambient sensing information.
-     * This is a bool annotation.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-    public static final byte ANNOTATION_ID_FIELD_RESTRICTION_AMBIENT_SENSING = 17;
-
-    /**
-     * Annotation ID to indicate that a field of an atom contains demographic classification
-     * information. This is a bool annotation.
-     *
-     * The ID is a byte since StatsEvent.addBooleanAnnotation() and StatsEvent.addIntAnnotation()
-     * accept byte as the type for annotation ids to save space.
-     *
-     * @hide
-     */
-    @SuppressLint("NoByteOrShort")
-    @SystemApi
-    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-    public static final byte ANNOTATION_ID_FIELD_RESTRICTION_DEMOGRAPHIC_CLASSIFICATION = 18;
-
-
-    /** @hide */
-    @IntDef(prefix = { "RESTRICTION_CATEGORY_" }, value = {
-            RESTRICTION_CATEGORY_DIAGNOSTIC,
-            RESTRICTION_CATEGORY_SYSTEM_INTELLIGENCE,
-            RESTRICTION_CATEGORY_AUTHENTICATION,
-            RESTRICTION_CATEGORY_FRAUD_AND_ABUSE})
-    @Retention(RetentionPolicy.SOURCE)
-    public @interface RestrictionCategory {}
-
-    /**
-     * Restriction category for atoms about diagnostics.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-    public static final int RESTRICTION_CATEGORY_DIAGNOSTIC = 1;
-
-    /**
-     * Restriction category for atoms about system intelligence.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-    public static final int RESTRICTION_CATEGORY_SYSTEM_INTELLIGENCE = 2;
-
-    /**
-     * Restriction category for atoms about authentication.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-    public static final int RESTRICTION_CATEGORY_AUTHENTICATION = 3;
-
-    /**
-     * Restriction category for atoms about fraud and abuse.
-     *
-     * @hide
-     */
-    @SystemApi
-    @RequiresApi(Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
-    public static final int RESTRICTION_CATEGORY_FRAUD_AND_ABUSE = 4;
-
-    private StatsLog() {
-    }
-
-    /**
-     * Logs a start event.
-     *
-     * @param label developer-chosen label.
-     * @return True if the log request was sent to statsd.
-     */
-    public static boolean logStart(int label) {
-        int callingUid = Process.myUid();
-//        StatsdStatsLog.write(
-//                StatsdStatsLog.APP_BREADCRUMB_REPORTED,
-//                callingUid,
-//                label,
-//                StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__START);
-        return true;
-    }
-
-    /**
-     * Logs a stop event.
-     *
-     * @param label developer-chosen label.
-     * @return True if the log request was sent to statsd.
-     */
-    public static boolean logStop(int label) {
-        int callingUid = Process.myUid();
-//        StatsdStatsLog.write(
-//                StatsdStatsLog.APP_BREADCRUMB_REPORTED,
-//                callingUid,
-//                label,
-//                StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__STOP);
-        return true;
-    }
-
-    /**
-     * Logs an event that does not represent a start or stop boundary.
-     *
-     * @param label developer-chosen label.
-     * @return True if the log request was sent to statsd.
-     */
-    public static boolean logEvent(int label) {
-        int callingUid = Process.myUid();
-//        StatsdStatsLog.write(
-//                StatsdStatsLog.APP_BREADCRUMB_REPORTED,
-//                callingUid,
-//                label,
-//                StatsdStatsLog.APP_BREADCRUMB_REPORTED__STATE__UNSPECIFIED);
-        return true;
-    }
-
-    /**
-     * Logs an event for binary push for module updates.
-     *
-     * @param trainName        name of install train.
-     * @param trainVersionCode version code of the train.
-     * @param options          optional flags about this install.
-     *                         The last 3 bits indicate options:
-     *                             0x01: FLAG_REQUIRE_STAGING
-     *                             0x02: FLAG_ROLLBACK_ENABLED
-     *                             0x04: FLAG_REQUIRE_LOW_LATENCY_MONITOR
-     * @param state            current install state. Defined as State enums in
-     *                         BinaryPushStateChanged atom in
-     *                         frameworks/proto_logging/stats/atoms.proto
-     * @param experimentIds    experiment ids.
-     * @return True if the log request was sent to statsd.
-     */
-    @RequiresPermission(allOf = {DUMP, PACKAGE_USAGE_STATS})
-    public static boolean logBinaryPushStateChanged(@NonNull String trainName,
-            long trainVersionCode, int options, int state,
-            @NonNull long[] experimentIds) {
-        ProtoOutputStream proto = new ProtoOutputStream();
-        for (long id : experimentIds) {
-            proto.write(
-                    ProtoOutputStream.FIELD_TYPE_INT64
-                    | ProtoOutputStream.FIELD_COUNT_REPEATED
-                    | EXPERIMENT_IDS_FIELD_ID,
-                    id);
-        }
-//        StatsdStatsLog.write(StatsdStatsLog.BINARY_PUSH_STATE_CHANGED,
-//                trainName,
-//                trainVersionCode,
-//                (options & IStatsd.FLAG_REQUIRE_STAGING) > 0,
-//                (options & IStatsd.FLAG_ROLLBACK_ENABLED) > 0,
-//                (options & IStatsd.FLAG_REQUIRE_LOW_LATENCY_MONITOR) > 0,
-//                state,
-//                proto.getBytes(),
-//                0,
-//                0,
-//                false);
-        return true;
-    }
-
-    /**
-     * Write an event to stats log using the raw format.
-     *
-     * @param buffer    The encoded buffer of data to write.
-     * @param size      The number of bytes from the buffer to write.
-     * @hide
-     * @deprecated Use {@link write(final StatsEvent statsEvent)} instead.
-     *
-     */
-    @Deprecated
-    @SystemApi
-    public static void writeRaw(@NonNull byte[] buffer, int size) {
-        writeImpl(buffer, size, 0);
-    }
-
-    /**
-     * Write an event to stats log using the raw format.
-     *
-     * @param buffer    The encoded buffer of data to write.
-     * @param size      The number of bytes from the buffer to write.
-     * @param atomId    The id of the atom to which the event belongs.
-     */
-//    private static native void writeImpl(@NonNull byte[] buffer, int size, int atomId);
-    private static void writeImpl(@NonNull byte[] buffer, int size, int atomId) {
-        // no-op for now
-    }
-
-    /**
-     * Write an event to stats log using the raw format encapsulated in StatsEvent.
-     * After writing to stats log, release() is called on the StatsEvent object.
-     * No further action should be taken on the StatsEvent object following this call.
-     *
-     * @param statsEvent    The StatsEvent object containing the encoded buffer of data to write.
-     * @hide
-     */
-    @SystemApi
-    public static void write(@NonNull final StatsEvent statsEvent) {
-        writeImpl(statsEvent.getBytes(), statsEvent.getNumBytes(), statsEvent.getAtomId());
-        statsEvent.release();
-    }
-}
diff --git a/ravenwood/scripts/ravenwood-stats-collector.sh b/ravenwood/scripts/ravenwood-stats-collector.sh
index 36601bd..b83216a 100755
--- a/ravenwood/scripts/ravenwood-stats-collector.sh
+++ b/ravenwood/scripts/ravenwood-stats-collector.sh
@@ -62,6 +62,8 @@
 
         dump "framework-minus-apex" hoststubgen_framework-minus-apex_stats.csv
         dump "service.core"  hoststubgen_services.core_stats.csv
+        dump "framework-configinfrastructure"  framework-configinfrastructure_stats.csv
+        dump "framework-statsd"  framework-statsd_stats.csv
     } > "$out"
 
     echo "Stats CVS created at $out"
@@ -76,6 +78,8 @@
 
         dump "framework-minus-apex"  hoststubgen_framework-minus-apex_apis.csv
         dump "service.core"  hoststubgen_services.core_apis.csv
+        dump "framework-configinfrastructure"  framework-configinfrastructure_apis.csv
+        dump "framework-statsd"  framework-statsd_apis.csv
     } > "$out"
 
     echo "API CVS created at $out"
diff --git a/ravenwood/tests/coretest/Android.bp b/ravenwood/tests/coretest/Android.bp
index 85f1baf..412744e 100644
--- a/ravenwood/tests/coretest/Android.bp
+++ b/ravenwood/tests/coretest/Android.bp
@@ -23,6 +23,7 @@
     ],
     srcs: [
         "test/**/*.java",
+        "test/**/*.kt",
     ],
     ravenizer: {
         strip_mockito: true,
diff --git a/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodStatsDTest.kt b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodStatsDTest.kt
new file mode 100644
index 0000000..d5f5e29
--- /dev/null
+++ b/ravenwood/tests/coretest/test/com/android/ravenwoodtest/coretest/RavenwoodStatsDTest.kt
@@ -0,0 +1,26 @@
+/*
+ * Copyright (C) 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.ravenwoodtest.coretest
+
+import com.android.internal.util.FrameworkStatsLog
+import org.junit.Test
+
+class RavenwoodStatsDTest {
+    @Test
+    fun testFrameworkStatsLog() {
+        FrameworkStatsLog.write(FrameworkStatsLog.PHONE_SIGNAL_STRENGTH_CHANGED, 123)
+    }
+}
\ No newline at end of file
diff --git a/ravenwood/texts/ravenwood-framework-policies.txt b/ravenwood/texts/ravenwood-framework-policies.txt
index b64944e..80126df 100644
--- a/ravenwood/texts/ravenwood-framework-policies.txt
+++ b/ravenwood/texts/ravenwood-framework-policies.txt
@@ -5,8 +5,7 @@
 rename com/.*/nano/   devicenano/
 rename android/.*/nano/   devicenano/
 
-
-# StatsD autogenerated classes. Maybe add a heuristic?
+# StatsD auto-generated
 class com.android.internal.util.FrameworkStatsLog keepclass
 
 # Exported to Mainline modules; cannot use annotations