diff --git a/service-t/src/com/android/server/net/PersistentInt.java b/service-t/src/com/android/server/net/PersistentInt.java
new file mode 100644
index 0000000..c212b77
--- /dev/null
+++ b/service-t/src/com/android/server/net/PersistentInt.java
@@ -0,0 +1,108 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.net;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.util.AtomicFile;
+import android.util.SystemConfigFileCommitEventLogger;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+
+/**
+ * A simple integer backed by an on-disk {@link AtomicFile}. Not thread-safe.
+ */
+public class PersistentInt {
+    private final String mPath;
+    private final AtomicFile mFile;
+
+    /**
+     * Constructs a new {@code PersistentInt}. The counter is set to 0 if the file does not exist.
+     * Before returning, the constructor checks that the file is readable and writable. This
+     * indicates that in the future {@link #get} and {@link #set} are likely to succeed,
+     * though other events (data corruption, other code deleting the file, etc.) may cause these
+     * calls to fail in the future.
+     *
+     * @param path the path of the file to use.
+     * @param logger the logger
+     * @throws IOException the counter could not be read or written
+     */
+    public PersistentInt(@NonNull String path, @Nullable SystemConfigFileCommitEventLogger logger)
+            throws IOException {
+        mPath = path;
+        mFile = new AtomicFile(new File(path), logger);
+        checkReadWrite();
+    }
+
+    private void checkReadWrite() throws IOException {
+        int value;
+        try {
+            value = get();
+        } catch (FileNotFoundException e) {
+            // Counter does not exist. Attempt to initialize to 0.
+            // Note that we cannot tell here if the file does not exist or if opening it failed,
+            // because in Java both of those throw FileNotFoundException.
+            value = 0;
+        }
+        set(value);
+        get();
+        // No exceptions? Good.
+    }
+
+    /**
+      * Gets the current value.
+      *
+      * @return the current value of the counter.
+      * @throws IOException if reading the value failed.
+      */
+    public int get() throws IOException {
+        try (FileInputStream fin = mFile.openRead();
+             DataInputStream din = new DataInputStream(fin)) {
+            return din.readInt();
+        }
+    }
+
+    /**
+     * Sets the current value.
+     * @param value the value to set
+     * @throws IOException if writing the value failed.
+     */
+    public void set(int value) throws IOException {
+        FileOutputStream fout = null;
+        try {
+            fout = mFile.startWrite();
+            DataOutputStream dout = new DataOutputStream(fout);
+            dout.writeInt(value);
+            mFile.finishWrite(fout);
+        } catch (IOException e) {
+            if (fout != null) {
+                mFile.failWrite(fout);
+            }
+            throw e;
+        }
+    }
+
+    public String getPath() {
+        return mPath;
+    }
+}
diff --git a/tests/unit/java/com/android/server/net/PersistentIntTest.kt b/tests/unit/java/com/android/server/net/PersistentIntTest.kt
new file mode 100644
index 0000000..9509d38
--- /dev/null
+++ b/tests/unit/java/com/android/server/net/PersistentIntTest.kt
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.net
+
+import android.util.SystemConfigFileCommitEventLogger
+import com.android.testutils.assertThrows
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import java.io.File
+import java.io.IOException
+import java.nio.file.Files
+import java.nio.file.Path
+import java.nio.file.attribute.PosixFilePermission
+import java.nio.file.attribute.PosixFilePermission.OWNER_EXECUTE
+import java.nio.file.attribute.PosixFilePermission.OWNER_READ
+import java.nio.file.attribute.PosixFilePermission.OWNER_WRITE
+import java.util.Random
+import kotlin.test.assertEquals
+
+class PersistentIntTest {
+    val tempFilesCreated = mutableSetOf<Path>()
+    lateinit var tempDir: Path
+
+    @Before
+    fun setUp() {
+        tempDir = Files.createTempDirectory("tmp.PersistentIntTest.")
+    }
+
+    @After
+    fun tearDown() {
+        var permissions = setOf(OWNER_READ, OWNER_WRITE, OWNER_EXECUTE)
+        Files.setPosixFilePermissions(tempDir, permissions)
+
+        for (file in tempFilesCreated) {
+            Files.deleteIfExists(file)
+        }
+        Files.delete(tempDir)
+    }
+
+    @Test
+    fun testNormalReadWrite() {
+        // New, initialized to 0.
+        val pi = createPersistentInt()
+        assertEquals(0, pi.get())
+        pi.set(12345)
+        assertEquals(12345, pi.get())
+
+        // Existing.
+        val pi2 = createPersistentInt(pathOf(pi))
+        assertEquals(12345, pi2.get())
+    }
+
+    @Test
+    fun testReadOrWriteFailsInCreate() {
+        setWritable(tempDir, false)
+        assertThrows(IOException::class.java) {
+            createPersistentInt()
+        }
+    }
+
+    @Test
+    fun testReadOrWriteFailsAfterCreate() {
+        val pi = createPersistentInt()
+        pi.set(42)
+        assertEquals(42, pi.get())
+
+        val path = pathOf(pi)
+        setReadable(path, false)
+        assertThrows(IOException::class.java) { pi.get() }
+        pi.set(77)
+
+        setReadable(path, true)
+        setWritable(path, false)
+        setWritable(tempDir, false) // Writing creates a new file+renames, make this fail.
+        assertThrows(IOException::class.java) { pi.set(99) }
+        assertEquals(77, pi.get())
+    }
+
+    fun addOrRemovePermission(p: Path, permission: PosixFilePermission, add: Boolean) {
+        val permissions = Files.getPosixFilePermissions(p)
+        if (add) {
+            permissions.add(permission)
+        } else {
+            permissions.remove(permission)
+        }
+        Files.setPosixFilePermissions(p, permissions)
+    }
+
+    fun setReadable(p: Path, readable: Boolean) {
+        addOrRemovePermission(p, OWNER_READ, readable)
+    }
+
+    fun setWritable(p: Path, writable: Boolean) {
+        addOrRemovePermission(p, OWNER_WRITE, writable)
+    }
+
+    fun pathOf(pi: PersistentInt): Path {
+        return File(pi.path).toPath()
+    }
+
+    fun createPersistentInt(path: Path = randomTempPath()): PersistentInt {
+        tempFilesCreated.add(path)
+        return PersistentInt(path.toString(),
+                SystemConfigFileCommitEventLogger("PersistentIntTest"))
+    }
+
+    fun randomTempPath(): Path {
+        return tempDir.resolve(Integer.toHexString(Random().nextInt())).also {
+            tempFilesCreated.add(it)
+        }
+    }
+}
\ No newline at end of file
