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

Commit 8a8c268f authored by Chloris Kuo's avatar Chloris Kuo
Browse files

Fix notification_policy user_set upgrade error

Bug: 203689334
Test: atest ManagedServicesTest, NotificationAssistantsTest
Test: manual test: upgrade from R(RP3A) to this and Q(QQ3A) to this with 1) User didn't change NAS, 2) User changed to new default NAS, 3) User changed to different NAS, 4) user changed to None
Change-Id: I64aa210b56d6350dea27b1b83c160ae147eb3a28
parent f4177fe7
Loading
Loading
Loading
Loading
+37 −7
Original line number Diff line number Diff line
@@ -114,9 +114,10 @@ abstract public class ManagedServices {
    static final String ATT_VERSION = "version";
    static final String ATT_DEFAULTS = "defaults";
    static final String ATT_USER_SET = "user_set_services";
    static final String ATT_USER_SET_OLD = "user_set";
    static final String ATT_USER_CHANGED = "user_changed";

    static final int DB_VERSION = 4;
    static final String DB_VERSION = "4";

    static final int APPROVAL_BY_PACKAGE = 0;
    static final int APPROVAL_BY_COMPONENT = 1;
@@ -482,7 +483,7 @@ abstract public class ManagedServices {
    public void writeXml(TypedXmlSerializer out, boolean forBackup, int userId) throws IOException {
        out.startTag(null, getConfig().xmlTag);

        out.attributeInt(null, ATT_VERSION, DB_VERSION);
        out.attributeInt(null, ATT_VERSION, Integer.parseInt(DB_VERSION));

        writeDefaults(out);

@@ -615,6 +616,7 @@ abstract public class ManagedServices {
        // read grants
        int type;
        String version = XmlUtils.readStringAttribute(parser, ATT_VERSION);
        boolean needUpgradeUserset = false;
        readDefaults(parser);
        while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
            String tag = parser.getName();
@@ -633,13 +635,42 @@ abstract public class ManagedServices {
                    final boolean isPrimary =
                            parser.getAttributeBoolean(null, ATT_IS_PRIMARY, true);

                    // Load three different userSet attributes from xml
                    // user_changed, not null if version == 4 and is NAS setting
                    final String isUserChanged = XmlUtils.readStringAttribute(parser,
                            ATT_USER_CHANGED);
                    String userSetComponent = null;
                    if (isUserChanged == null) {
                        userSetComponent = XmlUtils.readStringAttribute(parser, ATT_USER_SET);
                    } else {
                    // user_set, not null if version <= 3
                    final String isUserChanged_Old = XmlUtils.readStringAttribute(parser,
                            ATT_USER_SET_OLD);
                    // user_set_services, not null if version >= 3 and is non-NAS setting
                    String userSetComponent = XmlUtils.readStringAttribute(parser, ATT_USER_SET);

                    // since the same xml version may have different userSet attributes,
                    // we need to check both xml version and userSet values to know how to set
                    // the userSetComponent/mIsUserChanged to the correct value
                    if (DB_VERSION.equals(version)) {
                        // version 4, NAS contains user_changed and
                        // NLS/others contain user_set_services
                        if (isUserChanged == null) { //NLS
                            userSetComponent = TextUtils.emptyIfNull(userSetComponent);
                        } else { //NAS
                            mIsUserChanged.put(resolvedUserId, Boolean.valueOf(isUserChanged));
                            userSetComponent = Boolean.valueOf(isUserChanged) ? approved : "";
                        }
                    } else {
                        // version 3 may contain user_set (R) or user_set_services (S)
                        // version 2 or older contain user_set or nothing
                        needUpgradeUserset = true;
                        if (userSetComponent == null) { //contains user_set
                            if (isUserChanged_Old != null && Boolean.valueOf(isUserChanged_Old)) {
                                //user_set = true
                                userSetComponent = approved;
                                mIsUserChanged.put(resolvedUserId, true);
                                needUpgradeUserset = false;
                            } else {
                                userSetComponent = "";
                            }
                        }
                    }
                    readExtraAttributes(tag, parser, resolvedUserId);
                    if (allowedManagedServicePackages == null || allowedManagedServicePackages.test(
@@ -659,7 +690,6 @@ abstract public class ManagedServices {
                || DB_VERSION_1.equals(version)
                || DB_VERSION_2.equals(version)
                || DB_VERSION_3.equals(version);
        boolean needUpgradeUserset = DB_VERSION_3.equals(version);
        if (isOldVersion) {
            upgradeDefaultsXmlVersion();
        }
+15 −4
Original line number Diff line number Diff line
@@ -379,6 +379,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
    /** Test that restore correctly parses the user_set attribute. */
    @Test
    public void testReadXml_restoresUserSet() throws Exception {
        mVersionString = "4";
        for (int approvalLevel : new int[] {APPROVAL_BY_COMPONENT, APPROVAL_BY_PACKAGE}) {
            ManagedServices service =
                    new TestManagedServices(
@@ -1513,7 +1514,8 @@ public class ManagedServicesTest extends UiServiceTestCase {
        for (int userId : mExpectedPrimary.get(service.mApprovalLevel).keySet()) {
            String pkgOrCmp = mExpectedPrimary.get(service.mApprovalLevel).get(userId);
            xml.append(getXmlEntry(
                    pkgOrCmp, userId, true, !(pkgOrCmp.startsWith("non.user.set.package"))));
                    pkgOrCmp, userId, true,
                    !(pkgOrCmp.startsWith("non.user.set.package"))));
        }
        for (int userId : mExpectedSecondary.get(service.mApprovalLevel).keySet()) {
            xml.append(getXmlEntry(
@@ -1541,7 +1543,9 @@ public class ManagedServicesTest extends UiServiceTestCase {
    private TypedXmlPullParser getParserWithEntries(ManagedServices service, String... xmlEntries)
            throws Exception {
        final StringBuffer xml = new StringBuffer();
        xml.append("<" + service.getConfig().xmlTag + ">\n");
        xml.append("<" + service.getConfig().xmlTag
                + (mVersionString != null ? " version=\"" + mVersionString + "\" " : "")
                + ">\n");
        for (String xmlEntry : xmlEntries) {
            xml.append(xmlEntry);
        }
@@ -1726,12 +1730,19 @@ public class ManagedServicesTest extends UiServiceTestCase {
    }

    private String getXmlEntry(String approved, int userId, boolean isPrimary, boolean userSet) {
        String userSetString = "";
        if (mVersionString.equals("4")) {
            userSetString =
                    ManagedServices.ATT_USER_CHANGED + "=\"" + String.valueOf(userSet) + "\" ";
        } else if (mVersionString.equals("3")) {
            userSetString =
                    ManagedServices.ATT_USER_SET + "=\"" + (userSet ? approved : "") + "\" ";
        }
        return "<" + ManagedServices.TAG_MANAGED_SERVICES + " "
                + ManagedServices.ATT_USER_ID + "=\"" + userId +"\" "
                + ManagedServices.ATT_IS_PRIMARY + "=\"" + isPrimary +"\" "
                + ManagedServices.ATT_APPROVED_LIST + "=\"" + approved +"\" "
                + ManagedServices.ATT_USER_SET + "=\"" + (userSet ? approved : "") + "\" "
                + "/>\n";
                + userSetString + "/>\n";
    }

    class TestManagedServices extends ManagedServices {
+96 −1
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@
package com.android.server.notification;

import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertFalse;
import static junit.framework.Assert.assertNotNull;
import static junit.framework.Assert.assertTrue;

@@ -124,6 +125,7 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
        profileIds.add(12);
        when(mUserProfiles.getCurrentProfileIds()).thenReturn(profileIds);
        when(mNm.isNASMigrationDone(anyInt())).thenReturn(true);
        when(mNm.canUseManagedServices(any(), anyInt(), any())).thenReturn(true);
    }

    @Test
@@ -177,6 +179,92 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
        assertTrue(mAssistants.mIsUserChanged.get(0));
    }

    @Test
    public void testReadXml_upgradeUserSet_preS_VersionThree() throws Exception {
        String xml = "<enabled_assistants version=\"3\" defaults=\"b/b\">"
                + "<service_listing approved=\"\" user=\"0\" primary=\"true\""
                + "user_set=\"true\"/>"
                + "</enabled_assistants>";

        final TypedXmlPullParser parser = Xml.newFastPullParser();
        parser.setInput(new BufferedInputStream(
                new ByteArrayInputStream(xml.toString().getBytes())), null);
        TriPredicate<String, Integer, String> allowedManagedServicePackages =
                mNm::canUseManagedServices;

        parser.nextTag();
        mAssistants.readXml(parser, allowedManagedServicePackages, false, UserHandle.USER_ALL);

        verify(mAssistants, times(0)).upgradeUserSet();
        assertTrue(isUserSetServicesEmpty(mAssistants, 0));
        assertTrue(mAssistants.mIsUserChanged.get(0));
    }

    @Test
    public void testReadXml_upgradeUserSet_preS_VersionOne() throws Exception {
        String xml = "<enabled_assistants version=\"1\" defaults=\"b/b\">"
                + "<service_listing approved=\"\" user=\"0\" primary=\"true\""
                + "user_set=\"true\"/>"
                + "</enabled_assistants>";

        final TypedXmlPullParser parser = Xml.newFastPullParser();
        parser.setInput(new BufferedInputStream(
                new ByteArrayInputStream(xml.toString().getBytes())), null);
        TriPredicate<String, Integer, String> allowedManagedServicePackages =
                mNm::canUseManagedServices;

        parser.nextTag();
        mAssistants.readXml(parser, allowedManagedServicePackages, false, UserHandle.USER_ALL);

        verify(mAssistants, times(0)).upgradeUserSet();
        assertTrue(isUserSetServicesEmpty(mAssistants, 0));
        assertTrue(mAssistants.mIsUserChanged.get(0));
    }

    @Test
    public void testReadXml_upgradeUserSet_preS_noUserSet() throws Exception {
        String xml = "<enabled_assistants version=\"3\" defaults=\"b/b\">"
                + "<service_listing approved=\"b/b\" user=\"0\" primary=\"true\"/>"
                + "</enabled_assistants>";

        final TypedXmlPullParser parser = Xml.newFastPullParser();
        parser.setInput(new BufferedInputStream(
                new ByteArrayInputStream(xml.toString().getBytes())), null);
        TriPredicate<String, Integer, String> allowedManagedServicePackages =
                mNm::canUseManagedServices;

        parser.nextTag();
        mAssistants.readXml(parser, allowedManagedServicePackages, false, UserHandle.USER_ALL);

        verify(mAssistants, times(1)).upgradeUserSet();
        assertTrue(isUserSetServicesEmpty(mAssistants, 0));
        assertFalse(mAssistants.mIsUserChanged.get(0));
    }

    @Test
    public void testReadXml_upgradeUserSet_preS_noUserSet_diffDefault() throws Exception {
        String xml = "<enabled_assistants version=\"3\" defaults=\"a/a\">"
                + "<service_listing approved=\"b/b\" user=\"0\" primary=\"true\"/>"
                + "</enabled_assistants>";

        final TypedXmlPullParser parser = Xml.newFastPullParser();
        parser.setInput(new BufferedInputStream(
                new ByteArrayInputStream(xml.toString().getBytes())), null);
        TriPredicate<String, Integer, String> allowedManagedServicePackages =
                mNm::canUseManagedServices;

        parser.nextTag();
        mAssistants.readXml(parser, allowedManagedServicePackages, false, UserHandle.USER_ALL);

        verify(mAssistants, times(1)).upgradeUserSet();
        assertTrue(isUserSetServicesEmpty(mAssistants, 0));
        assertFalse(mAssistants.mIsUserChanged.get(0));
        assertEquals(new ArraySet<>(Arrays.asList(new ComponentName("a", "a"))),
                mAssistants.getDefaultComponents());
        assertEquals(Arrays.asList(new ComponentName("b", "b")),
                mAssistants.getAllowedComponents(0));
    }

    @Test
    public void testReadXml_multiApproved() throws Exception {
        String xml = "<enabled_assistants version=\"4\" defaults=\"b/b\">"
@@ -210,7 +298,7 @@ public class NotificationAssistantsTest extends UiServiceTestCase {

        verify(mNm, never()).setDefaultAssistantForUser(anyInt());
        verify(mAssistants, times(1)).addApprovedList(
                new ComponentName("b", "b").flattenToString(), 10, true, null);
                new ComponentName("b", "b").flattenToString(), 10, true, "");
    }

    @Test
@@ -380,4 +468,11 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
        verify(mNm, times(1)).setDefaultAssistantForUser(eq(mZero.id));
        assertEquals(new ArraySet<>(), mAssistants.getDefaultComponents());
    }

    // Helper function to hold mApproved lock, avoid GuardedBy lint errors
    private boolean isUserSetServicesEmpty(NotificationAssistants assistant, int userId) {
        synchronized (assistant.mApproved) {
            return assistant.mUserSetServices.get(userId).isEmpty();
        }
    }
}