diff --git a/services/core/java/com/android/server/notification/ManagedServices.java b/services/core/java/com/android/server/notification/ManagedServices.java index ddaaa1eeff4a0..7d31287663d5e 100644 --- a/services/core/java/com/android/server/notification/ManagedServices.java +++ b/services/core/java/com/android/server/notification/ManagedServices.java @@ -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); + // 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 { - mIsUserChanged.put(resolvedUserId, Boolean.valueOf(isUserChanged)); + // 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(); } diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java index 987236c7c98c3..c337ccd67db8a 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/ManagedServicesTest.java @@ -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 { diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java index 054a401d41af4..4b93e35e673a8 100644 --- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java +++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationAssistantsTest.java @@ -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 = "" + + "" + + ""; + + final TypedXmlPullParser parser = Xml.newFastPullParser(); + parser.setInput(new BufferedInputStream( + new ByteArrayInputStream(xml.toString().getBytes())), null); + TriPredicate 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 = "" + + "" + + ""; + + final TypedXmlPullParser parser = Xml.newFastPullParser(); + parser.setInput(new BufferedInputStream( + new ByteArrayInputStream(xml.toString().getBytes())), null); + TriPredicate 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 = "" + + "" + + ""; + + final TypedXmlPullParser parser = Xml.newFastPullParser(); + parser.setInput(new BufferedInputStream( + new ByteArrayInputStream(xml.toString().getBytes())), null); + TriPredicate 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 = "" + + "" + + ""; + + final TypedXmlPullParser parser = Xml.newFastPullParser(); + parser.setInput(new BufferedInputStream( + new ByteArrayInputStream(xml.toString().getBytes())), null); + TriPredicate 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 = "" @@ -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(); + } + } }