[DO NOT MERGE] Fix associations serialization optimization bug

There mas a missing defensive copy causing false positive detections of
"associations not changed" case, leading to xml file not being updated once
at least one record is present

Bug: 30932767
Test: Associate at least two different devices and ensure the xml has both.
Change-Id: Ic0dc615dd2b847e137555c1084c616831b4dde83
This commit is contained in:
Eugene Susla
2017-03-28 20:27:28 -07:00
committed by Svetoslav Ganov
parent 75fb821029
commit 4df89bcb31
2 changed files with 37 additions and 9 deletions

View File

@@ -127,4 +127,29 @@ public class CollectionUtils {
}
return null;
}
/**
* Similar to {@link List#add}, but with support for list values of {@code null} and
* {@link Collections#emptyList}
*/
public static @NonNull <T> List<T> add(@Nullable List<T> cur, T val) {
if (cur == null || cur == Collections.emptyList()) {
cur = new ArrayList<>();
}
cur.add(val);
return cur;
}
/**
* Similar to {@link List#remove}, but with support for list values of {@code null} and
* {@link Collections#emptyList}
*/
public static @NonNull <T> List<T> remove(@Nullable List<T> cur, T val) {
if (cur == null || cur == Collections.emptyList()) {
return Collections.emptyList();
}
cur.remove(val);
return cur;
}
}

View File

@@ -17,6 +17,7 @@
package com.android.server.print;
import static com.android.internal.util.CollectionUtils.size;
import static com.android.internal.util.Preconditions.checkArgument;
import static com.android.internal.util.Preconditions.checkNotNull;
@@ -221,7 +222,7 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
throws RemoteException {
checkNotNull(deviceMacAddress);
checkCallerIsSystemOr(callingPackage);
updateAssociations(associations -> ArrayUtils.remove(associations,
updateAssociations(associations -> CollectionUtils.remove(associations,
new Association(getCallingUserId(), deviceMacAddress, callingPackage)));
}
@@ -350,22 +351,24 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
}
private void recordAssociation(String priviledgedPackage, String deviceAddress) {
updateAssociations((associations) -> ArrayUtils.add(associations,
updateAssociations(associations -> CollectionUtils.add(associations,
new Association(getCallingUserId(), deviceAddress, priviledgedPackage)));
}
private void updateAssociations(Function<ArrayList<Association>, List<Association>> update) {
private void updateAssociations(Function<List<Association>, List<Association>> update) {
updateAssociations(update, getCallingUserId());
}
private void updateAssociations(Function<ArrayList<Association>, List<Association>> update,
private void updateAssociations(Function<List<Association>, List<Association>> update,
int userId) {
final AtomicFile file = getStorageFileForUser(userId);
synchronized (file) {
final ArrayList<Association> old = readAllAssociations(userId);
final List<Association> associations = update.apply(old);
if (Objects.equals(old, associations)) return;
List<Association> associations = readAllAssociations(userId);
final ArrayList<Association> old = new ArrayList<>(associations);
associations = update.apply(associations);
if (size(old) == size(associations)) return;
List<Association> finalAssociations = associations;
file.write((out) -> {
XmlSerializer xml = Xml.newSerializer();
try {
@@ -374,8 +377,8 @@ public class CompanionDeviceManagerService extends SystemService implements Bind
xml.startDocument(null, true);
xml.startTag(null, XML_TAG_ASSOCIATIONS);
for (int i = 0; i < CollectionUtils.size(associations); i++) {
Association association = associations.get(i);
for (int i = 0; i < size(finalAssociations); i++) {
Association association = finalAssociations.get(i);
xml.startTag(null, XML_TAG_ASSOCIATION)
.attribute(null, XML_ATTR_PACKAGE, association.companionAppPackage)
.attribute(null, XML_ATTR_DEVICE, association.deviceAddress)