diff --git a/thread/framework/java/android/net/thread/ActiveOperationalDataset.aidl b/thread/framework/java/android/net/thread/ActiveOperationalDataset.aidl
new file mode 100644
index 0000000..8bf12a4
--- /dev/null
+++ b/thread/framework/java/android/net/thread/ActiveOperationalDataset.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2023 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.net.thread;
+
+parcelable ActiveOperationalDataset;
diff --git a/thread/framework/java/android/net/thread/ActiveOperationalDataset.java b/thread/framework/java/android/net/thread/ActiveOperationalDataset.java
new file mode 100644
index 0000000..c9b047a
--- /dev/null
+++ b/thread/framework/java/android/net/thread/ActiveOperationalDataset.java
@@ -0,0 +1,1165 @@
+/*
+ * Copyright (C) 2023 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.net.thread;
+
+import static android.net.thread.ActiveOperationalDataset.SecurityPolicy.DEFAULT_ROTATION_TIME_HOURS;
+
+import static com.android.internal.util.Preconditions.checkArgument;
+import static com.android.internal.util.Preconditions.checkState;
+import static com.android.net.module.util.HexDump.dumpHexString;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.Size;
+import android.annotation.SystemApi;
+import android.net.IpPrefix;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.SparseArray;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.ByteArrayOutputStream;
+import java.net.Inet6Address;
+import java.net.UnknownHostException;
+import java.security.SecureRandom;
+import java.time.Instant;
+import java.util.Arrays;
+import java.util.Random;
+
+/**
+ * Data interface for managing a Thread Active Operational Dataset.
+ *
+ * <p>An example usage of creating an Active Operational Dataset with random parameters:
+ *
+ * <pre>{@code
+ * ActiveOperationalDataset activeDataset = ActiveOperationalDataset.createRandomDataset();
+ * }</pre>
+ *
+ * <p>or random Dataset with customized Network Name:
+ *
+ * <pre>{@code
+ * ActiveOperationalDataset activeDataset =
+ *         new ActiveOperationalDataset.Builder(ActiveOperationalDataset.createRandomDataset())
+ *                 .setNetworkName("MyThreadNet").build();
+ * }</pre>
+ *
+ * <p>If the Active Operational Dataset is already known as <a
+ * href="https://www.threadgroup.org">Thread TLVs</a>, you can simply use:
+ *
+ * <pre>{@code
+ * ActiveOperationalDataset activeDataset = ActiveOperationalDataset.fromThreadTlvs(datasetTlvs);
+ * }</pre>
+ *
+ * @hide
+ */
+@FlaggedApi(ThreadNetworkFlags.FLAG_THREAD_ENABLED)
+@SystemApi
+public final class ActiveOperationalDataset implements Parcelable {
+    /** The maximum length of the Active Operational Dataset TLV array in bytes. */
+    public static final int LENGTH_MAX_DATASET_TLVS = 254;
+    /** The length of Extended PAN ID in bytes. */
+    public static final int LENGTH_EXTENDED_PAN_ID = 8;
+    /** The minimum length of Network Name as UTF-8 bytes. */
+    public static final int LENGTH_MIN_NETWORK_NAME_BYTES = 1;
+    /** The maximum length of Network Name as UTF-8 bytes. */
+    public static final int LENGTH_MAX_NETWORK_NAME_BYTES = 16;
+    /** The length of Network Key in bytes. */
+    public static final int LENGTH_NETWORK_KEY = 16;
+    /** The length of Mesh-Local Prefix in bits. */
+    public static final int LENGTH_MESH_LOCAL_PREFIX_BITS = 64;
+    /** The length of PSKc in bytes. */
+    public static final int LENGTH_PSKC = 16;
+    /** The 2.4 GHz channel page. */
+    public static final int CHANNEL_PAGE_24_GHZ = 0;
+    /** The minimum 2.4GHz channel. */
+    public static final int CHANNEL_MIN_24_GHZ = 11;
+    /** The maximum 2.4GHz channel. */
+    public static final int CHANNEL_MAX_24_GHZ = 26;
+    /** @hide */
+    @VisibleForTesting public static final int TYPE_CHANNEL = 0;
+    /** @hide */
+    @VisibleForTesting public static final int TYPE_PAN_ID = 1;
+    /** @hide */
+    @VisibleForTesting public static final int TYPE_EXTENDED_PAN_ID = 2;
+    /** @hide */
+    @VisibleForTesting public static final int TYPE_NETWORK_NAME = 3;
+    /** @hide */
+    @VisibleForTesting public static final int TYPE_PSKC = 4;
+    /** @hide */
+    @VisibleForTesting public static final int TYPE_NETWORK_KEY = 5;
+    /** @hide */
+    @VisibleForTesting public static final int TYPE_MESH_LOCAL_PREFIX = 7;
+    /** @hide */
+    @VisibleForTesting public static final int TYPE_SECURITY_POLICY = 12;
+    /** @hide */
+    @VisibleForTesting public static final int TYPE_ACTIVE_TIMESTAMP = 14;
+    /** @hide */
+    @VisibleForTesting public static final int TYPE_CHANNEL_MASK = 53;
+
+    private static final byte MESH_LOCAL_PREFIX_FIRST_BYTE = (byte) 0xfd;
+    private static final int LENGTH_CHANNEL = 3;
+    private static final int LENGTH_PAN_ID = 2;
+
+    @NonNull
+    public static final Creator<ActiveOperationalDataset> CREATOR =
+            new Creator<>() {
+                @Override
+                public ActiveOperationalDataset createFromParcel(Parcel in) {
+                    return ActiveOperationalDataset.fromThreadTlvs(in.createByteArray());
+                }
+
+                @Override
+                public ActiveOperationalDataset[] newArray(int size) {
+                    return new ActiveOperationalDataset[size];
+                }
+            };
+
+    private final OperationalDatasetTimestamp mActiveTimestamp;
+    private final String mNetworkName;
+    private final byte[] mExtendedPanId;
+    private final int mPanId;
+    private final int mChannel;
+    private final int mChannelPage;
+    private final SparseArray<byte[]> mChannelMask;
+    private final byte[] mPskc;
+    private final byte[] mNetworkKey;
+    private final IpPrefix mMeshLocalPrefix;
+    private final SecurityPolicy mSecurityPolicy;
+    private final SparseArray<byte[]> mUnknownTlvs;
+
+    private ActiveOperationalDataset(Builder builder) {
+        this(
+                requireNonNull(builder.mActiveTimestamp),
+                requireNonNull(builder.mNetworkName),
+                requireNonNull(builder.mExtendedPanId),
+                requireNonNull(builder.mPanId),
+                requireNonNull(builder.mChannelPage),
+                requireNonNull(builder.mChannel),
+                requireNonNull(builder.mChannelMask),
+                requireNonNull(builder.mPskc),
+                requireNonNull(builder.mNetworkKey),
+                requireNonNull(builder.mMeshLocalPrefix),
+                requireNonNull(builder.mSecurityPolicy),
+                requireNonNull(builder.mUnknownTlvs));
+    }
+
+    private ActiveOperationalDataset(
+            OperationalDatasetTimestamp activeTimestamp,
+            String networkName,
+            byte[] extendedPanId,
+            int panId,
+            int channelPage,
+            int channel,
+            SparseArray<byte[]> channelMask,
+            byte[] pskc,
+            byte[] networkKey,
+            IpPrefix meshLocalPrefix,
+            SecurityPolicy securityPolicy,
+            SparseArray<byte[]> unknownTlvs) {
+        this.mActiveTimestamp = activeTimestamp;
+        this.mNetworkName = networkName;
+        this.mExtendedPanId = extendedPanId.clone();
+        this.mPanId = panId;
+        this.mChannel = channel;
+        this.mChannelPage = channelPage;
+        this.mChannelMask = deepCloneSparseArray(channelMask);
+        this.mPskc = pskc.clone();
+        this.mNetworkKey = networkKey.clone();
+        this.mMeshLocalPrefix = meshLocalPrefix;
+        this.mSecurityPolicy = securityPolicy;
+        this.mUnknownTlvs = deepCloneSparseArray(unknownTlvs);
+    }
+
+    /**
+     * Creates a new {@link ActiveOperationalDataset} object from a series of Thread TLVs.
+     *
+     * <p>{@code tlvs} can be obtained from the value of a Thread Active Operational Dataset TLV
+     * (see the <a href="https://www.threadgroup.org/support#specifications">Thread
+     * specification</a> for the definition) or the return value of {@link #toThreadTlvs}.
+     *
+     * @param tlvs a series of Thread TLVs which contain the Active Operational Dataset
+     * @return the decoded Active Operational Dataset
+     * @throws IllegalArgumentException if {@code tlvs} is malformed or the length is larger than
+     *     {@link LENGTH_MAX_DATASET_TLVS}
+     */
+    @NonNull
+    public static ActiveOperationalDataset fromThreadTlvs(@NonNull byte[] tlvs) {
+        requireNonNull(tlvs, "tlvs cannot be null");
+        if (tlvs.length > LENGTH_MAX_DATASET_TLVS) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "tlvs length exceeds max length %d (actual is %d)",
+                            LENGTH_MAX_DATASET_TLVS, tlvs.length));
+        }
+
+        Builder builder = new Builder();
+        int i = 0;
+        while (i < tlvs.length) {
+            int type = tlvs[i++] & 0xff;
+            if (i >= tlvs.length) {
+                throw new IllegalArgumentException(
+                        String.format(
+                                "Found TLV type %d at end of operational dataset with length %d",
+                                type, tlvs.length));
+            }
+
+            int length = tlvs[i++] & 0xff;
+            if (i + length > tlvs.length) {
+                throw new IllegalArgumentException(
+                        String.format(
+                                "Found TLV type %d with length %d which exceeds the remaining data"
+                                        + " in the operational dataset with length %d",
+                                type, length, tlvs.length));
+            }
+
+            initWithTlv(builder, type, Arrays.copyOfRange(tlvs, i, i + length));
+            i += length;
+        }
+        try {
+            return builder.build();
+        } catch (IllegalStateException e) {
+            throw new IllegalArgumentException(
+                    "Failed to build the ActiveOperationalDataset object", e);
+        }
+    }
+
+    private static void initWithTlv(Builder builder, int type, byte[] value) {
+        // The max length of the dataset is 254 bytes, so the max length of a single TLV value is
+        // 252 (254 - 1 - 1)
+        if (value.length > LENGTH_MAX_DATASET_TLVS - 2) {
+            throw new IllegalArgumentException(
+                    String.format(
+                            "Length of TLV %d exceeds %d (actualLength = %d)",
+                            (type & 0xff), LENGTH_MAX_DATASET_TLVS - 2, value.length));
+        }
+
+        switch (type) {
+            case TYPE_CHANNEL:
+                checkArgument(
+                        value.length == LENGTH_CHANNEL,
+                        "Invalid channel (length = %d, expectedLength = %d)",
+                        value.length,
+                        LENGTH_CHANNEL);
+                builder.setChannel((value[0] & 0xff), ((value[1] & 0xff) << 8) | (value[2] & 0xff));
+                break;
+            case TYPE_PAN_ID:
+                checkArgument(
+                        value.length == LENGTH_PAN_ID,
+                        "Invalid PAN ID (length = %d, expectedLength = %d)",
+                        value.length,
+                        LENGTH_PAN_ID);
+                builder.setPanId(((value[0] & 0xff) << 8) | (value[1] & 0xff));
+                break;
+            case TYPE_EXTENDED_PAN_ID:
+                builder.setExtendedPanId(value);
+                break;
+            case TYPE_NETWORK_NAME:
+                builder.setNetworkName(new String(value, UTF_8));
+                break;
+            case TYPE_PSKC:
+                builder.setPskc(value);
+                break;
+            case TYPE_NETWORK_KEY:
+                builder.setNetworkKey(value);
+                break;
+            case TYPE_MESH_LOCAL_PREFIX:
+                builder.setMeshLocalPrefix(value);
+                break;
+            case TYPE_SECURITY_POLICY:
+                builder.setSecurityPolicy(SecurityPolicy.fromTlvValue(value));
+                break;
+            case TYPE_ACTIVE_TIMESTAMP:
+                builder.setActiveTimestamp(OperationalDatasetTimestamp.fromTlvValue(value));
+                break;
+            case TYPE_CHANNEL_MASK:
+                builder.setChannelMask(decodeChannelMask(value));
+                break;
+            default:
+                builder.addUnknownTlv(type & 0xff, value);
+                break;
+        }
+    }
+
+    private static SparseArray<byte[]> decodeChannelMask(byte[] tlvValue) {
+        SparseArray<byte[]> channelMask = new SparseArray<>();
+        int i = 0;
+        while (i < tlvValue.length) {
+            int channelPage = tlvValue[i++] & 0xff;
+            if (i >= tlvValue.length) {
+                throw new IllegalArgumentException(
+                        "Invalid channel mask - channel mask length is missing");
+            }
+
+            int maskLength = tlvValue[i++] & 0xff;
+            if (i + maskLength > tlvValue.length) {
+                throw new IllegalArgumentException(
+                        String.format(
+                                "Invalid channel mask - channel mask is incomplete "
+                                        + "(offset = %d, length = %d, totalLength = %d)",
+                                i, maskLength, tlvValue.length));
+            }
+
+            channelMask.put(channelPage, Arrays.copyOfRange(tlvValue, i, i + maskLength));
+            i += maskLength;
+        }
+        return channelMask;
+    }
+
+    private static void encodeChannelMask(
+            SparseArray<byte[]> channelMask, ByteArrayOutputStream outputStream) {
+        ByteArrayOutputStream entryStream = new ByteArrayOutputStream();
+
+        for (int i = 0; i < channelMask.size(); i++) {
+            int key = channelMask.keyAt(i);
+            byte[] value = channelMask.get(key);
+            entryStream.write(key);
+            entryStream.write(value.length);
+            entryStream.write(value, 0, value.length);
+        }
+
+        byte[] entries = entryStream.toByteArray();
+
+        outputStream.write(TYPE_CHANNEL_MASK);
+        outputStream.write(entries.length);
+        outputStream.write(entries, 0, entries.length);
+    }
+
+    /**
+     * Creates a new {@link ActiveOperationalDataset} object with randomized or default parameters.
+     *
+     * <p>The randomized (or default) value for each parameter:
+     *
+     * <ul>
+     *   <li>{@code Active Timestamp} defaults to {@code new OperationalDatasetTimestamp(1, 0,
+     *       false)}
+     *   <li>{@code Network Name} defaults to "THREAD-PAN-<PAN ID decimal>", for example
+     *       "THREAD-PAN-12345"
+     *   <li>{@code Extended PAN ID} filled with randomly generated bytes
+     *   <li>{@code PAN ID} randomly generated integer in range of [0, 0xfffe]
+     *   <li>{@code Channel Page} defaults to {@link #CHANNEL_PAGE_24_GHZ}
+     *   <li>{@code Channel} randomly selected channel in range of [{@link #CHANNEL_MIN_24_GHZ},
+     *       {@link #CHANNEL_MAX_24_GHZ}]
+     *   <li>{@code Channel Mask} all bits from {@link #CHANNEL_MIN_24_GHZ} to {@link
+     *       #CHANNEL_MAX_24_GHZ} are set to {@code true}
+     *   <li>{@code PSKc} filled with bytes generated by secure random generator
+     *   <li>{@code Network Key} filled with bytes generated by secure random generator
+     *   <li>{@code Mesh-local Prefix} filled with randomly generated bytes except that the first
+     *       byte is always set to {@code 0xfd}
+     *   <li>{@code Security Policy} defaults to {@code new SecurityPolicy(
+     *       DEFAULT_ROTATION_TIME_HOURS, new byte[]{(byte)0xff, (byte)0xf8})}. This is the default
+     *       values required by the Thread 1.2 specification
+     * </ul>
+     *
+     * <p>This method is the recommended way to create a randomized operational dataset for a new
+     * Thread network. It may be desired to change one or more of the generated value(s). For
+     * example, to use a more meaningful Network Name. To do that, create a new {@link Builder}
+     * object from this dataset with {@link Builder#Builder(ActiveOperationalDataset)} and override
+     * the value with the setters of {@link Builder}.
+     *
+     * <p>Note that it's highly discouraged to change the randomly generated Extended PAN ID,
+     * Network Key or PSKc, as it will compromise the security of a Thread network.
+     */
+    @NonNull
+    public static ActiveOperationalDataset createRandomDataset() {
+        return createRandomDataset(new Random(Instant.now().toEpochMilli()), new SecureRandom());
+    }
+
+    /** @hide */
+    @VisibleForTesting
+    public static ActiveOperationalDataset createRandomDataset(
+            Random random, SecureRandom secureRandom) {
+        int panId = random.nextInt(/* bound= */ 0xffff);
+        byte[] meshLocalPrefix = newRandomBytes(random, LENGTH_MESH_LOCAL_PREFIX_BITS / 8);
+        meshLocalPrefix[0] = MESH_LOCAL_PREFIX_FIRST_BYTE;
+
+        SparseArray<byte[]> channelMask = new SparseArray<>(1);
+        channelMask.put(CHANNEL_PAGE_24_GHZ, new byte[] {0x00, 0x1f, (byte) 0xff, (byte) 0xe0});
+
+        return new Builder()
+                .setActiveTimestamp(
+                        new OperationalDatasetTimestamp(
+                                /* seconds= */ 1,
+                                /* ticks= */ 0,
+                                /* isAuthoritativeSource= */ false))
+                .setExtendedPanId(newRandomBytes(random, LENGTH_EXTENDED_PAN_ID))
+                .setPanId(panId)
+                .setNetworkName("THREAD-PAN-" + panId)
+                .setChannel(
+                        CHANNEL_PAGE_24_GHZ,
+                        random.nextInt(CHANNEL_MAX_24_GHZ - CHANNEL_MIN_24_GHZ + 1)
+                                + CHANNEL_MIN_24_GHZ)
+                .setChannelMask(channelMask)
+                .setPskc(newRandomBytes(secureRandom, LENGTH_PSKC))
+                .setNetworkKey(newRandomBytes(secureRandom, LENGTH_NETWORK_KEY))
+                .setMeshLocalPrefix(meshLocalPrefix)
+                .setSecurityPolicy(
+                        new SecurityPolicy(
+                                DEFAULT_ROTATION_TIME_HOURS, new byte[] {(byte) 0xff, (byte) 0xf8}))
+                .build();
+    }
+
+    private static byte[] newRandomBytes(Random random, int length) {
+        byte[] result = new byte[length];
+        random.nextBytes(result);
+        return result;
+    }
+
+    private static boolean areByteSparseArraysEqual(
+            @NonNull SparseArray<byte[]> first, @NonNull SparseArray<byte[]> second) {
+        if (first == second) {
+            return true;
+        } else if (first == null || second == null) {
+            return false;
+        } else if (first.size() != second.size()) {
+            return false;
+        } else {
+            for (int i = 0; i < first.size(); i++) {
+                int firstKey = first.keyAt(i);
+                int secondKey = second.keyAt(i);
+                if (firstKey != secondKey) {
+                    return false;
+                }
+
+                byte[] firstValue = first.valueAt(i);
+                byte[] secondValue = second.valueAt(i);
+                if (!Arrays.equals(firstValue, secondValue)) {
+                    return false;
+                }
+            }
+            return true;
+        }
+    }
+
+    /** An easy-to-use wrapper of {@link Arrays#deepHashCode}. */
+    private static int deepHashCode(Object... values) {
+        return Arrays.deepHashCode(values);
+    }
+
+    /**
+     * Converts this {@link ActiveOperationalDataset} object to a series of Thread TLVs.
+     *
+     * <p>See the <a href="https://www.threadgroup.org/support#specifications">Thread
+     * specification</a> for the definition of the Thread TLV format.
+     *
+     * @return a series of Thread TLVs which contain this Active Operational Dataset
+     */
+    @NonNull
+    public byte[] toThreadTlvs() {
+        ByteArrayOutputStream dataset = new ByteArrayOutputStream();
+
+        dataset.write(TYPE_ACTIVE_TIMESTAMP);
+        byte[] activeTimestampBytes = mActiveTimestamp.toTlvValue();
+        dataset.write(activeTimestampBytes.length);
+        dataset.write(activeTimestampBytes, 0, activeTimestampBytes.length);
+
+        dataset.write(TYPE_NETWORK_NAME);
+        byte[] networkNameBytes = mNetworkName.getBytes(UTF_8);
+        dataset.write(networkNameBytes.length);
+        dataset.write(networkNameBytes, 0, networkNameBytes.length);
+
+        dataset.write(TYPE_EXTENDED_PAN_ID);
+        dataset.write(mExtendedPanId.length);
+        dataset.write(mExtendedPanId, 0, mExtendedPanId.length);
+
+        dataset.write(TYPE_PAN_ID);
+        dataset.write(LENGTH_PAN_ID);
+        dataset.write(mPanId >> 8);
+        dataset.write(mPanId);
+
+        dataset.write(TYPE_CHANNEL);
+        dataset.write(LENGTH_CHANNEL);
+        dataset.write(mChannelPage);
+        dataset.write(mChannel >> 8);
+        dataset.write(mChannel);
+
+        encodeChannelMask(mChannelMask, dataset);
+
+        dataset.write(TYPE_PSKC);
+        dataset.write(mPskc.length);
+        dataset.write(mPskc, 0, mPskc.length);
+
+        dataset.write(TYPE_NETWORK_KEY);
+        dataset.write(mNetworkKey.length);
+        dataset.write(mNetworkKey, 0, mNetworkKey.length);
+
+        dataset.write(TYPE_MESH_LOCAL_PREFIX);
+        dataset.write(mMeshLocalPrefix.getPrefixLength() / 8);
+        dataset.write(mMeshLocalPrefix.getRawAddress(), 0, mMeshLocalPrefix.getPrefixLength() / 8);
+
+        dataset.write(TYPE_SECURITY_POLICY);
+        byte[] securityPolicyBytes = mSecurityPolicy.toTlvValue();
+        dataset.write(securityPolicyBytes.length);
+        dataset.write(securityPolicyBytes, 0, securityPolicyBytes.length);
+
+        for (int i = 0; i < mUnknownTlvs.size(); i++) {
+            byte[] value = mUnknownTlvs.valueAt(i);
+            dataset.write(mUnknownTlvs.keyAt(i));
+            dataset.write(value.length);
+            dataset.write(value, 0, value.length);
+        }
+
+        return dataset.toByteArray();
+    }
+
+    /** Returns the Active Timestamp. */
+    @NonNull
+    public OperationalDatasetTimestamp getActiveTimestamp() {
+        return mActiveTimestamp;
+    }
+
+    /** Returns the Network Name. */
+    @NonNull
+    @Size(min = LENGTH_MIN_NETWORK_NAME_BYTES, max = LENGTH_MAX_NETWORK_NAME_BYTES)
+    public String getNetworkName() {
+        return mNetworkName;
+    }
+
+    /** Returns the Extended PAN ID. */
+    @NonNull
+    @Size(LENGTH_EXTENDED_PAN_ID)
+    public byte[] getExtendedPanId() {
+        return mExtendedPanId.clone();
+    }
+
+    /** Returns the PAN ID. */
+    @IntRange(from = 0, to = 0xfffe)
+    public int getPanId() {
+        return mPanId;
+    }
+
+    /** Returns the Channel. */
+    @IntRange(from = 0, to = 65535)
+    public int getChannel() {
+        return mChannel;
+    }
+
+    /** Returns the Channel Page. */
+    @IntRange(from = 0, to = 255)
+    public int getChannelPage() {
+        return mChannelPage;
+    }
+
+    /**
+     * Returns the Channel masks. For the returned {@link SparseArray}, the key is the Channel Page
+     * and the value is the Channel Mask.
+     */
+    @NonNull
+    @Size(min = 1)
+    public SparseArray<byte[]> getChannelMask() {
+        return deepCloneSparseArray(mChannelMask);
+    }
+
+    private static SparseArray<byte[]> deepCloneSparseArray(SparseArray<byte[]> src) {
+        SparseArray<byte[]> dst = new SparseArray<>(src.size());
+        for (int i = 0; i < src.size(); i++) {
+            dst.put(src.keyAt(i), src.valueAt(i).clone());
+        }
+        return dst;
+    }
+
+    /** Returns the PSKc. */
+    @NonNull
+    @Size(LENGTH_PSKC)
+    public byte[] getPskc() {
+        return mPskc.clone();
+    }
+
+    /** Returns the Network Key. */
+    @NonNull
+    @Size(LENGTH_NETWORK_KEY)
+    public byte[] getNetworkKey() {
+        return mNetworkKey.clone();
+    }
+
+    /**
+     * Returns the Mesh-local Prefix. The length of the returned prefix is always {@link
+     * #LENGTH_MESH_LOCAL_PREFIX_BITS}.
+     */
+    @NonNull
+    public IpPrefix getMeshLocalPrefix() {
+        return mMeshLocalPrefix;
+    }
+
+    /** Returns the Security Policy. */
+    @NonNull
+    public SecurityPolicy getSecurityPolicy() {
+        return mSecurityPolicy;
+    }
+
+    /**
+     * Returns Thread TLVs which are not recognized by this device. The returned {@link SparseArray}
+     * associates TLV values to their keys.
+     *
+     * @hide
+     */
+    @NonNull
+    public SparseArray<byte[]> getUnknownTlvs() {
+        return deepCloneSparseArray(mUnknownTlvs);
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeByteArray(toThreadTlvs());
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (other == this) {
+            return true;
+        } else if (!(other instanceof ActiveOperationalDataset)) {
+            return false;
+        } else {
+            ActiveOperationalDataset otherDataset = (ActiveOperationalDataset) other;
+            return mActiveTimestamp.equals(otherDataset.mActiveTimestamp)
+                    && mNetworkName.equals(otherDataset.mNetworkName)
+                    && Arrays.equals(mExtendedPanId, otherDataset.mExtendedPanId)
+                    && mPanId == otherDataset.mPanId
+                    && mChannelPage == otherDataset.mChannelPage
+                    && mChannel == otherDataset.mChannel
+                    && areByteSparseArraysEqual(mChannelMask, otherDataset.mChannelMask)
+                    && Arrays.equals(mPskc, otherDataset.mPskc)
+                    && Arrays.equals(mNetworkKey, otherDataset.mNetworkKey)
+                    && mMeshLocalPrefix.equals(otherDataset.mMeshLocalPrefix)
+                    && mSecurityPolicy.equals(otherDataset.mSecurityPolicy)
+                    && areByteSparseArraysEqual(mUnknownTlvs, otherDataset.mUnknownTlvs);
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return deepHashCode(
+                mActiveTimestamp,
+                mNetworkName,
+                mExtendedPanId,
+                mPanId,
+                mChannel,
+                mChannelPage,
+                mChannelMask,
+                mPskc,
+                mNetworkKey,
+                mMeshLocalPrefix,
+                mSecurityPolicy);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{networkName=")
+                .append(getNetworkName())
+                .append(", extendedPanId=")
+                .append(dumpHexString(getExtendedPanId()))
+                .append(", panId=")
+                .append(getPanId())
+                .append(", channel=")
+                .append(getChannel())
+                .append(", activeTimestamp=")
+                .append(getActiveTimestamp())
+                .append("}");
+        return sb.toString();
+    }
+
+    /** The builder for creating {@link ActiveOperationalDataset} objects. */
+    public static final class Builder {
+        private OperationalDatasetTimestamp mActiveTimestamp;
+        private String mNetworkName;
+        private byte[] mExtendedPanId;
+        private Integer mPanId;
+        private Integer mChannel;
+        private Integer mChannelPage;
+        private SparseArray<byte[]> mChannelMask;
+        private byte[] mPskc;
+        private byte[] mNetworkKey;
+        private IpPrefix mMeshLocalPrefix;
+        private SecurityPolicy mSecurityPolicy;
+        private SparseArray<byte[]> mUnknownTlvs;
+
+        /**
+         * Creates a {@link Builder} object with values from an {@link ActiveOperationalDataset}
+         * object.
+         */
+        public Builder(@NonNull ActiveOperationalDataset activeOpDataset) {
+            requireNonNull(activeOpDataset, "activeOpDataset cannot be null");
+
+            this.mActiveTimestamp = activeOpDataset.mActiveTimestamp;
+            this.mNetworkName = activeOpDataset.mNetworkName;
+            this.mExtendedPanId = activeOpDataset.mExtendedPanId.clone();
+            this.mPanId = activeOpDataset.mPanId;
+            this.mChannel = activeOpDataset.mChannel;
+            this.mChannelPage = activeOpDataset.mChannelPage;
+            this.mChannelMask = deepCloneSparseArray(activeOpDataset.mChannelMask);
+            this.mPskc = activeOpDataset.mPskc.clone();
+            this.mNetworkKey = activeOpDataset.mNetworkKey.clone();
+            this.mMeshLocalPrefix = activeOpDataset.mMeshLocalPrefix;
+            this.mSecurityPolicy = activeOpDataset.mSecurityPolicy;
+            this.mUnknownTlvs = deepCloneSparseArray(activeOpDataset.mUnknownTlvs);
+        }
+
+        /**
+         * Creates an empty {@link Builder} object.
+         *
+         * <p>An empty builder cannot build a new {@link ActiveOperationalDataset} object. The
+         * Active Operational Dataset parameters must be set with setters of this builder.
+         */
+        public Builder() {
+            mChannelMask = new SparseArray<>();
+            mUnknownTlvs = new SparseArray<>();
+        }
+
+        /**
+         * Sets the Active Timestamp.
+         *
+         * @param activeTimestamp Active Timestamp of the Operational Dataset
+         */
+        @NonNull
+        public Builder setActiveTimestamp(@NonNull OperationalDatasetTimestamp activeTimestamp) {
+            requireNonNull(activeTimestamp, "activeTimestamp cannot be null");
+            this.mActiveTimestamp = activeTimestamp;
+            return this;
+        }
+
+        /**
+         * Sets the Network Name.
+         *
+         * @param networkName the name of the Thread network
+         * @throws IllegalArgumentException if length of the UTF-8 representation of {@code
+         *     networkName} isn't in range of [{@link #LENGTH_MIN_NETWORK_NAME_BYTES}, {@link
+         *     #LENGTH_MAX_NETWORK_NAME_BYTES}].
+         */
+        @NonNull
+        public Builder setNetworkName(
+                @NonNull
+                        @Size(
+                                min = LENGTH_MIN_NETWORK_NAME_BYTES,
+                                max = LENGTH_MAX_NETWORK_NAME_BYTES)
+                        String networkName) {
+            requireNonNull(networkName, "networkName cannot be null");
+
+            int nameLength = networkName.getBytes(UTF_8).length;
+            checkArgument(
+                    nameLength >= LENGTH_MIN_NETWORK_NAME_BYTES
+                            && nameLength <= LENGTH_MAX_NETWORK_NAME_BYTES,
+                    "Invalid network name (length = %d, expectedLengthRange = [%d, %d])",
+                    nameLength,
+                    LENGTH_MIN_NETWORK_NAME_BYTES,
+                    LENGTH_MAX_NETWORK_NAME_BYTES);
+            this.mNetworkName = networkName;
+            return this;
+        }
+
+        /**
+         * Sets the Extended PAN ID.
+         *
+         * <p>Use with caution. A randomly generated Extended PAN ID should be used for real Thread
+         * networks. It's discouraged to call this method to override the default value created by
+         * {@link ActiveOperationalDataset#createRandomDataset} in production.
+         *
+         * @throws IllegalArgumentException if length of {@code extendedPanId} is not {@link
+         *     #LENGTH_EXTENDED_PAN_ID}.
+         */
+        @NonNull
+        public Builder setExtendedPanId(
+                @NonNull @Size(LENGTH_EXTENDED_PAN_ID) byte[] extendedPanId) {
+            requireNonNull(extendedPanId, "extendedPanId cannot be null");
+            checkArgument(
+                    extendedPanId.length == LENGTH_EXTENDED_PAN_ID,
+                    "Invalid extended PAN ID (length = %d, expectedLength = %d)",
+                    extendedPanId.length,
+                    LENGTH_EXTENDED_PAN_ID);
+            this.mExtendedPanId = extendedPanId.clone();
+            return this;
+        }
+
+        /**
+         * Sets the PAN ID.
+         *
+         * @throws IllegalArgumentException if {@code panId} is not in range of 0x0-0xfffe
+         */
+        @NonNull
+        public Builder setPanId(@IntRange(from = 0, to = 0xfffe) int panId) {
+            checkArgument(
+                    panId >= 0 && panId <= 0xfffe,
+                    "PAN ID exceeds allowed range (panid = %d, allowedRange = [0x0, 0xffff])",
+                    panId);
+            this.mPanId = panId;
+            return this;
+        }
+
+        /**
+         * Sets the Channel Page and Channel.
+         *
+         * <p>Channel Pages other than {@link #CHANNEL_PAGE_24_GHZ} are undefined and may lead to
+         * unexpected behavior if it's applied to Thread devices.
+         *
+         * @throws IllegalArgumentException if invalid channel is specified for the {@code
+         *     channelPage}
+         */
+        @NonNull
+        public Builder setChannel(
+                @IntRange(from = 0, to = 255) int page,
+                @IntRange(from = 0, to = 65535) int channel) {
+            checkArgument(
+                    page >= 0 && page <= 255,
+                    "Invalid channel page (page = %d, allowedRange = [0, 255])",
+                    page);
+            if (page == CHANNEL_PAGE_24_GHZ) {
+                checkArgument(
+                        channel >= CHANNEL_MIN_24_GHZ && channel <= CHANNEL_MAX_24_GHZ,
+                        "Invalid channel %d in page %d (allowedChannelRange = [%d, %d])",
+                        channel,
+                        page,
+                        CHANNEL_MIN_24_GHZ,
+                        CHANNEL_MAX_24_GHZ);
+            } else {
+                checkArgument(
+                        channel >= 0 && channel <= 65535,
+                        "Invalid channel %d in page %d "
+                                + "(channel = %d, allowedChannelRange = [0, 65535])",
+                        channel,
+                        page,
+                        channel);
+            }
+
+            this.mChannelPage = page;
+            this.mChannel = channel;
+            return this;
+        }
+
+        /**
+         * Sets the Channel Mask.
+         *
+         * @throws IllegalArgumentException if {@code channelMask} is empty
+         */
+        @NonNull
+        public Builder setChannelMask(@NonNull @Size(min = 1) SparseArray<byte[]> channelMask) {
+            requireNonNull(channelMask, "channelMask cannot be null");
+            checkArgument(channelMask.size() > 0, "channelMask is empty");
+            this.mChannelMask = deepCloneSparseArray(channelMask);
+            return this;
+        }
+
+        /**
+         * Sets the PSKc.
+         *
+         * <p>Use with caution. A randomly generated PSKc should be used for real Thread networks.
+         * It's discouraged to call this method to override the default value created by {@link
+         * ActiveOperationalDataset#createRandomDataset} in production.
+         *
+         * @param pskc the key stretched version of the Commissioning Credential for the network
+         * @throws IllegalArgumentException if length of {@code pskc} is not {@link #LENGTH_PSKC}
+         */
+        @NonNull
+        public Builder setPskc(@NonNull @Size(LENGTH_PSKC) byte[] pskc) {
+            requireNonNull(pskc, "pskc cannot be null");
+            checkArgument(
+                    pskc.length == LENGTH_PSKC,
+                    "Invalid PSKc length (length = %d, expectedLength = %d)",
+                    pskc.length,
+                    LENGTH_PSKC);
+            this.mPskc = pskc.clone();
+            return this;
+        }
+
+        /**
+         * Sets the Network Key.
+         *
+         * <p>Use with caution, randomly generated Network Key should be used for real Thread
+         * networks. It's discouraged to call this method to override the default value created by
+         * {@link ActiveOperationalDataset#createRandomDataset} in production.
+         *
+         * @param networkKey a 128-bit security key-derivation key for the Thread Network
+         * @throws IllegalArgumentException if length of {@code networkKey} is not {@link
+         *     #LENGTH_NETWORK_KEY}
+         */
+        @NonNull
+        public Builder setNetworkKey(@NonNull @Size(LENGTH_NETWORK_KEY) byte[] networkKey) {
+            requireNonNull(networkKey, "networkKey cannot be null");
+            checkArgument(
+                    networkKey.length == LENGTH_NETWORK_KEY,
+                    "Invalid network key length (length = %d, expectedLength = %d)",
+                    networkKey.length,
+                    LENGTH_NETWORK_KEY);
+            this.mNetworkKey = networkKey.clone();
+            return this;
+        }
+
+        /**
+         * Sets the Mesh-Local Prefix.
+         *
+         * @param meshLocalPrefix the prefix used for realm-local traffic within the mesh
+         * @throws IllegalArgumentException if prefix length of {@code meshLocalPrefix} isn't {@link
+         *     #LENGTH_MESH_LOCAL_PREFIX_BITS} or {@code meshLocalPrefix} doesn't start with {@code
+         *     0xfd}
+         */
+        @NonNull
+        public Builder setMeshLocalPrefix(@NonNull IpPrefix meshLocalPrefix) {
+            requireNonNull(meshLocalPrefix, "meshLocalPrefix cannot be null");
+            checkArgument(
+                    meshLocalPrefix.getPrefixLength() == LENGTH_MESH_LOCAL_PREFIX_BITS,
+                    "Invalid mesh-local prefix length (length = %d, expectedLength = %d)",
+                    meshLocalPrefix.getPrefixLength(),
+                    LENGTH_MESH_LOCAL_PREFIX_BITS);
+            checkArgument(
+                    meshLocalPrefix.getRawAddress()[0] == MESH_LOCAL_PREFIX_FIRST_BYTE,
+                    "Mesh-local prefix must start with 0xfd: " + meshLocalPrefix);
+            this.mMeshLocalPrefix = meshLocalPrefix;
+            return this;
+        }
+
+        @NonNull
+        private Builder setMeshLocalPrefix(byte[] meshLocalPrefix) {
+            final int prefixLength = meshLocalPrefix.length * 8;
+            checkArgument(
+                    prefixLength == LENGTH_MESH_LOCAL_PREFIX_BITS,
+                    "Invalid mesh-local prefix length (length = %d, expectedLength = %d)",
+                    prefixLength,
+                    LENGTH_MESH_LOCAL_PREFIX_BITS);
+            byte[] ip6RawAddress = new byte[16];
+            System.arraycopy(meshLocalPrefix, 0, ip6RawAddress, 0, meshLocalPrefix.length);
+            try {
+                return setMeshLocalPrefix(
+                        new IpPrefix(Inet6Address.getByAddress(ip6RawAddress), prefixLength));
+            } catch (UnknownHostException e) {
+                // Can't happen because numeric address is provided
+                throw new AssertionError(e);
+            }
+        }
+
+        /** Sets the Security Policy. */
+        @NonNull
+        public Builder setSecurityPolicy(@NonNull SecurityPolicy securityPolicy) {
+            requireNonNull(securityPolicy, "securityPolicy cannot be null");
+            this.mSecurityPolicy = securityPolicy;
+            return this;
+        }
+
+        /**
+         * Sets additional unknown TLVs.
+         *
+         * @hide
+         */
+        @NonNull
+        public Builder setUnknownTlvs(@NonNull SparseArray<byte[]> unknownTlvs) {
+            requireNonNull(unknownTlvs, "unknownTlvs cannot be null");
+            mUnknownTlvs = deepCloneSparseArray(unknownTlvs);
+            return this;
+        }
+
+        /** Adds one more unknown TLV. @hide */
+        @VisibleForTesting
+        @NonNull
+        public Builder addUnknownTlv(int type, byte[] value) {
+            mUnknownTlvs.put(type, value);
+            return this;
+        }
+
+        /**
+         * Creates a new {@link ActiveOperationalDataset} object.
+         *
+         * @throws IllegalStateException if any of the fields isn't set or the total length exceeds
+         *     {@link #LENGTH_MAX_DATASET_TLVS} bytes
+         */
+        @NonNull
+        public ActiveOperationalDataset build() {
+            checkState(mActiveTimestamp != null, "Active Timestamp is missing");
+            checkState(mNetworkName != null, "Network Name is missing");
+            checkState(mExtendedPanId != null, "Extended PAN ID is missing");
+            checkState(mPanId != null, "PAN ID is missing");
+            checkState(mChannel != null, "Channel is missing");
+            checkState(mChannelPage != null, "Channel Page is missing");
+            checkState(mChannelMask.size() != 0, "Channel Mask is missing");
+            checkState(mPskc != null, "PSKc is missing");
+            checkState(mNetworkKey != null, "Network Key is missing");
+            checkState(mMeshLocalPrefix != null, "Mesh Local Prefix is missing");
+            checkState(mSecurityPolicy != null, "Security Policy is missing");
+
+            int length = getTotalDatasetLength();
+            if (length > LENGTH_MAX_DATASET_TLVS) {
+                throw new IllegalStateException(
+                        String.format(
+                                "Total dataset length exceeds max length %d (actual is %d)",
+                                LENGTH_MAX_DATASET_TLVS, length));
+            }
+
+            return new ActiveOperationalDataset(this);
+        }
+
+        private int getTotalDatasetLength() {
+            int length =
+                    2 * 9 // 9 fields with 1 byte of type and 1 byte of length
+                            + OperationalDatasetTimestamp.LENGTH_TIMESTAMP
+                            + mNetworkName.getBytes(UTF_8).length
+                            + LENGTH_EXTENDED_PAN_ID
+                            + LENGTH_PAN_ID
+                            + LENGTH_CHANNEL
+                            + LENGTH_PSKC
+                            + LENGTH_NETWORK_KEY
+                            + LENGTH_MESH_LOCAL_PREFIX_BITS / 8
+                            + mSecurityPolicy.toTlvValue().length;
+
+            for (int i = 0; i < mChannelMask.size(); i++) {
+                length += 2 + mChannelMask.valueAt(i).length;
+            }
+
+            // For the type and length bytes of the Channel Mask TLV because the masks are encoded
+            // as TLVs in TLV.
+            length += 2;
+
+            for (int i = 0; i < mUnknownTlvs.size(); i++) {
+                length += 2 + mUnknownTlvs.valueAt(i).length;
+            }
+
+            return length;
+        }
+    }
+
+    /**
+     * The Security Policy of Thread Operational Dataset which provides an administrator with a way
+     * to enable or disable certain security related behaviors.
+     */
+    public static final class SecurityPolicy {
+        /** The default Rotation Time in hours. */
+        public static final int DEFAULT_ROTATION_TIME_HOURS = 672;
+        /** The minimum length of Security Policy flags in bytes. */
+        public static final int LENGTH_MIN_SECURITY_POLICY_FLAGS = 1;
+        /** The length of Rotation Time TLV value in bytes. */
+        private static final int LENGTH_SECURITY_POLICY_ROTATION_TIME = 2;
+
+        private final int mRotationTimeHours;
+        private final byte[] mFlags;
+
+        /**
+         * Creates a new {@link SecurityPolicy} object.
+         *
+         * @param rotationTimeHours the value for Thread key rotation in hours. Must be in range of
+         *     0x1-0xffff.
+         * @param flags security policy flags with length of either 1 byte for Thread 1.1 or 2 bytes
+         *     for Thread 1.2 or higher.
+         * @throws IllegalArgumentException if {@code rotationTimeHours} is not in range of
+         *     0x1-0xffff or length of {@code flags} is smaller than {@link
+         *     #LENGTH_MIN_SECURITY_POLICY_FLAGS}.
+         */
+        public SecurityPolicy(
+                @IntRange(from = 0x1, to = 0xffff) int rotationTimeHours,
+                @NonNull @Size(min = LENGTH_MIN_SECURITY_POLICY_FLAGS) byte[] flags) {
+            requireNonNull(flags, "flags cannot be null");
+            checkArgument(
+                    rotationTimeHours >= 1 && rotationTimeHours <= 0xffff,
+                    "Rotation time exceeds allowed range (rotationTimeHours = %d, allowedRange ="
+                            + " [0x1, 0xffff])",
+                    rotationTimeHours);
+            checkArgument(
+                    flags.length >= LENGTH_MIN_SECURITY_POLICY_FLAGS,
+                    "Invalid security policy flags length (length = %d, minimumLength = %d)",
+                    flags.length,
+                    LENGTH_MIN_SECURITY_POLICY_FLAGS);
+            this.mRotationTimeHours = rotationTimeHours;
+            this.mFlags = flags.clone();
+        }
+
+        /**
+         * Creates a new {@link SecurityPolicy} object from the Security Policy TLV value.
+         *
+         * @hide
+         */
+        @VisibleForTesting
+        @NonNull
+        public static SecurityPolicy fromTlvValue(byte[] encodedSecurityPolicy) {
+            checkArgument(
+                    encodedSecurityPolicy.length
+                            >= LENGTH_SECURITY_POLICY_ROTATION_TIME
+                                    + LENGTH_MIN_SECURITY_POLICY_FLAGS,
+                    "Invalid Security Policy TLV length (length = %d, minimumLength = %d)",
+                    encodedSecurityPolicy.length,
+                    LENGTH_SECURITY_POLICY_ROTATION_TIME + LENGTH_MIN_SECURITY_POLICY_FLAGS);
+
+            return new SecurityPolicy(
+                    ((encodedSecurityPolicy[0] & 0xff) << 8) | (encodedSecurityPolicy[1] & 0xff),
+                    Arrays.copyOfRange(
+                            encodedSecurityPolicy,
+                            LENGTH_SECURITY_POLICY_ROTATION_TIME,
+                            encodedSecurityPolicy.length));
+        }
+
+        /**
+         * Converts this {@link SecurityPolicy} object to Security Policy TLV value.
+         *
+         * @hide
+         */
+        @VisibleForTesting
+        @NonNull
+        public byte[] toTlvValue() {
+            ByteArrayOutputStream result = new ByteArrayOutputStream();
+            result.write(mRotationTimeHours >> 8);
+            result.write(mRotationTimeHours);
+            result.write(mFlags, 0, mFlags.length);
+            return result.toByteArray();
+        }
+
+        /** Returns the Security Policy Rotation Time in hours. */
+        @IntRange(from = 0x1, to = 0xffff)
+        public int getRotationTimeHours() {
+            return mRotationTimeHours;
+        }
+
+        /** Returns 1 byte flags for Thread 1.1 or 2 bytes flags for Thread 1.2. */
+        @NonNull
+        @Size(min = LENGTH_MIN_SECURITY_POLICY_FLAGS)
+        public byte[] getFlags() {
+            return mFlags.clone();
+        }
+
+        @Override
+        public boolean equals(@Nullable Object other) {
+            if (this == other) {
+                return true;
+            } else if (!(other instanceof SecurityPolicy)) {
+                return false;
+            } else {
+                SecurityPolicy otherSecurityPolicy = (SecurityPolicy) other;
+                return mRotationTimeHours == otherSecurityPolicy.mRotationTimeHours
+                        && Arrays.equals(mFlags, otherSecurityPolicy.mFlags);
+            }
+        }
+
+        @Override
+        public int hashCode() {
+            return deepHashCode(mRotationTimeHours, mFlags);
+        }
+
+        @Override
+        public String toString() {
+            StringBuilder sb = new StringBuilder();
+            sb.append("{rotation=")
+                    .append(mRotationTimeHours)
+                    .append(", flags=")
+                    .append(dumpHexString(mFlags))
+                    .append("}");
+            return sb.toString();
+        }
+    }
+}
diff --git a/thread/framework/java/android/net/thread/OperationalDatasetTimestamp.java b/thread/framework/java/android/net/thread/OperationalDatasetTimestamp.java
new file mode 100644
index 0000000..bda9373
--- /dev/null
+++ b/thread/framework/java/android/net/thread/OperationalDatasetTimestamp.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright (C) 2023 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.net.thread;
+
+import static com.android.internal.util.Preconditions.checkArgument;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.FlaggedApi;
+import android.annotation.IntRange;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.SystemApi;
+
+import java.nio.ByteBuffer;
+import java.time.Instant;
+import java.util.Objects;
+
+/**
+ * The timestamp of Thread Operational Dataset.
+ *
+ * @see ActiveOperationalDataset
+ * @see PendingOperationalDataset
+ * @hide
+ */
+@FlaggedApi(ThreadNetworkFlags.FLAG_THREAD_ENABLED)
+@SystemApi
+public final class OperationalDatasetTimestamp {
+    /** @hide */
+    public static final int LENGTH_TIMESTAMP = Long.BYTES;
+
+    private static final long TICKS_UPPER_BOUND = 0x8000;
+
+    private final Instant mInstant;
+    private final boolean mIsAuthoritativeSource;
+
+    /**
+     * Creates a new {@link OperationalDatasetTimestamp} object from an {@link Instant}.
+     *
+     * <p>The {@code seconds} is set to {@code instant.getEpochSecond()}, {@code ticks} is set to
+     * {@link instant#getNano()} based on frequency of 32768 Hz, and {@code isAuthoritativeSource}
+     * is set to {@code true}.
+     *
+     * @throws IllegalArgumentException if {@code instant.getEpochSecond()} is larger than {@code
+     *     0xffffffffffffL}
+     */
+    @NonNull
+    public static OperationalDatasetTimestamp fromInstant(@NonNull Instant instant) {
+        return new OperationalDatasetTimestamp(instant, /* isAuthoritativeSource= */ true);
+    }
+
+    /** Converts this {@link OperationalDatasetTimestamp} object to an {@link Instant}. */
+    @NonNull
+    public Instant toInstant() {
+        return mInstant;
+    }
+
+    /**
+     * Creates a new {@link OperationalDatasetTimestamp} object from the OperationalDatasetTimestamp
+     * TLV value.
+     *
+     * @hide
+     */
+    @NonNull
+    public static OperationalDatasetTimestamp fromTlvValue(@NonNull byte[] encodedTimestamp) {
+        requireNonNull(encodedTimestamp, "encodedTimestamp cannot be null");
+        checkArgument(
+                encodedTimestamp.length == LENGTH_TIMESTAMP,
+                "Invalid Thread OperationalDatasetTimestamp length (length = %d,"
+                        + " expectedLength=%d)",
+                encodedTimestamp.length,
+                LENGTH_TIMESTAMP);
+        long longTimestamp = ByteBuffer.wrap(encodedTimestamp).getLong();
+        return new OperationalDatasetTimestamp(
+                (longTimestamp >> 16) & 0x0000ffffffffffffL,
+                (int) ((longTimestamp >> 1) & 0x7fffL),
+                (longTimestamp & 0x01) != 0);
+    }
+
+    /**
+     * Converts this {@link OperationalDatasetTimestamp} object to Thread TLV value.
+     *
+     * @hide
+     */
+    @NonNull
+    public byte[] toTlvValue() {
+        byte[] tlv = new byte[LENGTH_TIMESTAMP];
+        ByteBuffer buffer = ByteBuffer.wrap(tlv);
+        long encodedValue =
+                (mInstant.getEpochSecond() << 16)
+                        | ((mInstant.getNano() * TICKS_UPPER_BOUND / 1000000000L) << 1)
+                        | (mIsAuthoritativeSource ? 1 : 0);
+        buffer.putLong(encodedValue);
+        return tlv;
+    }
+
+    /**
+     * Creates a new {@link OperationalDatasetTimestamp} object.
+     *
+     * @param seconds the value encodes a Unix Time value. Must be in the range of
+     *     0x0-0xffffffffffffL
+     * @param ticks the value encodes the fractional Unix Time value in 32.768 kHz resolution. Must
+     *     be in the range of 0x0-0x7fff
+     * @param isAuthoritativeSource the flag indicates the time was obtained from an authoritative
+     *     source: either NTP (Network Time Protocol), GPS (Global Positioning System), cell
+     *     network, or other method
+     * @throws IllegalArgumentException if the {@code seconds} is not in range of
+     *     0x0-0xffffffffffffL or {@code ticks} is not in range of 0x0-0x7fff
+     */
+    public OperationalDatasetTimestamp(
+            @IntRange(from = 0x0, to = 0xffffffffffffL) long seconds,
+            @IntRange(from = 0x0, to = 0x7fff) int ticks,
+            boolean isAuthoritativeSource) {
+        this(makeInstant(seconds, ticks), isAuthoritativeSource);
+    }
+
+    private static Instant makeInstant(long seconds, int ticks) {
+        checkArgument(
+                seconds >= 0 && seconds <= 0xffffffffffffL,
+                "seconds exceeds allowed range (seconds = %d,"
+                        + " allowedRange = [0x0, 0xffffffffffffL])",
+                seconds);
+        checkArgument(
+                ticks >= 0 && ticks <= 0x7fff,
+                "ticks exceeds allowed ranged (ticks = %d, allowedRange" + " = [0x0, 0x7fff])",
+                ticks);
+        long nanos = Math.round((double) ticks * 1000000000L / TICKS_UPPER_BOUND);
+        return Instant.ofEpochSecond(seconds, nanos);
+    }
+
+    /**
+     * Creates new {@link OperationalDatasetTimestamp} object.
+     *
+     * @throws IllegalArgumentException if {@code instant.getEpochSecond()} is larger than {@code
+     *     0xffffffffffffL}
+     */
+    private OperationalDatasetTimestamp(@NonNull Instant instant, boolean isAuthoritativeSource) {
+        requireNonNull(instant, "instant cannot be null");
+        long seconds = instant.getEpochSecond();
+        checkArgument(
+                seconds >= 0 && seconds <= 0xffffffffffffL,
+                "instant seconds exceeds allowed range (seconds = %d, allowedRange = [0x0,"
+                        + " 0xffffffffffffL])",
+                seconds);
+        mInstant = instant;
+        mIsAuthoritativeSource = isAuthoritativeSource;
+    }
+
+    /**
+     * Returns the rounded ticks converted from the nano seconds.
+     *
+     * <p>Note that rhe return value can be as large as {@code TICKS_UPPER_BOUND}.
+     */
+    private static int getRoundedTicks(long nanos) {
+        return (int) Math.round((double) nanos * TICKS_UPPER_BOUND / 1000000000L);
+    }
+
+    /** Returns the seconds portion of the timestamp. */
+    public @IntRange(from = 0x0, to = 0xffffffffffffL) long getSeconds() {
+        return mInstant.getEpochSecond() + getRoundedTicks(mInstant.getNano()) / TICKS_UPPER_BOUND;
+    }
+
+    /** Returns the ticks portion of the timestamp. */
+    public @IntRange(from = 0x0, to = 0x7fff) int getTicks() {
+        // the rounded ticks can be 0x8000 if mInstant.getNano() >= 999984742
+        return (int) (getRoundedTicks(mInstant.getNano()) % TICKS_UPPER_BOUND);
+    }
+
+    /** Returns {@code true} if the timestamp comes from an authoritative source. */
+    public boolean isAuthoritativeSource() {
+        return mIsAuthoritativeSource;
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{seconds=")
+                .append(getSeconds())
+                .append(", ticks=")
+                .append(getTicks())
+                .append(", isAuthoritativeSource=")
+                .append(isAuthoritativeSource())
+                .append(", instant=")
+                .append(toInstant())
+                .append("}");
+        return sb.toString();
+    }
+
+    @Override
+    public boolean equals(@Nullable Object other) {
+        if (this == other) {
+            return true;
+        } else if (!(other instanceof OperationalDatasetTimestamp)) {
+            return false;
+        } else {
+            OperationalDatasetTimestamp otherTimestamp = (OperationalDatasetTimestamp) other;
+            return mInstant.equals(otherTimestamp.mInstant)
+                    && mIsAuthoritativeSource == otherTimestamp.mIsAuthoritativeSource;
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mInstant, mIsAuthoritativeSource);
+    }
+}
diff --git a/thread/framework/java/android/net/thread/PendingOperationalDataset.aidl b/thread/framework/java/android/net/thread/PendingOperationalDataset.aidl
new file mode 100644
index 0000000..e5bc05e
--- /dev/null
+++ b/thread/framework/java/android/net/thread/PendingOperationalDataset.aidl
@@ -0,0 +1,19 @@
+/*
+ * Copyright 2023 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.net.thread;
+
+parcelable PendingOperationalDataset;
diff --git a/thread/framework/java/android/net/thread/PendingOperationalDataset.java b/thread/framework/java/android/net/thread/PendingOperationalDataset.java
new file mode 100644
index 0000000..4762d7f
--- /dev/null
+++ b/thread/framework/java/android/net/thread/PendingOperationalDataset.java
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2023 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.net.thread;
+
+import static com.android.internal.util.Preconditions.checkArgument;
+
+import static java.util.Objects.requireNonNull;
+
+import android.annotation.FlaggedApi;
+import android.annotation.NonNull;
+import android.annotation.SystemApi;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.SparseArray;
+
+import java.io.ByteArrayOutputStream;
+import java.nio.ByteBuffer;
+import java.time.Duration;
+import java.util.Objects;
+
+/**
+ * Data interface for managing a Thread Pending Operational Dataset.
+ *
+ * <p>The Pending Operational Dataset represents an Operational Dataset which will become Active in
+ * a given delay. This is typically used to deploy new network parameters (e.g. Network Key or
+ * Channel) to all devices in the network.
+ *
+ * @hide
+ */
+@FlaggedApi(ThreadNetworkFlags.FLAG_THREAD_ENABLED)
+@SystemApi
+public final class PendingOperationalDataset implements Parcelable {
+    // Value defined in Thread spec 8.10.1.16
+    private static final int TYPE_PENDING_TIMESTAMP = 51;
+
+    // Values defined in Thread spec 8.10.1.17
+    private static final int TYPE_DELAY_TIMER = 52;
+    private static final int LENGTH_DELAY_TIMER_BYTES = 4;
+
+    @NonNull
+    public static final Creator<PendingOperationalDataset> CREATOR =
+            new Creator<>() {
+                @Override
+                public PendingOperationalDataset createFromParcel(Parcel in) {
+                    return PendingOperationalDataset.fromThreadTlvs(in.createByteArray());
+                }
+
+                @Override
+                public PendingOperationalDataset[] newArray(int size) {
+                    return new PendingOperationalDataset[size];
+                }
+            };
+
+    @NonNull private final ActiveOperationalDataset mActiveOpDataset;
+    @NonNull private final OperationalDatasetTimestamp mPendingTimestamp;
+    @NonNull private final Duration mDelayTimer;
+
+    /** Creates a new {@link PendingOperationalDataset} object. */
+    public PendingOperationalDataset(
+            @NonNull ActiveOperationalDataset activeOpDataset,
+            @NonNull OperationalDatasetTimestamp pendingTimestamp,
+            @NonNull Duration delayTimer) {
+        requireNonNull(activeOpDataset, "activeOpDataset cannot be null");
+        requireNonNull(pendingTimestamp, "pendingTimestamp cannot be null");
+        requireNonNull(delayTimer, "delayTimer cannot be null");
+        this.mActiveOpDataset = activeOpDataset;
+        this.mPendingTimestamp = pendingTimestamp;
+        this.mDelayTimer = delayTimer;
+    }
+
+    /**
+     * Creates a new {@link PendingOperationalDataset} object from a series of Thread TLVs.
+     *
+     * <p>{@code tlvs} can be obtained from the value of a Thread Pending Operational Dataset TLV
+     * (see the <a href="https://www.threadgroup.org/support#specifications">Thread
+     * specification</a> for the definition) or the return value of {@link #toThreadTlvs}.
+     *
+     * @throws IllegalArgumentException if {@code tlvs} is malformed or contains an invalid Thread
+     *     TLV
+     */
+    @NonNull
+    public static PendingOperationalDataset fromThreadTlvs(@NonNull byte[] tlvs) {
+        requireNonNull(tlvs, "tlvs cannot be null");
+
+        SparseArray<byte[]> newUnknownTlvs = new SparseArray<>();
+        OperationalDatasetTimestamp pendingTimestamp = null;
+        Duration delayTimer = null;
+        ActiveOperationalDataset activeDataset = ActiveOperationalDataset.fromThreadTlvs(tlvs);
+        SparseArray<byte[]> unknownTlvs = activeDataset.getUnknownTlvs();
+        for (int i = 0; i < unknownTlvs.size(); i++) {
+            int key = unknownTlvs.keyAt(i);
+            byte[] value = unknownTlvs.valueAt(i);
+            switch (key) {
+                case TYPE_PENDING_TIMESTAMP:
+                    pendingTimestamp = OperationalDatasetTimestamp.fromTlvValue(value);
+                    break;
+                case TYPE_DELAY_TIMER:
+                    checkArgument(
+                            value.length == LENGTH_DELAY_TIMER_BYTES,
+                            "Invalid delay timer (length = %d, expectedLength = %d)",
+                            value.length,
+                            LENGTH_DELAY_TIMER_BYTES);
+                    int millis = ByteBuffer.wrap(value).getInt();
+                    delayTimer = Duration.ofMillis(Integer.toUnsignedLong(millis));
+                    break;
+                default:
+                    newUnknownTlvs.put(key, value);
+                    break;
+            }
+        }
+
+        if (pendingTimestamp == null) {
+            throw new IllegalArgumentException("Pending Timestamp is missing");
+        }
+        if (delayTimer == null) {
+            throw new IllegalArgumentException("Delay Timer is missing");
+        }
+
+        activeDataset =
+                new ActiveOperationalDataset.Builder(activeDataset)
+                        .setUnknownTlvs(newUnknownTlvs)
+                        .build();
+        return new PendingOperationalDataset(activeDataset, pendingTimestamp, delayTimer);
+    }
+
+    /** Returns the Active Operational Dataset. */
+    @NonNull
+    public ActiveOperationalDataset getActiveOperationalDataset() {
+        return mActiveOpDataset;
+    }
+
+    /** Returns the Pending Timestamp. */
+    @NonNull
+    public OperationalDatasetTimestamp getPendingTimestamp() {
+        return mPendingTimestamp;
+    }
+
+    /** Returns the Delay Timer. */
+    @NonNull
+    public Duration getDelayTimer() {
+        return mDelayTimer;
+    }
+
+    /**
+     * Converts this {@link PendingOperationalDataset} object to a series of Thread TLVs.
+     *
+     * <p>See the <a href="https://www.threadgroup.org/support#specifications">Thread
+     * specification</a> for the definition of the Thread TLV format.
+     */
+    @NonNull
+    public byte[] toThreadTlvs() {
+        ByteArrayOutputStream dataset = new ByteArrayOutputStream();
+
+        byte[] activeDatasetBytes = mActiveOpDataset.toThreadTlvs();
+        dataset.write(activeDatasetBytes, 0, activeDatasetBytes.length);
+
+        dataset.write(TYPE_PENDING_TIMESTAMP);
+        byte[] pendingTimestampBytes = mPendingTimestamp.toTlvValue();
+        dataset.write(pendingTimestampBytes.length);
+        dataset.write(pendingTimestampBytes, 0, pendingTimestampBytes.length);
+
+        dataset.write(TYPE_DELAY_TIMER);
+        byte[] delayTimerBytes = new byte[LENGTH_DELAY_TIMER_BYTES];
+        ByteBuffer.wrap(delayTimerBytes).putInt((int) mDelayTimer.toMillis());
+        dataset.write(delayTimerBytes.length);
+        dataset.write(delayTimerBytes, 0, delayTimerBytes.length);
+
+        return dataset.toByteArray();
+    }
+
+    @Override
+    public boolean equals(Object other) {
+        if (this == other) {
+            return true;
+        } else if (!(other instanceof PendingOperationalDataset)) {
+            return false;
+        } else {
+            PendingOperationalDataset otherDataset = (PendingOperationalDataset) other;
+            return mActiveOpDataset.equals(otherDataset.mActiveOpDataset)
+                    && mPendingTimestamp.equals(otherDataset.mPendingTimestamp)
+                    && mDelayTimer.equals(otherDataset.mDelayTimer);
+        }
+    }
+
+    @Override
+    public int hashCode() {
+        return Objects.hash(mActiveOpDataset, mPendingTimestamp, mDelayTimer);
+    }
+
+    @Override
+    public String toString() {
+        StringBuilder sb = new StringBuilder();
+        sb.append("{activeDataset=")
+                .append(getActiveOperationalDataset())
+                .append(", pendingTimestamp=")
+                .append(getPendingTimestamp())
+                .append(", delayTimer=")
+                .append(getDelayTimer())
+                .append("}");
+        return sb.toString();
+    }
+
+    @Override
+    public int describeContents() {
+        return 0;
+    }
+
+    @Override
+    public void writeToParcel(@NonNull Parcel dest, int flags) {
+        dest.writeByteArray(toThreadTlvs());
+    }
+}
diff --git a/thread/tests/cts/Android.bp b/thread/tests/cts/Android.bp
index 278798e..ce770e0 100644
--- a/thread/tests/cts/Android.bp
+++ b/thread/tests/cts/Android.bp
@@ -37,6 +37,7 @@
         "androidx.test.ext.junit",
         "compatibility-device-util-axt",
         "ctstestrunner-axt",
+        "guava-android-testlib",
         "net-tests-utils",
         "truth",
     ],
diff --git a/thread/tests/cts/AndroidTest.xml b/thread/tests/cts/AndroidTest.xml
index 5ba605f..ffc181c 100644
--- a/thread/tests/cts/AndroidTest.xml
+++ b/thread/tests/cts/AndroidTest.xml
@@ -47,5 +47,7 @@
 
     <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
         <option name="package" value="android.net.thread.cts" />
+        <!-- Ignores tests introduced by guava-android-testlib -->
+        <option name="exclude-annotation" value="org.junit.Ignore"/>
     </test>
 </configuration>
diff --git a/thread/tests/cts/src/android/net/thread/cts/ActiveOperationalDatasetTest.java b/thread/tests/cts/src/android/net/thread/cts/ActiveOperationalDatasetTest.java
new file mode 100644
index 0000000..39df21b
--- /dev/null
+++ b/thread/tests/cts/src/android/net/thread/cts/ActiveOperationalDatasetTest.java
@@ -0,0 +1,737 @@
+/*
+ * Copyright (C) 2023 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.net.thread.cts;
+
+import static android.net.thread.ActiveOperationalDataset.CHANNEL_PAGE_24_GHZ;
+
+import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
+
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.net.IpPrefix;
+import android.net.thread.ActiveOperationalDataset;
+import android.net.thread.ActiveOperationalDataset.Builder;
+import android.net.thread.ActiveOperationalDataset.SecurityPolicy;
+import android.net.thread.OperationalDatasetTimestamp;
+import android.util.SparseArray;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.google.common.primitives.Bytes;
+import com.google.common.testing.EqualsTester;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.io.ByteArrayOutputStream;
+import java.util.Arrays;
+
+/** CTS tests for {@link ActiveOperationalDataset}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class ActiveOperationalDatasetTest {
+    private static final int TYPE_ACTIVE_TIMESTAMP = 14;
+    private static final int TYPE_CHANNEL = 0;
+    private static final int TYPE_CHANNEL_MASK = 53;
+    private static final int TYPE_EXTENDED_PAN_ID = 2;
+    private static final int TYPE_MESH_LOCAL_PREFIX = 7;
+    private static final int TYPE_NETWORK_KEY = 5;
+    private static final int TYPE_NETWORK_NAME = 3;
+    private static final int TYPE_PAN_ID = 1;
+    private static final int TYPE_PSKC = 4;
+    private static final int TYPE_SECURITY_POLICY = 12;
+
+    // A valid Thread Active Operational Dataset generated from OpenThread CLI "dataset new":
+    // Active Timestamp: 1
+    // Channel: 19
+    // Channel Mask: 0x07FFF800
+    // Ext PAN ID: ACC214689BC40BDF
+    // Mesh Local Prefix: fd64:db12:25f4:7e0b::/64
+    // Network Key: F26B3153760F519A63BAFDDFFC80D2AF
+    // Network Name: OpenThread-d9a0
+    // PAN ID: 0xD9A0
+    // PSKc: A245479C836D551B9CA557F7B9D351B4
+    // Security Policy: 672 onrcb
+    private static final byte[] VALID_DATASET =
+            base16().decode(
+                            "0E080000000000010000000300001335060004001FFFE002"
+                                    + "08ACC214689BC40BDF0708FD64DB1225F47E0B0510F26B31"
+                                    + "53760F519A63BAFDDFFC80D2AF030F4F70656E5468726561"
+                                    + "642D643961300102D9A00410A245479C836D551B9CA557F7"
+                                    + "B9D351B40C0402A0FFF8");
+
+    private static byte[] removeTlv(byte[] dataset, int type) {
+        ByteArrayOutputStream os = new ByteArrayOutputStream(dataset.length);
+        int i = 0;
+        while (i < dataset.length) {
+            int ty = dataset[i++] & 0xff;
+            byte length = dataset[i++];
+            if (ty != type) {
+                byte[] value = Arrays.copyOfRange(dataset, i, i + length);
+                os.write(ty);
+                os.write(length);
+                os.writeBytes(value);
+            }
+            i += length;
+        }
+        return os.toByteArray();
+    }
+
+    private static byte[] addTlv(byte[] dataset, String tlvHex) {
+        return Bytes.concat(dataset, base16().decode(tlvHex));
+    }
+
+    private static byte[] replaceTlv(byte[] dataset, int type, String newTlvHex) {
+        return addTlv(removeTlv(dataset, type), newTlvHex);
+    }
+
+    @Test
+    public void parcelable_parcelingIsLossLess() {
+        ActiveOperationalDataset dataset = ActiveOperationalDataset.fromThreadTlvs(VALID_DATASET);
+
+        assertParcelingIsLossless(dataset);
+    }
+
+    @Test
+    public void fromThreadTlvs_tooLongTlv_throwsIllegalArgument() {
+        byte[] invalidTlv = new byte[255];
+        invalidTlv[0] = (byte) 0xff;
+
+        // This is invalid because the TLV has max total length of 254 bytes and the value length
+        // can't exceeds 252 ( = 254 - 1 - 1)
+        invalidTlv[1] = (byte) 253;
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_invalidNetworkKeyTlv_throwsIllegalArgument() {
+        byte[] invalidTlv = replaceTlv(VALID_DATASET, TYPE_NETWORK_KEY, "05080000000000000000");
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_noNetworkKeyTlv_throwsIllegalArgument() {
+        byte[] invalidTlv = removeTlv(VALID_DATASET, TYPE_NETWORK_KEY);
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_invalidActiveTimestampTlv_throwsIllegalArgument() {
+        byte[] invalidTlv = replaceTlv(VALID_DATASET, TYPE_ACTIVE_TIMESTAMP, "0E0700000000010000");
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_noActiveTimestampTlv_throwsIllegalArgument() {
+        byte[] invalidTlv = removeTlv(VALID_DATASET, TYPE_ACTIVE_TIMESTAMP);
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_invalidNetworkNameTlv_emptyName_throwsIllegalArgument() {
+        byte[] invalidTlv = replaceTlv(VALID_DATASET, TYPE_NETWORK_NAME, "0300");
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_invalidNetworkNameTlv_tooLongName_throwsIllegalArgument() {
+        byte[] invalidTlv =
+                replaceTlv(
+                        VALID_DATASET, TYPE_NETWORK_NAME, "03114142434445464748494A4B4C4D4E4F5051");
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_noNetworkNameTlv_throwsIllegalArgument() {
+        byte[] invalidTlv = removeTlv(VALID_DATASET, TYPE_NETWORK_NAME);
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_invalidChannelTlv_channelMissing_throwsIllegalArgument() {
+        byte[] invalidTlv = replaceTlv(VALID_DATASET, TYPE_CHANNEL, "000100");
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_undefinedChannelPage_success() {
+        byte[] datasetTlv = replaceTlv(VALID_DATASET, TYPE_CHANNEL, "0003010020");
+
+        ActiveOperationalDataset dataset = ActiveOperationalDataset.fromThreadTlvs(datasetTlv);
+
+        assertThat(dataset.getChannelPage()).isEqualTo(0x01);
+        assertThat(dataset.getChannel()).isEqualTo(0x20);
+    }
+
+    @Test
+    public void fromThreadTlvs_invalid2P4GhzChannel_throwsIllegalArgument() {
+        byte[] invalidTlv1 = replaceTlv(VALID_DATASET, TYPE_CHANNEL, "000300000A");
+        byte[] invalidTlv2 = replaceTlv(VALID_DATASET, TYPE_CHANNEL, "000300001B");
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv1));
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv2));
+    }
+
+    @Test
+    public void fromThreadTlvs_valid2P4GhzChannelTlv_success() {
+        byte[] validTlv = replaceTlv(VALID_DATASET, TYPE_CHANNEL, "0003000010");
+
+        ActiveOperationalDataset dataset = ActiveOperationalDataset.fromThreadTlvs(validTlv);
+
+        assertThat(dataset.getChannel()).isEqualTo(16);
+    }
+
+    @Test
+    public void fromThreadTlvs_noChannelTlv_throwsIllegalArgument() {
+        byte[] invalidTlv = removeTlv(VALID_DATASET, TYPE_CHANNEL);
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_prematureEndOfChannelMaskEntry_throwsIllegalArgument() {
+        byte[] invalidTlv = replaceTlv(VALID_DATASET, TYPE_CHANNEL_MASK, "350100");
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_inconsistentChannelMaskLength_throwsIllegalArgument() {
+        byte[] invalidTlv = replaceTlv(VALID_DATASET, TYPE_CHANNEL_MASK, "3506000500010000");
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_unsupportedChannelMaskLength_success() {
+        ActiveOperationalDataset dataset =
+                ActiveOperationalDataset.fromThreadTlvs(
+                        replaceTlv(VALID_DATASET, TYPE_CHANNEL_MASK, "350700050001000000"));
+
+        SparseArray<byte[]> channelMask = dataset.getChannelMask();
+        assertThat(channelMask.size()).isEqualTo(1);
+        assertThat(channelMask.get(CHANNEL_PAGE_24_GHZ))
+                .isEqualTo(new byte[] {0x00, 0x01, 0x00, 0x00, 0x00});
+    }
+
+    @Test
+    public void fromThreadTlvs_noChannelMaskTlv_throwsIllegalArgument() {
+        byte[] invalidTlv = removeTlv(VALID_DATASET, TYPE_CHANNEL_MASK);
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_invalidPanIdTlv_throwsIllegalArgument() {
+        byte[] invalidTlv = replaceTlv(VALID_DATASET, TYPE_PAN_ID, "010101");
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_noPanIdTlv_throwsIllegalArgument() {
+        byte[] invalidTlv = removeTlv(VALID_DATASET, TYPE_PAN_ID);
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_invalidExtendedPanIdTlv_throwsIllegalArgument() {
+        byte[] invalidTlv = replaceTlv(VALID_DATASET, TYPE_EXTENDED_PAN_ID, "020700010203040506");
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_noExtendedPanIdTlv_throwsIllegalArgument() {
+        byte[] invalidTlv = removeTlv(VALID_DATASET, TYPE_EXTENDED_PAN_ID);
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_invalidPskcTlv_throwsIllegalArgument() {
+        byte[] invalidTlv =
+                replaceTlv(VALID_DATASET, TYPE_PSKC, "0411000102030405060708090A0B0C0D0E0F10");
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_noPskcTlv_throwsIllegalArgument() {
+        byte[] invalidTlv = removeTlv(VALID_DATASET, TYPE_PSKC);
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_invalidMeshLocalPrefixTlv_throwsIllegalArgument() {
+        byte[] invalidTlv =
+                replaceTlv(VALID_DATASET, TYPE_MESH_LOCAL_PREFIX, "0709FD0001020304050607");
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_noMeshLocalPrefixTlv_throwsIllegalArgument() {
+        byte[] invalidTlv = removeTlv(VALID_DATASET, TYPE_MESH_LOCAL_PREFIX);
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_tooShortSecurityPolicyTlv_throwsIllegalArgument() {
+        byte[] invalidTlv = replaceTlv(VALID_DATASET, TYPE_SECURITY_POLICY, "0C0101");
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_noSecurityPolicyTlv_throwsIllegalArgument() {
+        byte[] invalidTlv = removeTlv(VALID_DATASET, TYPE_SECURITY_POLICY);
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(invalidTlv));
+    }
+
+    @Test
+    public void fromThreadTlvs_lengthAndDataMissing_throwsIllegalArgument() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(new byte[] {(byte) 0x00}));
+    }
+
+    @Test
+    public void fromThreadTlvs_prematureEndOfData_throwsIllegalArgument() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> ActiveOperationalDataset.fromThreadTlvs(new byte[] {0x00, 0x03, 0x00, 0x00}));
+    }
+
+    @Test
+    public void fromThreadTlvs_validFullDataset_success() {
+        // A valid Thread active operational dataset:
+        // Active Timestamp: 1
+        // Channel: 19
+        // Channel Mask: 0x07FFF800
+        // Ext PAN ID: ACC214689BC40BDF
+        // Mesh Local Prefix: fd64:db12:25f4:7e0b::/64
+        // Network Key: F26B3153760F519A63BAFDDFFC80D2AF
+        // Network Name: OpenThread-d9a0
+        // PAN ID: 0xD9A0
+        // PSKc: A245479C836D551B9CA557F7B9D351B4
+        // Security Policy: 672 onrcb
+        byte[] validDatasetTlv =
+                base16().decode(
+                                "0E080000000000010000000300001335060004001FFFE002"
+                                        + "08ACC214689BC40BDF0708FD64DB1225F47E0B0510F26B31"
+                                        + "53760F519A63BAFDDFFC80D2AF030F4F70656E5468726561"
+                                        + "642D643961300102D9A00410A245479C836D551B9CA557F7"
+                                        + "B9D351B40C0402A0FFF8");
+
+        ActiveOperationalDataset dataset = ActiveOperationalDataset.fromThreadTlvs(validDatasetTlv);
+
+        assertThat(dataset.getNetworkKey())
+                .isEqualTo(base16().decode("F26B3153760F519A63BAFDDFFC80D2AF"));
+        assertThat(dataset.getPanId()).isEqualTo(0xd9a0);
+        assertThat(dataset.getExtendedPanId()).isEqualTo(base16().decode("ACC214689BC40BDF"));
+        assertThat(dataset.getChannel()).isEqualTo(19);
+        assertThat(dataset.getNetworkName()).isEqualTo("OpenThread-d9a0");
+        assertThat(dataset.getPskc())
+                .isEqualTo(base16().decode("A245479C836D551B9CA557F7B9D351B4"));
+        assertThat(dataset.getActiveTimestamp())
+                .isEqualTo(new OperationalDatasetTimestamp(1, 0, false));
+        SparseArray<byte[]> channelMask = dataset.getChannelMask();
+        assertThat(channelMask.size()).isEqualTo(1);
+        assertThat(channelMask.get(CHANNEL_PAGE_24_GHZ))
+                .isEqualTo(new byte[] {0x00, 0x1f, (byte) 0xff, (byte) 0xe0});
+        assertThat(dataset.getMeshLocalPrefix())
+                .isEqualTo(new IpPrefix("fd64:db12:25f4:7e0b::/64"));
+        assertThat(dataset.getSecurityPolicy())
+                .isEqualTo(new SecurityPolicy(672, new byte[] {(byte) 0xff, (byte) 0xf8}));
+    }
+
+    @Test
+    public void fromThreadTlvs_containsUnknownTlvs_unknownTlvsRetained() {
+        final byte[] datasetWithUnknownTlvs = addTlv(VALID_DATASET, "AA01FFBB020102");
+
+        ActiveOperationalDataset dataset =
+                ActiveOperationalDataset.fromThreadTlvs(datasetWithUnknownTlvs);
+
+        byte[] newDatasetTlvs = dataset.toThreadTlvs();
+        String newDatasetTlvsHex = base16().encode(newDatasetTlvs);
+        assertThat(newDatasetTlvs.length).isEqualTo(datasetWithUnknownTlvs.length);
+        assertThat(newDatasetTlvsHex).contains("AA01FF");
+        assertThat(newDatasetTlvsHex).contains("BB020102");
+    }
+
+    @Test
+    public void toThreadTlvs_conversionIsLossLess() {
+        ActiveOperationalDataset dataset1 = ActiveOperationalDataset.createRandomDataset();
+
+        ActiveOperationalDataset dataset2 =
+                ActiveOperationalDataset.fromThreadTlvs(dataset1.toThreadTlvs());
+
+        assertThat(dataset2).isEqualTo(dataset1);
+    }
+
+    @Test
+    public void builder_buildWithdefaultValues_throwsIllegalState() {
+        assertThrows(IllegalStateException.class, () -> new Builder().build());
+    }
+
+    @Test
+    public void builder_setValidNetworkKey_success() {
+        final byte[] networkKey =
+                new byte[] {
+                    0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c,
+                    0x0d, 0x0e, 0x0f
+                };
+
+        ActiveOperationalDataset dataset =
+                new Builder(ActiveOperationalDataset.createRandomDataset())
+                        .setNetworkKey(networkKey)
+                        .build();
+
+        assertThat(dataset.getNetworkKey()).isEqualTo(networkKey);
+    }
+
+    @Test
+    public void builder_setInvalidNetworkKey_throwsIllegalArgument() {
+        byte[] invalidNetworkKey = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
+        Builder builder = new Builder(ActiveOperationalDataset.createRandomDataset());
+
+        assertThrows(
+                IllegalArgumentException.class, () -> builder.setNetworkKey(invalidNetworkKey));
+    }
+
+    @Test
+    public void builder_setValidExtendedPanId_success() {
+        byte[] extendedPanId = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07};
+
+        ActiveOperationalDataset dataset =
+                new Builder(ActiveOperationalDataset.createRandomDataset())
+                        .setExtendedPanId(extendedPanId)
+                        .build();
+
+        assertThat(dataset.getExtendedPanId()).isEqualTo(extendedPanId);
+    }
+
+    @Test
+    public void builder_setInvalidExtendedPanId_throwsIllegalArgument() {
+        byte[] extendedPanId = new byte[] {0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06};
+        Builder builder = new Builder(ActiveOperationalDataset.createRandomDataset());
+
+        assertThrows(IllegalArgumentException.class, () -> builder.setExtendedPanId(extendedPanId));
+    }
+
+    @Test
+    public void builder_setValidPanId_success() {
+        ActiveOperationalDataset dataset =
+                new Builder(ActiveOperationalDataset.createRandomDataset())
+                        .setPanId(0xfffe)
+                        .build();
+
+        assertThat(dataset.getPanId()).isEqualTo(0xfffe);
+    }
+
+    @Test
+    public void builder_setInvalidPanId_throwsIllegalArgument() {
+        Builder builder = new Builder(ActiveOperationalDataset.createRandomDataset());
+
+        assertThrows(IllegalArgumentException.class, () -> builder.setPanId(0xffff));
+    }
+
+    @Test
+    public void builder_setInvalidChannel_throwsIllegalArgument() {
+        Builder builder = new Builder(ActiveOperationalDataset.createRandomDataset());
+
+        assertThrows(IllegalArgumentException.class, () -> builder.setChannel(0, 0));
+        assertThrows(IllegalArgumentException.class, () -> builder.setChannel(0, 27));
+    }
+
+    @Test
+    public void builder_setValid2P4GhzChannel_success() {
+        ActiveOperationalDataset dataset =
+                new Builder(ActiveOperationalDataset.createRandomDataset())
+                        .setChannel(CHANNEL_PAGE_24_GHZ, 16)
+                        .build();
+
+        assertThat(dataset.getChannel()).isEqualTo(16);
+        assertThat(dataset.getChannelPage()).isEqualTo(CHANNEL_PAGE_24_GHZ);
+    }
+
+    @Test
+    public void builder_setValidNetworkName_success() {
+        ActiveOperationalDataset dataset =
+                new Builder(ActiveOperationalDataset.createRandomDataset())
+                        .setNetworkName("ot-network")
+                        .build();
+
+        assertThat(dataset.getNetworkName()).isEqualTo("ot-network");
+    }
+
+    @Test
+    public void builder_setEmptyNetworkName_throwsIllegalArgument() {
+        Builder builder = new Builder(ActiveOperationalDataset.createRandomDataset());
+
+        assertThrows(IllegalArgumentException.class, () -> builder.setNetworkName(""));
+    }
+
+    @Test
+    public void builder_setTooLongNetworkName_throwsIllegalArgument() {
+        Builder builder = new Builder(ActiveOperationalDataset.createRandomDataset());
+
+        assertThrows(
+                IllegalArgumentException.class, () -> builder.setNetworkName("openthread-network"));
+    }
+
+    @Test
+    public void builder_setTooLongUtf8NetworkName_throwsIllegalArgument() {
+        Builder builder = new Builder(ActiveOperationalDataset.createRandomDataset());
+
+        // UTF-8 encoded length of "我的线程网络" is 18 bytes which exceeds the max length
+        assertThrows(IllegalArgumentException.class, () -> builder.setNetworkName("我的线程网络"));
+    }
+
+    @Test
+    public void builder_setValidUtf8NetworkName_success() {
+        ActiveOperationalDataset dataset =
+                new Builder(ActiveOperationalDataset.createRandomDataset())
+                        .setNetworkName("我的网络")
+                        .build();
+
+        assertThat(dataset.getNetworkName()).isEqualTo("我的网络");
+    }
+
+    @Test
+    public void builder_setValidPskc_success() {
+        byte[] pskc = base16().decode("A245479C836D551B9CA557F7B9D351B4");
+
+        ActiveOperationalDataset dataset =
+                new Builder(ActiveOperationalDataset.createRandomDataset()).setPskc(pskc).build();
+
+        assertThat(dataset.getPskc()).isEqualTo(pskc);
+    }
+
+    @Test
+    public void builder_setTooLongPskc_throwsIllegalArgument() {
+        byte[] tooLongPskc = base16().decode("A245479C836D551B9CA557F7B9D351B400");
+        Builder builder = new Builder(ActiveOperationalDataset.createRandomDataset());
+
+        assertThrows(IllegalArgumentException.class, () -> builder.setPskc(tooLongPskc));
+    }
+
+    @Test
+    public void builder_setValidChannelMask_success() {
+        Builder builder = new Builder(ActiveOperationalDataset.createRandomDataset());
+        SparseArray<byte[]> channelMask = new SparseArray<byte[]>(1);
+        channelMask.put(0, new byte[] {0x00, 0x00, 0x01, 0x00});
+
+        ActiveOperationalDataset dataset = builder.setChannelMask(channelMask).build();
+
+        SparseArray<byte[]> resultChannelMask = dataset.getChannelMask();
+        assertThat(resultChannelMask.size()).isEqualTo(1);
+        assertThat(resultChannelMask.get(0)).isEqualTo(new byte[] {0x00, 0x00, 0x01, 0x00});
+    }
+
+    @Test
+    public void builder_setEmptyChannelMask_throwsIllegalArgument() {
+        Builder builder = new Builder(ActiveOperationalDataset.createRandomDataset());
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> builder.setChannelMask(new SparseArray<byte[]>()));
+    }
+
+    @Test
+    public void builder_setValidActiveTimestamp_success() {
+        ActiveOperationalDataset dataset =
+                new Builder(ActiveOperationalDataset.createRandomDataset())
+                        .setActiveTimestamp(
+                                new OperationalDatasetTimestamp(
+                                        /* seconds= */ 1,
+                                        /* ticks= */ 0,
+                                        /* isAuthoritativeSource= */ true))
+                        .build();
+
+        assertThat(dataset.getActiveTimestamp().getSeconds()).isEqualTo(1);
+        assertThat(dataset.getActiveTimestamp().getTicks()).isEqualTo(0);
+        assertThat(dataset.getActiveTimestamp().isAuthoritativeSource()).isTrue();
+    }
+
+    @Test
+    public void builder_wrongMeshLocalPrefixLength_throwsIllegalArguments() {
+        Builder builder = new Builder(ActiveOperationalDataset.createRandomDataset());
+
+        // The Mesh-Local Prefix length must be 64 bits
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> builder.setMeshLocalPrefix(new IpPrefix("fd00::/32")));
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> builder.setMeshLocalPrefix(new IpPrefix("fd00::/96")));
+
+        // The Mesh-Local Prefix must start with 0xfd
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> builder.setMeshLocalPrefix(new IpPrefix("fc00::/64")));
+    }
+
+    @Test
+    public void builder_meshLocalPrefixNotStartWith0xfd_throwsIllegalArguments() {
+        Builder builder = new Builder(ActiveOperationalDataset.createRandomDataset());
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> builder.setMeshLocalPrefix(new IpPrefix("fc00::/64")));
+    }
+
+    @Test
+    public void builder_setValidMeshLocalPrefix_success() {
+        ActiveOperationalDataset dataset =
+                new Builder(ActiveOperationalDataset.createRandomDataset())
+                        .setMeshLocalPrefix(new IpPrefix("fd00::/64"))
+                        .build();
+
+        assertThat(dataset.getMeshLocalPrefix()).isEqualTo(new IpPrefix("fd00::/64"));
+    }
+
+    @Test
+    public void builder_setValid1P2SecurityPolicy_success() {
+        ActiveOperationalDataset dataset =
+                new Builder(ActiveOperationalDataset.createRandomDataset())
+                        .setSecurityPolicy(
+                                new SecurityPolicy(672, new byte[] {(byte) 0xff, (byte) 0xf8}))
+                        .build();
+
+        assertThat(dataset.getSecurityPolicy().getRotationTimeHours()).isEqualTo(672);
+        assertThat(dataset.getSecurityPolicy().getFlags())
+                .isEqualTo(new byte[] {(byte) 0xff, (byte) 0xf8});
+    }
+
+    @Test
+    public void builder_setValid1P1SecurityPolicy_success() {
+        ActiveOperationalDataset dataset =
+                new Builder(ActiveOperationalDataset.createRandomDataset())
+                        .setSecurityPolicy(new SecurityPolicy(672, new byte[] {(byte) 0xff}))
+                        .build();
+
+        assertThat(dataset.getSecurityPolicy().getRotationTimeHours()).isEqualTo(672);
+        assertThat(dataset.getSecurityPolicy().getFlags()).isEqualTo(new byte[] {(byte) 0xff});
+    }
+
+    @Test
+    public void securityPolicy_invalidRotationTime_throwsIllegalArguments() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> new SecurityPolicy(0, new byte[] {(byte) 0xff, (byte) 0xf8}));
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> new SecurityPolicy(0x1ffff, new byte[] {(byte) 0xff, (byte) 0xf8}));
+    }
+
+    @Test
+    public void securityPolicy_emptyFlags_throwsIllegalArguments() {
+        assertThrows(IllegalArgumentException.class, () -> new SecurityPolicy(672, new byte[] {}));
+    }
+
+    @Test
+    public void securityPolicy_tooLongFlags_success() {
+        SecurityPolicy securityPolicy =
+                new SecurityPolicy(672, new byte[] {0, 1, 2, 3, 4, 5, 6, 7});
+
+        assertThat(securityPolicy.getFlags()).isEqualTo(new byte[] {0, 1, 2, 3, 4, 5, 6, 7});
+    }
+
+    @Test
+    public void securityPolicy_equals() {
+        new EqualsTester()
+                .addEqualityGroup(
+                        new SecurityPolicy(672, new byte[] {(byte) 0xff, (byte) 0xf8}),
+                        new SecurityPolicy(672, new byte[] {(byte) 0xff, (byte) 0xf8}))
+                .addEqualityGroup(
+                        new SecurityPolicy(1, new byte[] {(byte) 0xff}),
+                        new SecurityPolicy(1, new byte[] {(byte) 0xff}))
+                .addEqualityGroup(
+                        new SecurityPolicy(1, new byte[] {(byte) 0xff, (byte) 0xf8}),
+                        new SecurityPolicy(1, new byte[] {(byte) 0xff, (byte) 0xf8}))
+                .testEquals();
+    }
+}
diff --git a/thread/tests/cts/src/android/net/thread/cts/OperationalDatasetTimestampTest.java b/thread/tests/cts/src/android/net/thread/cts/OperationalDatasetTimestampTest.java
new file mode 100644
index 0000000..9be3d56
--- /dev/null
+++ b/thread/tests/cts/src/android/net/thread/cts/OperationalDatasetTimestampTest.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2023 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.net.thread.cts;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.net.thread.OperationalDatasetTimestamp;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.google.common.testing.EqualsTester;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.time.Instant;
+
+/** Tests for {@link OperationalDatasetTimestamp}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class OperationalDatasetTimestampTest {
+    @Test
+    public void fromInstant_tooLargeInstant_throwsIllegalArgument() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () ->
+                        OperationalDatasetTimestamp.fromInstant(
+                                Instant.ofEpochSecond(0xffffffffffffL + 1L)));
+    }
+
+    @Test
+    public void fromInstant_ticksIsRounded() {
+        Instant instant = Instant.ofEpochSecond(100L);
+
+        // 32767.5 / 32768 * 1000000000 = 999984741.2109375 and given the `ticks` is rounded, so
+        // the `ticks` should be 32767 for 999984741 and 0 (carried over to seconds) for 999984742.
+        OperationalDatasetTimestamp timestampTicks32767 =
+                OperationalDatasetTimestamp.fromInstant(instant.plusNanos(999984741));
+        OperationalDatasetTimestamp timestampTicks0 =
+                OperationalDatasetTimestamp.fromInstant(instant.plusNanos(999984742));
+
+        assertThat(timestampTicks32767.getSeconds()).isEqualTo(100L);
+        assertThat(timestampTicks0.getSeconds()).isEqualTo(101L);
+        assertThat(timestampTicks32767.getTicks()).isEqualTo(32767);
+        assertThat(timestampTicks0.getTicks()).isEqualTo(0);
+        assertThat(timestampTicks32767.isAuthoritativeSource()).isTrue();
+        assertThat(timestampTicks0.isAuthoritativeSource()).isTrue();
+    }
+
+    @Test
+    public void toInstant_nanosIsRounded() {
+        // 32767 / 32768 * 1000000000 = 999969482.421875
+        assertThat(new OperationalDatasetTimestamp(100L, 32767, false).toInstant().getNano())
+                .isEqualTo(999969482);
+
+        // 32766 / 32768 * 1000000000 = 999938964.84375
+        assertThat(new OperationalDatasetTimestamp(100L, 32766, false).toInstant().getNano())
+                .isEqualTo(999938965);
+    }
+
+    @Test
+    public void toInstant_onlyAuthoritativeSourceDiscarded() {
+        OperationalDatasetTimestamp timestamp1 =
+                new OperationalDatasetTimestamp(100L, 0x7fff, false);
+
+        OperationalDatasetTimestamp timestamp2 =
+                OperationalDatasetTimestamp.fromInstant(timestamp1.toInstant());
+
+        assertThat(timestamp2.getSeconds()).isEqualTo(100L);
+        assertThat(timestamp2.getTicks()).isEqualTo(0x7fff);
+        assertThat(timestamp2.isAuthoritativeSource()).isTrue();
+    }
+
+    @Test
+    public void constructor_tooLargeSeconds_throwsIllegalArguments() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () ->
+                        new OperationalDatasetTimestamp(
+                                /* seconds= */ 0x0001112233445566L,
+                                /* ticks= */ 0,
+                                /* isAuthoritativeSource= */ true));
+    }
+
+    @Test
+    public void constructor_tooLargeTicks_throwsIllegalArguments() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () ->
+                        new OperationalDatasetTimestamp(
+                                /* seconds= */ 0x01L,
+                                /* ticks= */ 0x8000,
+                                /* isAuthoritativeSource= */ true));
+    }
+
+    @Test
+    public void equalityTests() {
+        new EqualsTester()
+                .addEqualityGroup(
+                        new OperationalDatasetTimestamp(100, 100, false),
+                        new OperationalDatasetTimestamp(100, 100, false))
+                .addEqualityGroup(
+                        new OperationalDatasetTimestamp(0, 0, false),
+                        new OperationalDatasetTimestamp(0, 0, false))
+                .addEqualityGroup(
+                        new OperationalDatasetTimestamp(0xffffffffffffL, 0x7fff, true),
+                        new OperationalDatasetTimestamp(0xffffffffffffL, 0x7fff, true))
+                .testEquals();
+    }
+}
diff --git a/thread/tests/cts/src/android/net/thread/cts/PendingOperationalDatasetTest.java b/thread/tests/cts/src/android/net/thread/cts/PendingOperationalDatasetTest.java
new file mode 100644
index 0000000..7a49957
--- /dev/null
+++ b/thread/tests/cts/src/android/net/thread/cts/PendingOperationalDatasetTest.java
@@ -0,0 +1,247 @@
+/*
+ * Copyright (C) 2023 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.net.thread.cts;
+
+import static com.android.testutils.ParcelUtils.assertParcelingIsLossless;
+
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import android.net.IpPrefix;
+import android.net.thread.ActiveOperationalDataset;
+import android.net.thread.OperationalDatasetTimestamp;
+import android.net.thread.PendingOperationalDataset;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.google.common.primitives.Bytes;
+import com.google.common.testing.EqualsTester;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.time.Duration;
+
+/** Tests for {@link PendingOperationalDataset}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class PendingOperationalDatasetTest {
+    private static final ActiveOperationalDataset DEFAULT_ACTIVE_DATASET =
+            ActiveOperationalDataset.createRandomDataset();
+
+    @Test
+    public void parcelable_parcelingIsLossLess() {
+        PendingOperationalDataset dataset =
+                new PendingOperationalDataset(
+                        DEFAULT_ACTIVE_DATASET,
+                        new OperationalDatasetTimestamp(31536000, 200, false),
+                        Duration.ofHours(100));
+
+        assertParcelingIsLossless(dataset);
+    }
+
+    @Test
+    public void equalityTests() {
+        ActiveOperationalDataset activeDataset1 = ActiveOperationalDataset.createRandomDataset();
+        ActiveOperationalDataset activeDataset2 = ActiveOperationalDataset.createRandomDataset();
+
+        new EqualsTester()
+                .addEqualityGroup(
+                        new PendingOperationalDataset(
+                                activeDataset1,
+                                new OperationalDatasetTimestamp(31536000, 100, false),
+                                Duration.ofMillis(0)),
+                        new PendingOperationalDataset(
+                                activeDataset1,
+                                new OperationalDatasetTimestamp(31536000, 100, false),
+                                Duration.ofMillis(0)))
+                .addEqualityGroup(
+                        new PendingOperationalDataset(
+                                activeDataset2,
+                                new OperationalDatasetTimestamp(31536000, 100, false),
+                                Duration.ofMillis(0)),
+                        new PendingOperationalDataset(
+                                activeDataset2,
+                                new OperationalDatasetTimestamp(31536000, 100, false),
+                                Duration.ofMillis(0)))
+                .addEqualityGroup(
+                        new PendingOperationalDataset(
+                                activeDataset2,
+                                new OperationalDatasetTimestamp(15768000, 0, false),
+                                Duration.ofMillis(0)),
+                        new PendingOperationalDataset(
+                                activeDataset2,
+                                new OperationalDatasetTimestamp(15768000, 0, false),
+                                Duration.ofMillis(0)))
+                .addEqualityGroup(
+                        new PendingOperationalDataset(
+                                activeDataset2,
+                                new OperationalDatasetTimestamp(15768000, 0, false),
+                                Duration.ofMillis(100)),
+                        new PendingOperationalDataset(
+                                activeDataset2,
+                                new OperationalDatasetTimestamp(15768000, 0, false),
+                                Duration.ofMillis(100)))
+                .testEquals();
+    }
+
+    @Test
+    public void constructor_correctValuesAreSet() {
+        PendingOperationalDataset dataset =
+                new PendingOperationalDataset(
+                        DEFAULT_ACTIVE_DATASET,
+                        new OperationalDatasetTimestamp(31536000, 200, false),
+                        Duration.ofHours(100));
+
+        assertThat(dataset.getActiveOperationalDataset()).isEqualTo(DEFAULT_ACTIVE_DATASET);
+        assertThat(dataset.getPendingTimestamp())
+                .isEqualTo(new OperationalDatasetTimestamp(31536000, 200, false));
+        assertThat(dataset.getDelayTimer()).isEqualTo(Duration.ofHours(100));
+    }
+
+    @Test
+    public void fromThreadTlvs_openthreadTlvs_success() {
+        // An example Pending Operational Dataset which is generated with OpenThread CLI:
+        // Pending Timestamp: 2
+        // Active Timestamp: 1
+        // Channel: 26
+        // Channel Mask: 0x07fff800
+        // Delay: 46354
+        // Ext PAN ID: a74182f4d3f4de41
+        // Mesh Local Prefix: fd46:c1b9:e159:5574::/64
+        // Network Key: ed916e454d96fd00184f10a6f5c9e1d3
+        // Network Name: OpenThread-bff8
+        // PAN ID: 0xbff8
+        // PSKc: 264f78414adc683191863d968f72d1b7
+        // Security Policy: 672 onrc
+        final byte[] OPENTHREAD_PENDING_DATASET_TLVS =
+                base16().lowerCase()
+                        .decode(
+                                "0e0800000000000100003308000000000002000034040000b51200030000"
+                                        + "1a35060004001fffe00208a74182f4d3f4de410708fd46c1b9"
+                                        + "e15955740510ed916e454d96fd00184f10a6f5c9e1d3030f4f"
+                                        + "70656e5468726561642d626666380102bff80410264f78414a"
+                                        + "dc683191863d968f72d1b70c0402a0f7f8");
+
+        PendingOperationalDataset pendingDataset =
+                PendingOperationalDataset.fromThreadTlvs(OPENTHREAD_PENDING_DATASET_TLVS);
+
+        ActiveOperationalDataset activeDataset = pendingDataset.getActiveOperationalDataset();
+        assertThat(pendingDataset.getPendingTimestamp().getSeconds()).isEqualTo(2L);
+        assertThat(activeDataset.getActiveTimestamp().getSeconds()).isEqualTo(1L);
+        assertThat(activeDataset.getChannel()).isEqualTo(26);
+        assertThat(activeDataset.getChannelMask().get(0))
+                .isEqualTo(new byte[] {0x00, 0x1f, (byte) 0xff, (byte) 0xe0});
+        assertThat(pendingDataset.getDelayTimer().toMillis()).isEqualTo(46354);
+        assertThat(activeDataset.getExtendedPanId())
+                .isEqualTo(base16().lowerCase().decode("a74182f4d3f4de41"));
+        assertThat(activeDataset.getMeshLocalPrefix())
+                .isEqualTo(new IpPrefix("fd46:c1b9:e159:5574::/64"));
+        assertThat(activeDataset.getNetworkKey())
+                .isEqualTo(base16().lowerCase().decode("ed916e454d96fd00184f10a6f5c9e1d3"));
+        assertThat(activeDataset.getNetworkName()).isEqualTo("OpenThread-bff8");
+        assertThat(activeDataset.getPanId()).isEqualTo(0xbff8);
+        assertThat(activeDataset.getPskc())
+                .isEqualTo(base16().lowerCase().decode("264f78414adc683191863d968f72d1b7"));
+        assertThat(activeDataset.getSecurityPolicy().getRotationTimeHours()).isEqualTo(672);
+        assertThat(activeDataset.getSecurityPolicy().getFlags())
+                .isEqualTo(new byte[] {(byte) 0xf7, (byte) 0xf8});
+    }
+
+    @Test
+    public void fromThreadTlvs_completePendingDatasetTlvs_success() {
+        // Type Length Value
+        // 0x33 0x08 0x0000000000010000 (Pending Timestamp TLV)
+        // 0x34 0x04 0x0000012C (Delay Timer TLV)
+        final byte[] pendingTimestampAndDelayTimerTlvs =
+                base16().decode("3308000000000001000034040000012C");
+        final byte[] pendingDatasetTlvs =
+                Bytes.concat(
+                        pendingTimestampAndDelayTimerTlvs, DEFAULT_ACTIVE_DATASET.toThreadTlvs());
+
+        PendingOperationalDataset dataset =
+                PendingOperationalDataset.fromThreadTlvs(pendingDatasetTlvs);
+
+        assertThat(dataset.getActiveOperationalDataset()).isEqualTo(DEFAULT_ACTIVE_DATASET);
+        assertThat(dataset.getPendingTimestamp())
+                .isEqualTo(new OperationalDatasetTimestamp(1, 0, false));
+        assertThat(dataset.getDelayTimer()).isEqualTo(Duration.ofMillis(300));
+    }
+
+    @Test
+    public void fromThreadTlvs_PendingTimestampTlvIsMissing_throwsIllegalArgument() {
+        // Type Length Value
+        // 0x34 0x04 0x00000064 (Delay Timer TLV)
+        final byte[] pendingTimestampAndDelayTimerTlvs = base16().decode("34040000012C");
+        final byte[] pendingDatasetTlvs =
+                Bytes.concat(
+                        pendingTimestampAndDelayTimerTlvs, DEFAULT_ACTIVE_DATASET.toThreadTlvs());
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> PendingOperationalDataset.fromThreadTlvs(pendingDatasetTlvs));
+    }
+
+    @Test
+    public void fromThreadTlvs_delayTimerTlvIsMissing_throwsIllegalArgument() {
+        // Type Length Value
+        // 0x33 0x08 0x0000000000010000 (Pending Timestamp TLV)
+        final byte[] pendingTimestampAndDelayTimerTlvs = base16().decode("33080000000000010000");
+        final byte[] pendingDatasetTlvs =
+                Bytes.concat(
+                        pendingTimestampAndDelayTimerTlvs, DEFAULT_ACTIVE_DATASET.toThreadTlvs());
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> PendingOperationalDataset.fromThreadTlvs(pendingDatasetTlvs));
+    }
+
+    @Test
+    public void fromThreadTlvs_activeDatasetTlvs_throwsIllegalArgument() {
+        final byte[] activeDatasetTlvs = DEFAULT_ACTIVE_DATASET.toThreadTlvs();
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> PendingOperationalDataset.fromThreadTlvs(activeDatasetTlvs));
+    }
+
+    @Test
+    public void fromThreadTlvs_malformedTlvs_throwsIllegalArgument() {
+        final byte[] invalidTlvs = new byte[] {0x00};
+
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> PendingOperationalDataset.fromThreadTlvs(invalidTlvs));
+    }
+
+    @Test
+    public void toThreadTlvs_conversionIsLossLess() {
+        PendingOperationalDataset dataset1 =
+                new PendingOperationalDataset(
+                        DEFAULT_ACTIVE_DATASET,
+                        new OperationalDatasetTimestamp(31536000, 200, false),
+                        Duration.ofHours(100));
+
+        PendingOperationalDataset dataset2 =
+                PendingOperationalDataset.fromThreadTlvs(dataset1.toThreadTlvs());
+
+        assertThat(dataset2).isEqualTo(dataset1);
+    }
+}
diff --git a/thread/tests/unit/Android.bp b/thread/tests/unit/Android.bp
new file mode 100644
index 0000000..1f16ad1
--- /dev/null
+++ b/thread/tests/unit/Android.bp
@@ -0,0 +1,50 @@
+//
+// Copyright (C) 2023 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 {
+    default_applicable_licenses: ["Android-Apache-2.0"],
+}
+
+android_test {
+    name: "ThreadNetworkUnitTests",
+    min_sdk_version: "33",
+    sdk_version: "module_current",
+    manifest: "AndroidManifest.xml",
+    test_config: "AndroidTest.xml",
+    srcs: [
+        "src/**/*.java",
+    ],
+    test_suites: [
+        "general-tests",
+    ],
+    static_libs: [
+        "androidx.test.ext.junit",
+        "compatibility-device-util-axt",
+        "ctstestrunner-axt",
+        "framework-connectivity-pre-jarjar",
+        "framework-connectivity-t-pre-jarjar",
+        "guava-android-testlib",
+        "net-tests-utils",
+        "truth-prebuilt",
+    ],
+    libs: [
+        "android.test.base",
+        "android.test.runner",
+    ],
+    // Test coverage system runs on different devices. Need to
+    // compile for all architectures.
+    compile_multilib: "both",
+}
diff --git a/thread/tests/unit/AndroidManifest.xml b/thread/tests/unit/AndroidManifest.xml
new file mode 100644
index 0000000..ace7c52
--- /dev/null
+++ b/thread/tests/unit/AndroidManifest.xml
@@ -0,0 +1,30 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2023 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.
+ -->
+
+<manifest
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    package="android.net.thread.unittests">
+
+    <application android:debuggable="true">
+        <uses-library android:name="android.test.runner" />
+    </application>
+
+    <instrumentation
+        android:name="androidx.test.runner.AndroidJUnitRunner"
+        android:targetPackage="android.net.thread.unittests"
+        android:label="Unit tests for android.net.thread" />
+</manifest>
diff --git a/thread/tests/unit/AndroidTest.xml b/thread/tests/unit/AndroidTest.xml
new file mode 100644
index 0000000..663ff74
--- /dev/null
+++ b/thread/tests/unit/AndroidTest.xml
@@ -0,0 +1,33 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+    Copyright (C) 2023 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.
+ -->
+
+<configuration description="Config for Thread network unit test cases">
+    <option name="test-tag" value="ThreadNetworkUnitTests" />
+    <option name="test-suite-tag" value="apct" />
+
+    <target_preparer class="com.android.tradefed.targetprep.suite.SuiteApkInstaller">
+        <option name="test-file-name" value="ThreadNetworkUnitTests.apk" />
+        <option name="check-min-sdk" value="true" />
+        <option name="cleanup-apks" value="true" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.AndroidJUnitTest" >
+        <option name="package" value="android.net.thread.unittests" />
+        <!-- Ignores tests introduced by guava-android-testlib -->
+        <option name="exclude-annotation" value="org.junit.Ignore"/>
+    </test>
+</configuration>
diff --git a/thread/tests/unit/src/android/net/thread/ActiveOperationalDatasetTest.java b/thread/tests/unit/src/android/net/thread/ActiveOperationalDatasetTest.java
new file mode 100644
index 0000000..78eb3d0
--- /dev/null
+++ b/thread/tests/unit/src/android/net/thread/ActiveOperationalDatasetTest.java
@@ -0,0 +1,202 @@
+/*
+ * Copyright (C) 2023 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.net.thread;
+
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.ArgumentMatchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.net.IpPrefix;
+import android.net.thread.ActiveOperationalDataset.Builder;
+import android.net.thread.ActiveOperationalDataset.SecurityPolicy;
+import android.util.SparseArray;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.google.common.primitives.Bytes;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.Mock;
+import org.mockito.MockitoAnnotations;
+
+import java.security.SecureRandom;
+import java.util.Random;
+
+/** Unit tests for {@link ActiveOperationalDataset}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class ActiveOperationalDatasetTest {
+    // A valid Thread Active Operational Dataset generated from OpenThread CLI "dataset new":
+    // Active Timestamp: 1
+    // Channel: 19
+    // Channel Mask: 0x07FFF800
+    // Ext PAN ID: ACC214689BC40BDF
+    // Mesh Local Prefix: fd64:db12:25f4:7e0b::/64
+    // Network Key: F26B3153760F519A63BAFDDFFC80D2AF
+    // Network Name: OpenThread-d9a0
+    // PAN ID: 0xD9A0
+    // PSKc: A245479C836D551B9CA557F7B9D351B4
+    // Security Policy: 672 onrcb
+    private static final byte[] VALID_DATASET =
+            base16().decode(
+                            "0E080000000000010000000300001335060004001FFFE002"
+                                    + "08ACC214689BC40BDF0708FD64DB1225F47E0B0510F26B31"
+                                    + "53760F519A63BAFDDFFC80D2AF030F4F70656E5468726561"
+                                    + "642D643961300102D9A00410A245479C836D551B9CA557F7"
+                                    + "B9D351B40C0402A0FFF8");
+
+    @Mock private Random mockRandom;
+    @Mock private SecureRandom mockSecureRandom;
+
+    @Before
+    public void setUp() {
+        MockitoAnnotations.initMocks(this);
+    }
+
+    private static byte[] addTlv(byte[] dataset, String tlvHex) {
+        return Bytes.concat(dataset, base16().decode(tlvHex));
+    }
+
+    @Test
+    public void fromThreadTlvs_containsUnknownTlvs_unknownTlvsRetained() {
+        byte[] datasetWithUnknownTlvs = addTlv(VALID_DATASET, "AA01FFBB020102");
+
+        ActiveOperationalDataset dataset1 =
+                ActiveOperationalDataset.fromThreadTlvs(datasetWithUnknownTlvs);
+        ActiveOperationalDataset dataset2 =
+                ActiveOperationalDataset.fromThreadTlvs(dataset1.toThreadTlvs());
+
+        SparseArray<byte[]> unknownTlvs = dataset2.getUnknownTlvs();
+        assertThat(unknownTlvs.size()).isEqualTo(2);
+        assertThat(unknownTlvs.get(0xAA)).isEqualTo(new byte[] {(byte) 0xFF});
+        assertThat(unknownTlvs.get(0xBB)).isEqualTo(new byte[] {0x01, 0x02});
+        assertThat(dataset2).isEqualTo(dataset1);
+    }
+
+    @Test
+    public void createRandomDataset_fieldsAreRandomized() {
+        // Always return the max bounded value
+        doAnswer(invocation -> (int) invocation.getArgument(0) - 1)
+                .when(mockRandom)
+                .nextInt(anyInt());
+        doAnswer(
+                        invocation -> {
+                            byte[] output = invocation.getArgument(0);
+                            for (int i = 0; i < output.length; ++i) {
+                                output[i] = (byte) (i + 10);
+                            }
+                            return null;
+                        })
+                .when(mockRandom)
+                .nextBytes(any(byte[].class));
+        doAnswer(
+                        invocation -> {
+                            byte[] output = invocation.getArgument(0);
+                            for (int i = 0; i < output.length; ++i) {
+                                output[i] = (byte) (i + 30);
+                            }
+                            return null;
+                        })
+                .when(mockSecureRandom)
+                .nextBytes(any(byte[].class));
+
+        ActiveOperationalDataset dataset =
+                ActiveOperationalDataset.createRandomDataset(mockRandom, mockSecureRandom);
+
+        assertThat(dataset.getActiveTimestamp())
+                .isEqualTo(new OperationalDatasetTimestamp(1, 0, false));
+        assertThat(dataset.getExtendedPanId())
+                .isEqualTo(new byte[] {10, 11, 12, 13, 14, 15, 16, 17});
+        assertThat(dataset.getMeshLocalPrefix())
+                .isEqualTo(new IpPrefix("fd0b:0c0d:0e0f:1011::/64"));
+        verify(mockRandom, times(2)).nextBytes(any(byte[].class));
+        assertThat(dataset.getPanId()).isEqualTo(0xfffe); // PAN ID <= 0xfffe
+        verify(mockRandom, times(1)).nextInt(eq(0xffff));
+        assertThat(dataset.getChannel()).isEqualTo(26);
+        verify(mockRandom, times(1)).nextInt(eq(16));
+        assertThat(dataset.getChannelPage()).isEqualTo(0);
+        assertThat(dataset.getChannelMask().size()).isEqualTo(1);
+        assertThat(dataset.getPskc())
+                .isEqualTo(
+                        new byte[] {
+                            30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45
+                        });
+        assertThat(dataset.getNetworkKey())
+                .isEqualTo(
+                        new byte[] {
+                            30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45
+                        });
+        verify(mockSecureRandom, times(2)).nextBytes(any(byte[].class));
+        assertThat(dataset.getSecurityPolicy())
+                .isEqualTo(new SecurityPolicy(672, new byte[] {(byte) 0xff, (byte) 0xf8}));
+    }
+
+    @Test
+    public void builder_buildWithTooLongTlvs_throwsIllegalState() {
+        Builder builder = new Builder(ActiveOperationalDataset.createRandomDataset());
+        for (int i = 0; i < 10; i++) {
+            builder.addUnknownTlv(i, new byte[20]);
+        }
+
+        assertThrows(IllegalStateException.class, () -> new Builder().build());
+    }
+
+    @Test
+    public void builder_setUnknownTlvs_success() {
+        ActiveOperationalDataset dataset1 = ActiveOperationalDataset.fromThreadTlvs(VALID_DATASET);
+        SparseArray<byte[]> unknownTlvs = new SparseArray<>(2);
+        unknownTlvs.put(0x33, new byte[] {1, 2, 3});
+        unknownTlvs.put(0x44, new byte[] {1, 2, 3, 4});
+
+        ActiveOperationalDataset dataset2 =
+                new ActiveOperationalDataset.Builder(dataset1).setUnknownTlvs(unknownTlvs).build();
+
+        assertThat(dataset1.getUnknownTlvs().size()).isEqualTo(0);
+        assertThat(dataset2.getUnknownTlvs().size()).isEqualTo(2);
+        assertThat(dataset2.getUnknownTlvs().get(0x33)).isEqualTo(new byte[] {1, 2, 3});
+        assertThat(dataset2.getUnknownTlvs().get(0x44)).isEqualTo(new byte[] {1, 2, 3, 4});
+    }
+
+    @Test
+    public void securityPolicy_fromTooShortTlvValue_throwsIllegalArgument() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> SecurityPolicy.fromTlvValue(new byte[] {0x01}));
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> SecurityPolicy.fromTlvValue(new byte[] {0x01, 0x02}));
+    }
+
+    @Test
+    public void securityPolicy_toTlvValue_conversionIsLossLess() {
+        SecurityPolicy policy1 = new SecurityPolicy(200, new byte[] {(byte) 0xFF, (byte) 0xF8});
+
+        SecurityPolicy policy2 = SecurityPolicy.fromTlvValue(policy1.toTlvValue());
+
+        assertThat(policy2).isEqualTo(policy1);
+    }
+}
diff --git a/thread/tests/unit/src/android/net/thread/OperationalDatasetTimestampTest.java b/thread/tests/unit/src/android/net/thread/OperationalDatasetTimestampTest.java
new file mode 100644
index 0000000..32063fc
--- /dev/null
+++ b/thread/tests/unit/src/android/net/thread/OperationalDatasetTimestampTest.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 2023 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.net.thread;
+
+import static com.google.common.io.BaseEncoding.base16;
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.junit.Assert.assertThrows;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/** Unit tests for {@link OperationalDatasetTimestamp}. */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public final class OperationalDatasetTimestampTest {
+    @Test
+    public void fromTlvValue_invalidTimestamp_throwsIllegalArguments() {
+        assertThrows(
+                IllegalArgumentException.class,
+                () -> OperationalDatasetTimestamp.fromTlvValue(new byte[7]));
+    }
+
+    @Test
+    public void fromTlvValue_goodValue_success() {
+        OperationalDatasetTimestamp timestamp =
+                OperationalDatasetTimestamp.fromTlvValue(base16().decode("FFEEDDCCBBAA9989"));
+
+        assertThat(timestamp.getSeconds()).isEqualTo(0xFFEEDDCCBBAAL);
+        // 0x9989 is 0x4CC4 << 1 + 1
+        assertThat(timestamp.getTicks()).isEqualTo(0x4CC4);
+        assertThat(timestamp.isAuthoritativeSource()).isTrue();
+    }
+
+    @Test
+    public void toTlvValue_conversionIsLossLess() {
+        OperationalDatasetTimestamp timestamp1 = new OperationalDatasetTimestamp(100L, 10, true);
+
+        OperationalDatasetTimestamp timestamp2 =
+                OperationalDatasetTimestamp.fromTlvValue(timestamp1.toTlvValue());
+
+        assertThat(timestamp2).isEqualTo(timestamp1);
+    }
+}
