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

Commit 3a00015f authored by James O'Leary's avatar James O'Leary
Browse files

Fix XML serialization of WallpaperColors

WallpaperColors is serialized to disk for use the next time the device
boots. WallpaperColors wasn't serializing the quantizer results, just
the 3 "main" colors, so it was unable to identify more than a few
colors, using the AOSP algorithm.

Bug: 186203148
Test: Reboot device without patch, verify only a couple colors are
available, or none if the AOSP algorithm for selecting main colors
differed sufficiently. Verify that with patch, rebooting the device
shows the same color options in the same order as it did at runtime.
Change-Id: I881a2cfe5b7dda5b7734ce3fda7275dc5544ce0c
parent 0245b5cb
Loading
Loading
Loading
Loading
+31 −3
Original line number Diff line number Diff line
@@ -129,7 +129,9 @@ import java.io.InputStream;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Consumer;
import java.util.function.Predicate;
@@ -3140,7 +3142,9 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
        }
    }

    private void writeWallpaperAttributes(TypedXmlSerializer out, String tag,

    @VisibleForTesting
    void writeWallpaperAttributes(TypedXmlSerializer out, String tag,
            WallpaperData wallpaper)
            throws IllegalArgumentException, IllegalStateException, IOException {
        if (DEBUG) {
@@ -3179,6 +3183,19 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
                    out.attributeInt(null, "colorValue" + i, wc.toArgb());
                }
            }

            int allColorsCount = wallpaper.primaryColors.getAllColors().size();
            out.attributeInt(null, "allColorsCount", allColorsCount);
            if (allColorsCount > 0) {
                int index = 0;
                for (Map.Entry<Integer, Integer> entry : wallpaper.primaryColors.getAllColors()
                        .entrySet()) {
                    out.attributeInt(null, "allColorsValue" + index, entry.getKey());
                    out.attributeInt(null, "allColorsPopulation" + index, entry.getValue());
                    index++;
                }
            }

            out.attributeInt(null, "colorHints", wallpaper.primaryColors.getColorHints());
        }

@@ -3410,7 +3427,8 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
        }
    }

    private void parseWallpaperAttributes(TypedXmlPullParser parser, WallpaperData wallpaper,
    @VisibleForTesting
    void parseWallpaperAttributes(TypedXmlPullParser parser, WallpaperData wallpaper,
            boolean keepDimensionHints) throws XmlPullParserException {
        final int id = parser.getAttributeInt(null, "id", -1);
        if (id != -1) {
@@ -3437,7 +3455,17 @@ public class WallpaperManagerService extends IWallpaperManager.Stub
        wpData.mPadding.right = getAttributeInt(parser, "paddingRight", 0);
        wpData.mPadding.bottom = getAttributeInt(parser, "paddingBottom", 0);
        int colorsCount = getAttributeInt(parser, "colorsCount", 0);
        if (colorsCount > 0) {
        int allColorsCount =  getAttributeInt(parser, "allColorsCount", 0);
        if (allColorsCount > 0) {
            Map<Integer, Integer> allColors = new HashMap<>(allColorsCount);
            for (int i = 0; i < allColorsCount; i++) {
                int colorInt = getAttributeInt(parser, "allColorsValue" + i, 0);
                int population = getAttributeInt(parser, "allColorsPopulation" + i, 0);
                allColors.put(colorInt, population);
            }
            int colorHints = getAttributeInt(parser, "colorHints", 0);
            wallpaper.primaryColors = new WallpaperColors(allColors, colorHints);
        } else if (colorsCount > 0) {
            Color primary = null, secondary = null, tertiary = null;
            for (int i = 0; i < colorsCount; i++) {
                Color color = Color.valueOf(getAttributeInt(parser, "colorValue" + i, 0));
+32 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.junit.Assume.assumeThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -57,6 +58,9 @@ import android.service.wallpaper.WallpaperService;
import android.testing.TestableContext;
import android.util.Log;
import android.util.SparseArray;
import android.util.TypedXmlPullParser;
import android.util.TypedXmlSerializer;
import android.util.Xml;
import android.view.Display;

import androidx.test.filters.FlakyTest;
@@ -82,9 +86,12 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.quality.Strictness;
import org.xmlpull.v1.XmlPullParserException;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;

/**
 * Tests for the {@link WallpaperManagerService} class.
@@ -355,6 +362,31 @@ public class WallpaperManagerServiceTests {
        verifyDisplayData();
    }

    @Test
    public void testXmlSerializationRoundtrip() {
        WallpaperData systemWallpaperData = mService.getCurrentWallpaperData(FLAG_SYSTEM, 0);
        try {
            TypedXmlSerializer serializer = Xml.newBinarySerializer();
            serializer.setOutput(new ByteArrayOutputStream(), StandardCharsets.UTF_8.name());
            serializer.startDocument(StandardCharsets.UTF_8.name(), true);
            mService.writeWallpaperAttributes(serializer, "wp", systemWallpaperData);
        } catch (IOException e) {
            fail("exception occurred while writing system wallpaper attributes");
        }

        WallpaperData shouldMatchSystem = new WallpaperData(systemWallpaperData.userId,
                systemWallpaperData.wallpaperFile.getParentFile(),
                systemWallpaperData.wallpaperFile.getAbsolutePath(),
                systemWallpaperData.cropFile.getAbsolutePath());
        try {
            TypedXmlPullParser parser = Xml.newBinaryPullParser();
            mService.parseWallpaperAttributes(parser, shouldMatchSystem, true);
        } catch (XmlPullParserException e) {
            fail("exception occurred while parsing wallpaper");
        }
        assertEquals(systemWallpaperData.primaryColors, shouldMatchSystem.primaryColors);
    }

    // Verify that after continue switch user from userId 0 to lastUserId, the wallpaper data for
    // non-current user must not bind to wallpaper service.
    private void verifyNoConnectionBeforeLastUser(int lastUserId) {