Extract TestDisplayWindowSettingsProvider class

This is useful for injecting TestStorage instead of the real disk in
hermetic tests. It should be used in more tests than just the
DisplayWindowSettingsProvider unit tests.

Flag: EXEMPT mechanical refactor
Test: atest WmTests
Bug: 362981229
Change-Id: I1a7ec7d236cad3c6b583ac3ad16a75ac2a5bc0d1
diff --git a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
index 2f2b473..b7aa730 100644
--- a/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/DisplayWindowSettingsProviderTests.java
@@ -45,6 +45,7 @@
 
 import com.android.modules.utils.TypedXmlPullParser;
 import com.android.server.wm.DisplayWindowSettings.SettingsProvider.SettingsEntry;
+import com.android.server.wm.TestDisplayWindowSettingsProvider.TestStorage;
 
 import org.junit.After;
 import org.junit.Before;
@@ -516,81 +517,4 @@
         }
         return fullyDeleted;
     }
-
-    /** In-memory storage implementation. */
-    public class TestStorage implements DisplayWindowSettingsProvider.WritableSettingsStorage {
-        private InputStream mReadStream;
-        private ByteArrayOutputStream mWriteStream;
-
-        private boolean mWasSuccessful;
-
-        /**
-         * Returns input stream for reading. By default tries forward the output stream if previous
-         * write was successful.
-         * @see #closeRead()
-         */
-        @Override
-        public InputStream openRead() throws FileNotFoundException {
-            if (mReadStream == null && mWasSuccessful) {
-                mReadStream = new ByteArrayInputStream(mWriteStream.toByteArray());
-            }
-            if (mReadStream == null) {
-                throw new FileNotFoundException();
-            }
-            if (mReadStream.markSupported()) {
-                mReadStream.mark(Integer.MAX_VALUE);
-            }
-            return mReadStream;
-        }
-
-        /** Must be called after each {@link #openRead} to reset the position in the stream. */
-        void closeRead() throws IOException {
-            if (mReadStream == null) {
-                throw new FileNotFoundException();
-            }
-            if (mReadStream.markSupported()) {
-                mReadStream.reset();
-            }
-            mReadStream = null;
-        }
-
-        /**
-         * Creates new or resets existing output stream for write. Automatically closes previous
-         * read stream, since following reads should happen based on this new write.
-         */
-        @Override
-        public OutputStream startWrite() throws IOException {
-            if (mWriteStream == null) {
-                mWriteStream = new ByteArrayOutputStream();
-            } else {
-                mWriteStream.reset();
-            }
-            if (mReadStream != null) {
-                closeRead();
-            }
-            return mWriteStream;
-        }
-
-        @Override
-        public void finishWrite(OutputStream os, boolean success) {
-            mWasSuccessful = success;
-            try {
-                os.close();
-            } catch (IOException e) {
-                // This method can't throw IOException since the super implementation doesn't, so
-                // we just wrap it in a RuntimeException so we end up crashing the test all the
-                // same.
-                throw new RuntimeException(e);
-            }
-        }
-
-        /** Overrides the read stream of the injector. By default it uses current write stream. */
-        private void setReadStream(InputStream is) {
-            mReadStream = is;
-        }
-
-        private boolean wasWriteSuccessful() {
-            return mWasSuccessful;
-        }
-    }
 }
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestDisplayWindowSettingsProvider.java b/services/tests/wmtests/src/com/android/server/wm/TestDisplayWindowSettingsProvider.java
index e11df98..877f65c 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestDisplayWindowSettingsProvider.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestDisplayWindowSettingsProvider.java
@@ -22,6 +22,16 @@
 import java.util.HashMap;
 import java.util.Map;
 
+import com.android.server.wm.DisplayWindowSettingsProvider.WritableSettingsStorage;
+import com.android.server.wm.DisplayWindowSettings.SettingsProvider.SettingsEntry;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
 /**
  * In-memory DisplayWindowSettingsProvider used in tests. Ensures no settings are read from or
  * written to device-specific display settings files.
@@ -30,6 +40,10 @@
 
     private final Map<String, SettingsEntry> mOverrideSettingsMap = new HashMap<>();
 
+    public TestDisplayWindowSettingsProvider() {
+        super(new TestStorage(), new TestStorage());
+    }
+
     @Override
     @NonNull
     public SettingsEntry getSettings(@NonNull DisplayInfo info) {
@@ -76,4 +90,81 @@
     private static String getIdentifier(DisplayInfo displayInfo) {
         return displayInfo.uniqueId;
     }
+
+    /** In-memory storage implementation. */
+    public static class TestStorage implements WritableSettingsStorage {
+        private InputStream mReadStream;
+        private ByteArrayOutputStream mWriteStream;
+
+        private boolean mWasSuccessful;
+
+        /**
+         * Returns input stream for reading. By default tries forward the output stream if previous
+         * write was successful.
+         * @see #closeRead()
+         */
+        @Override
+        public InputStream openRead() throws FileNotFoundException {
+            if (mReadStream == null && mWasSuccessful) {
+                mReadStream = new ByteArrayInputStream(mWriteStream.toByteArray());
+            }
+            if (mReadStream == null) {
+                throw new FileNotFoundException();
+            }
+            if (mReadStream.markSupported()) {
+                mReadStream.mark(Integer.MAX_VALUE);
+            }
+            return mReadStream;
+        }
+
+        /** Must be called after each {@link #openRead} to reset the position in the stream. */
+        public void closeRead() throws IOException {
+            if (mReadStream == null) {
+                throw new FileNotFoundException();
+            }
+            if (mReadStream.markSupported()) {
+                mReadStream.reset();
+            }
+            mReadStream = null;
+        }
+
+        /**
+         * Creates new or resets existing output stream for write. Automatically closes previous
+         * read stream, since following reads should happen based on this new write.
+         */
+        @Override
+        public OutputStream startWrite() throws IOException {
+            if (mWriteStream == null) {
+                mWriteStream = new ByteArrayOutputStream();
+            } else {
+                mWriteStream.reset();
+            }
+            if (mReadStream != null) {
+                closeRead();
+            }
+            return mWriteStream;
+        }
+
+        @Override
+        public void finishWrite(OutputStream os, boolean success) {
+            mWasSuccessful = success;
+            try {
+                os.close();
+            } catch (IOException e) {
+                // This method can't throw IOException since the super implementation doesn't, so
+                // we just wrap it in a RuntimeException so we end up crashing the test all the
+                // same.
+                throw new RuntimeException(e);
+            }
+        }
+
+        /** Overrides the read stream of the injector. By default it uses current write stream. */
+        public void setReadStream(InputStream is) {
+            mReadStream = is;
+        }
+
+        public boolean wasWriteSuccessful() {
+            return mWasSuccessful;
+        }
+    }
 }