Fix bug: NAS set to none will be reset to default after the second
reboot Bug: 185725135 Test: atest NotificationAssistantsTest, ManagedServicesTest, NotificationManagedServiceTest Change-Id: I63ba2a4e6fc1e9ac4612231af25c55fb66b0991e
This commit is contained in:
@@ -101,6 +101,7 @@ abstract public class ManagedServices {
|
||||
protected static final String ENABLED_SERVICES_SEPARATOR = ":";
|
||||
private static final String DB_VERSION_1 = "1";
|
||||
private static final String DB_VERSION_2 = "2";
|
||||
private static final String DB_VERSION_3 = "3";
|
||||
|
||||
|
||||
/**
|
||||
@@ -113,8 +114,9 @@ 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_CHANGED = "user_changed";
|
||||
|
||||
static final int DB_VERSION = 3;
|
||||
static final int DB_VERSION = 4;
|
||||
|
||||
static final int APPROVAL_BY_PACKAGE = 0;
|
||||
static final int APPROVAL_BY_COMPONENT = 1;
|
||||
@@ -160,6 +162,8 @@ abstract public class ManagedServices {
|
||||
@GuardedBy("mApproved")
|
||||
protected ArrayMap<Integer, ArraySet<String>> mUserSetServices = new ArrayMap<>();
|
||||
|
||||
protected ArrayMap<Integer, Boolean> mIsUserChanged = new ArrayMap<>();
|
||||
|
||||
// True if approved services are stored in xml, not settings.
|
||||
private boolean mUseXml;
|
||||
|
||||
@@ -338,6 +342,7 @@ abstract public class ManagedServices {
|
||||
for (int i = 0; i < N; i++) {
|
||||
final int userId = mApproved.keyAt(i);
|
||||
final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
|
||||
final Boolean userChanged = mIsUserChanged.get(userId);
|
||||
if (approvedByType != null) {
|
||||
final int M = approvedByType.size();
|
||||
for (int j = 0; j < M; j++) {
|
||||
@@ -345,16 +350,20 @@ abstract public class ManagedServices {
|
||||
final ArraySet<String> approved = approvedByType.valueAt(j);
|
||||
if (approvedByType != null && approvedByType.size() > 0) {
|
||||
pw.println(" " + String.join(ENABLED_SERVICES_SEPARATOR, approved)
|
||||
+ " (user: " + userId + " isPrimary: " + isPrimary + ")");
|
||||
+ " (user: " + userId + " isPrimary: " + isPrimary
|
||||
+ (userChanged == null ? "" : " isUserChanged: "
|
||||
+ userChanged) + ")");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pw.println(" Has user set:");
|
||||
Set<Integer> userIds = mUserSetServices.keySet();
|
||||
for (int userId : userIds) {
|
||||
pw.println(" userId=" + userId + " value=" + mUserSetServices.get(userId));
|
||||
if (mIsUserChanged.get(userId) == null) {
|
||||
pw.println(" userId=" + userId + " value="
|
||||
+ (mUserSetServices.get(userId)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -489,13 +498,14 @@ abstract public class ManagedServices {
|
||||
continue;
|
||||
}
|
||||
final ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.valueAt(i);
|
||||
final Boolean isUserChanged = mIsUserChanged.get(approvedUserId);
|
||||
if (approvedByType != null) {
|
||||
final int M = approvedByType.size();
|
||||
for (int j = 0; j < M; j++) {
|
||||
final boolean isPrimary = approvedByType.keyAt(j);
|
||||
final Set<String> approved = approvedByType.valueAt(j);
|
||||
final Set<String> userSet = mUserSetServices.get(approvedUserId);
|
||||
if (approved != null || userSet != null) {
|
||||
if (approved != null || userSet != null || isUserChanged != null) {
|
||||
String allowedItems = approved == null
|
||||
? ""
|
||||
: String.join(ENABLED_SERVICES_SEPARATOR, approved);
|
||||
@@ -503,7 +513,9 @@ abstract public class ManagedServices {
|
||||
out.attribute(null, ATT_APPROVED_LIST, allowedItems);
|
||||
out.attributeInt(null, ATT_USER_ID, approvedUserId);
|
||||
out.attributeBoolean(null, ATT_IS_PRIMARY, isPrimary);
|
||||
if (userSet != null) {
|
||||
if (isUserChanged != null) {
|
||||
out.attributeBoolean(null, ATT_USER_CHANGED, isUserChanged);
|
||||
} else if (userSet != null) {
|
||||
String userSetItems =
|
||||
String.join(ENABLED_SERVICES_SEPARATOR, userSet);
|
||||
out.attribute(null, ATT_USER_SET, userSetItems);
|
||||
@@ -618,12 +630,21 @@ abstract public class ManagedServices {
|
||||
? userId : parser.getAttributeInt(null, ATT_USER_ID, 0);
|
||||
final boolean isPrimary =
|
||||
parser.getAttributeBoolean(null, ATT_IS_PRIMARY, true);
|
||||
final String userSet = XmlUtils.readStringAttribute(parser, ATT_USER_SET);
|
||||
|
||||
final String isUserChanged = XmlUtils.readStringAttribute(parser,
|
||||
ATT_USER_CHANGED);
|
||||
String userSetComponent = null;
|
||||
if (isUserChanged == null) {
|
||||
userSetComponent = XmlUtils.readStringAttribute(parser, ATT_USER_SET);
|
||||
} else {
|
||||
mIsUserChanged.put(resolvedUserId, Boolean.valueOf(isUserChanged));
|
||||
}
|
||||
readExtraAttributes(tag, parser, resolvedUserId);
|
||||
if (allowedManagedServicePackages == null || allowedManagedServicePackages.test(
|
||||
getPackageName(approved), resolvedUserId, getRequiredPermission())) {
|
||||
getPackageName(approved), resolvedUserId, getRequiredPermission())
|
||||
|| approved.isEmpty()) {
|
||||
if (mUm.getUserInfo(resolvedUserId) != null) {
|
||||
addApprovedList(approved, resolvedUserId, isPrimary, userSet);
|
||||
addApprovedList(approved, resolvedUserId, isPrimary, userSetComponent);
|
||||
}
|
||||
mUseXml = true;
|
||||
}
|
||||
@@ -634,10 +655,16 @@ abstract public class ManagedServices {
|
||||
}
|
||||
boolean isOldVersion = TextUtils.isEmpty(version)
|
||||
|| DB_VERSION_1.equals(version)
|
||||
|| DB_VERSION_2.equals(version);
|
||||
|| DB_VERSION_2.equals(version)
|
||||
|| DB_VERSION_3.equals(version);
|
||||
boolean needUpgradeUserset = DB_VERSION_3.equals(version);
|
||||
if (isOldVersion) {
|
||||
upgradeDefaultsXmlVersion();
|
||||
}
|
||||
if (needUpgradeUserset) {
|
||||
upgradeUserSet();
|
||||
}
|
||||
|
||||
rebindServices(false, USER_ALL);
|
||||
}
|
||||
|
||||
@@ -666,6 +693,8 @@ abstract public class ManagedServices {
|
||||
}
|
||||
}
|
||||
|
||||
protected void upgradeUserSet() {};
|
||||
|
||||
/**
|
||||
* Read extra attributes in the {@link #TAG_MANAGED_SERVICES} tag.
|
||||
*/
|
||||
|
||||
@@ -106,7 +106,6 @@ import static android.service.notification.NotificationListenerService.TRIM_FULL
|
||||
import static android.service.notification.NotificationListenerService.TRIM_LIGHT;
|
||||
import static android.view.WindowManager.LayoutParams.TYPE_TOAST;
|
||||
|
||||
import static com.android.internal.util.CollectionUtils.emptyIfNull;
|
||||
import static com.android.internal.util.FrameworkStatsLog.DND_MODE_RULE;
|
||||
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_GROUP_PREFERENCES;
|
||||
import static com.android.internal.util.FrameworkStatsLog.PACKAGE_NOTIFICATION_CHANNEL_PREFERENCES;
|
||||
@@ -324,7 +323,6 @@ import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.Objects;
|
||||
import java.util.Set;
|
||||
@@ -9428,6 +9426,14 @@ public class NotificationManagerService extends SystemService {
|
||||
return mDefaultFromConfig;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void upgradeUserSet() {
|
||||
for (int userId: mApproved.keySet()) {
|
||||
ArraySet<String> userSetServices = mUserSetServices.get(userId);
|
||||
mIsUserChanged.put(userId, (userSetServices != null && userSetServices.size() > 0));
|
||||
}
|
||||
}
|
||||
|
||||
public NotificationAssistants(Context context, Object lock, UserProfiles up,
|
||||
IPackageManager pm) {
|
||||
super(context, lock, up, pm);
|
||||
@@ -9602,47 +9608,12 @@ public class NotificationManagerService extends SystemService {
|
||||
}
|
||||
|
||||
boolean hasUserSet(int userId) {
|
||||
synchronized (mLock) {
|
||||
ArraySet<String> userSetServices = mUserSetServices.get(userId);
|
||||
if (userSetServices == null) {
|
||||
// Legacy case - no data means user-set, unless no assistant is set
|
||||
return !mApproved.isEmpty();
|
||||
}
|
||||
Map<Boolean, ArraySet<String>> approvedByType = emptyIfNull(mApproved.get(userId));
|
||||
return userSetServices.containsAll(emptyIfNull(approvedByType.get(true)))
|
||||
&& userSetServices.containsAll(emptyIfNull(approvedByType.get(false)));
|
||||
}
|
||||
Boolean userSet = mIsUserChanged.get(userId);
|
||||
return (userSet != null && userSet);
|
||||
}
|
||||
|
||||
void setUserSet(int userId, boolean set) {
|
||||
synchronized (mLock) {
|
||||
ArraySet<String> userSetServices = new ArraySet<>();
|
||||
if (set) {
|
||||
ArrayMap<Boolean, ArraySet<String>> approvedByType = mApproved.get(userId);
|
||||
if (approvedByType != null) {
|
||||
for (int i = 0; i < approvedByType.size(); i++) {
|
||||
userSetServices.addAll(approvedByType.valueAt(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
mUserSetServices.put(userId, userSetServices);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void readExtraAttributes(String tag, TypedXmlPullParser parser, int userId)
|
||||
throws IOException {
|
||||
// TODO: this logic looks broken, since it's trying to convert a
|
||||
// list into a boolean; for now we preserve the old parsing behavior
|
||||
// to avoid a performance regression, but someone should investigate
|
||||
final String value = parser.getAttributeValue(null, ATT_USER_SET);
|
||||
final boolean userSet;
|
||||
if (TextUtils.isEmpty(value)) {
|
||||
userSet = false;
|
||||
} else {
|
||||
userSet = Boolean.parseBoolean(value);
|
||||
}
|
||||
setUserSet(userId, userSet);
|
||||
mIsUserChanged.put(userId, set);
|
||||
}
|
||||
|
||||
private void notifyCapabilitiesChanged(final ManagedServiceInfo info) {
|
||||
|
||||
@@ -100,6 +100,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
|
||||
private String mVersionString;
|
||||
private final Set<ComponentName> mDefaults = new ArraySet();
|
||||
private ManagedServices mService;
|
||||
private String mUserSetString;
|
||||
|
||||
private static final String SETTING = "setting";
|
||||
private static final String SECONDARY_SETTING = "secondary_setting";
|
||||
@@ -138,7 +139,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
|
||||
profileIds.add(13);
|
||||
when(mUserProfiles.getCurrentProfileIds()).thenReturn(profileIds);
|
||||
|
||||
mVersionString = "2";
|
||||
mVersionString = "4";
|
||||
mExpectedPrimary = new ArrayMap<>();
|
||||
mExpectedSecondary = new ArrayMap<>();
|
||||
mExpectedPrimaryPackages = new ArrayMap<>();
|
||||
@@ -1363,6 +1364,7 @@ public class ManagedServicesTest extends UiServiceTestCase {
|
||||
public void loadDefaults_noVersionWithDefaults() throws Exception {
|
||||
resetComponentsAndPackages();
|
||||
mDefaults.add(new ComponentName("default", "class"));
|
||||
mVersionString = null;
|
||||
loadXml(mService);
|
||||
assertEquals(mService.getDefaultComponents(), mDefaults);
|
||||
}
|
||||
@@ -1421,12 +1423,34 @@ public class ManagedServicesTest extends UiServiceTestCase {
|
||||
resetComponentsAndPackages();
|
||||
mDefaults.add(new ComponentName("default", "class"));
|
||||
mDefaultsString = "xml/class";
|
||||
mVersionString = String.valueOf(mService.DB_VERSION);
|
||||
loadXml(mService);
|
||||
assertEquals(mService.getDefaultComponents(),
|
||||
new ArraySet(Arrays.asList(new ComponentName("xml", "class"))));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void upgradeUserSet_versionThree() throws Exception {
|
||||
resetComponentsAndPackages();
|
||||
|
||||
List<UserInfo> users = new ArrayList<>();
|
||||
users.add(new UserInfo(98, "98", 0));
|
||||
users.add(new UserInfo(99, "99", 0));
|
||||
for (UserInfo user : users) {
|
||||
when(mUm.getUserInfo(eq(user.id))).thenReturn(user);
|
||||
}
|
||||
|
||||
mDefaultsString = "xml/class";
|
||||
mVersionString = "3";
|
||||
mUserSetString = "xml/class";
|
||||
loadXml(mService);
|
||||
|
||||
//Test services without overriding upgradeUserSet() remain unchanged
|
||||
assertEquals(new ArraySet(Arrays.asList(mUserSetString)),
|
||||
mService.mUserSetServices.get(98));
|
||||
assertEquals(new ArraySet(Arrays.asList(mUserSetString)),
|
||||
mService.mUserSetServices.get(99));
|
||||
assertEquals(new ArrayMap(), mService.mIsUserChanged);
|
||||
}
|
||||
|
||||
private void resetComponentsAndPackages() {
|
||||
ArrayMap<Integer, ArrayMap<Integer, String>> empty = new ArrayMap(1);
|
||||
@@ -1468,11 +1492,17 @@ public class ManagedServicesTest extends UiServiceTestCase {
|
||||
xml.append("<" + ManagedServices.TAG_MANAGED_SERVICES + " "
|
||||
+ ManagedServices.ATT_USER_ID + "=\"99\" "
|
||||
+ ManagedServices.ATT_IS_PRIMARY + "=\"true\" "
|
||||
+ ManagedServices.ATT_APPROVED_LIST + "=\"990\" />\n");
|
||||
+ ManagedServices.ATT_APPROVED_LIST + "=\"990\" "
|
||||
+ (mUserSetString != null ? ManagedServices.ATT_USER_SET + "=\""
|
||||
+ mUserSetString + "\" " : "")
|
||||
+ "/>\n");
|
||||
xml.append("<" + ManagedServices.TAG_MANAGED_SERVICES + " "
|
||||
+ ManagedServices.ATT_USER_ID + "=\"98\" "
|
||||
+ ManagedServices.ATT_IS_PRIMARY + "=\"false\" "
|
||||
+ ManagedServices.ATT_APPROVED_LIST + "=\"981\" />\n");
|
||||
+ ManagedServices.ATT_APPROVED_LIST + "=\"981\" "
|
||||
+ (mUserSetString != null ? ManagedServices.ATT_USER_SET + "=\""
|
||||
+ mUserSetString + "\" " : "")
|
||||
+ " />\n");
|
||||
xml.append("</" + xmlTag + ">");
|
||||
|
||||
return xml.toString();
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
package com.android.server.notification;
|
||||
|
||||
import static junit.framework.Assert.assertEquals;
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
import static junit.framework.Assert.assertTrue;
|
||||
|
||||
import static org.junit.Assert.assertNull;
|
||||
@@ -41,11 +42,13 @@ import android.content.pm.UserInfo;
|
||||
import android.os.UserHandle;
|
||||
import android.os.UserManager;
|
||||
import android.testing.TestableContext;
|
||||
import android.util.ArrayMap;
|
||||
import android.util.ArraySet;
|
||||
import android.util.IntArray;
|
||||
import android.util.TypedXmlPullParser;
|
||||
import android.util.Xml;
|
||||
|
||||
import com.android.internal.util.function.TriPredicate;
|
||||
import com.android.server.UiServiceTestCase;
|
||||
import com.android.server.notification.NotificationManagerService.NotificationAssistants;
|
||||
|
||||
@@ -131,6 +134,49 @@ public class NotificationAssistantsTest extends UiServiceTestCase {
|
||||
verify(mNm, times(mUm.getUsers().size())).setDefaultAssistantForUser(anyInt());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadXml_userDisabled() throws Exception {
|
||||
String xml = "<enabled_assistants version=\"4\" defaults=\"b/b\">"
|
||||
+ "<service_listing approved=\"\" user=\"0\" primary=\"true\""
|
||||
+ "user_changed=\"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);
|
||||
|
||||
ArrayMap<Boolean, ArraySet<String>> approved = mAssistants.mApproved.get(0);
|
||||
|
||||
// approved should not be null
|
||||
assertNotNull(approved);
|
||||
assertEquals(new ArraySet<>(), approved.get(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testReadXml_upgradeUserSet() throws Exception {
|
||||
String xml = "<enabled_assistants version=\"3\" defaults=\"b/b\">"
|
||||
+ "<service_listing approved=\"\" user=\"0\" primary=\"true\""
|
||||
+ "user_set_services=\"b/b\"/>"
|
||||
+ "</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(mAssistants.mIsUserChanged.get(0));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testXmlUpgradeExistingApprovedComponents() throws Exception {
|
||||
String xml = "<enabled_assistants version=\"2\" defaults=\"b\\b\">"
|
||||
|
||||
Reference in New Issue
Block a user