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

Commit 6ca9fe48 authored by Robin Lee's avatar Robin Lee
Browse files

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
parent 8592e887
Loading
Loading
Loading
Loading
+1 −77
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ import androidx.test.filters.SmallTest;

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 @@ public class DisplayWindowSettingsProviderTests extends WindowTestsBase {
        }
        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;
        }
    }
}
+91 −0
Original line number Diff line number Diff line
@@ -22,6 +22,16 @@ import android.view.DisplayInfo;
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 @@ public final class TestDisplayWindowSettingsProvider extends DisplayWindowSettin

    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 @@ public final class TestDisplayWindowSettingsProvider extends DisplayWindowSettin
    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;
        }
    }
}