Rename CDM's Association class AssociationInfo

First step in making the Association(Info) class a part of the public
API surface.

Bug: 194301022
Test: make
Change-Id: Ib1544ef7da471ae9fee1b9a9fabb01653454e277
This commit is contained in:
Sergey Nikolaienkov
2021-10-25 12:42:56 +02:00
parent a7e52432d5
commit c0ab6713d1
8 changed files with 75 additions and 75 deletions

View File

@@ -15,4 +15,4 @@
*/
package android.companion;
parcelable Association;
parcelable AssociationInfo;

View File

@@ -39,7 +39,7 @@ import java.util.Set;
* TODO(b/1979395): un-hide and rename to AssociationInfo when implementing public APIs that use
* this class.
*/
public final class Association implements Parcelable {
public final class AssociationInfo implements Parcelable {
/**
* A unique ID of this Association record.
* Disclosed to the clients (ie. companion applications) for referring to this record (eg. in
@@ -63,7 +63,7 @@ public final class Association implements Parcelable {
*
* @hide
*/
public Association(int associationId, @UserIdInt int userId, @NonNull String packageName,
public AssociationInfo(int associationId, @UserIdInt int userId, @NonNull String packageName,
@NonNull List<DeviceId> deviceIds, @Nullable String deviceProfile,
boolean managedByCompanionApp, boolean notifyOnDeviceNearby, long timeApprovedMs) {
if (associationId <= 0) {
@@ -178,8 +178,8 @@ public final class Association implements Parcelable {
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof Association)) return false;
final Association that = (Association) o;
if (!(o instanceof AssociationInfo)) return false;
final AssociationInfo that = (AssociationInfo) o;
return mAssociationId == that.mAssociationId
&& mUserId == that.mUserId
&& mManagedByCompanionApp == that.mManagedByCompanionApp
@@ -216,7 +216,7 @@ public final class Association implements Parcelable {
dest.writeLong(mTimeApprovedMs);
}
private Association(@NonNull Parcel in) {
private AssociationInfo(@NonNull Parcel in) {
mAssociationId = in.readInt();
mUserId = in.readInt();
@@ -230,16 +230,16 @@ public final class Association implements Parcelable {
mTimeApprovedMs = in.readLong();
}
public static final Parcelable.Creator<Association> CREATOR =
new Parcelable.Creator<Association>() {
public static final Parcelable.Creator<AssociationInfo> CREATOR =
new Parcelable.Creator<AssociationInfo>() {
@Override
public Association[] newArray(int size) {
return new Association[size];
public AssociationInfo[] newArray(int size) {
return new AssociationInfo[size];
}
@Override
public Association createFromParcel(@NonNull Parcel in) {
return new Association(in);
public AssociationInfo createFromParcel(@NonNull Parcel in) {
return new AssociationInfo(in);
}
};

View File

@@ -319,13 +319,13 @@ public final class CompanionDeviceManager {
}
/**
* Gets all package-device {@link Association}s for the current user.
* Gets all package-device {@link AssociationInfo}s for the current user.
*
* @return the associations list
* @hide
*/
@RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES)
public @NonNull List<Association> getAllAssociations() {
public @NonNull List<AssociationInfo> getAllAssociations() {
if (!checkFeaturePresent()) {
return Collections.emptyList();
}

View File

@@ -18,7 +18,7 @@ package android.companion;
import android.app.PendingIntent;
import android.companion.IFindDeviceCallback;
import android.companion.Association;
import android.companion.AssociationInfo;
import android.companion.AssociationRequest;
import android.content.ComponentName;
@@ -36,7 +36,7 @@ interface ICompanionDeviceManager {
in String callingPackage);
List<String> getAssociations(String callingPackage, int userId);
List<Association> getAssociationsForUser(int userId);
List<AssociationInfo> getAssociationsForUser(int userId);
void disassociate(String deviceMacAddress, String callingPackage);

View File

@@ -32,7 +32,7 @@ import static java.util.Collections.unmodifiableMap;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.companion.Association;
import android.companion.AssociationInfo;
import android.companion.AssociationRequest;
import android.companion.CompanionDeviceManager;
import android.companion.ICompanionDeviceDiscoveryService;
@@ -226,7 +226,7 @@ class AssociationRequestsProcessor {
// Throttle frequent associations
long now = System.currentTimeMillis();
Set<Association> recentAssociations = filter(
Set<AssociationInfo> recentAssociations = filter(
mService.getAllAssociations(userId, packageName),
a -> now - a.getTimeApprovedMs() < ASSOCIATE_WITHOUT_PROMPT_WINDOW_MS);

View File

@@ -56,7 +56,7 @@ import android.bluetooth.le.ScanCallback;
import android.bluetooth.le.ScanFilter;
import android.bluetooth.le.ScanResult;
import android.bluetooth.le.ScanSettings;
import android.companion.Association;
import android.companion.AssociationInfo;
import android.companion.AssociationRequest;
import android.companion.DeviceId;
import android.companion.DeviceNotAssociatedException;
@@ -182,7 +182,7 @@ public class CompanionDeviceManagerService extends SystemService {
/** Maps a {@link UserIdInt} to a set of associations for the user. */
@GuardedBy("mLock")
private final SparseArray<Set<Association>> mCachedAssociations = new SparseArray<>();
private final SparseArray<Set<AssociationInfo>> mCachedAssociations = new SparseArray<>();
/**
* A structure that consist of two nested maps, and effectively maps (userId + packageName) to
* a list of IDs that have been previously assigned to associations for that package.
@@ -270,7 +270,7 @@ public class CompanionDeviceManagerService extends SystemService {
@Override
public void onUserUnlocking(@NonNull TargetUser user) {
int userHandle = user.getUserIdentifier();
Set<Association> associations = getAllAssociations(userHandle);
Set<AssociationInfo> associations = getAllAssociations(userHandle);
if (associations == null || associations.isEmpty()) {
return;
}
@@ -293,11 +293,11 @@ public class CompanionDeviceManagerService extends SystemService {
}
try {
Set<Association> associations = getAllAssociations(userId);
Set<AssociationInfo> associations = getAllAssociations(userId);
if (associations == null) {
continue;
}
for (Association a : associations) {
for (AssociationInfo a : associations) {
try {
int uid = pm.getPackageUidAsUser(a.getPackageName(), userId);
exemptFromAutoRevoke(a.getPackageName(), uid);
@@ -355,7 +355,7 @@ public class CompanionDeviceManagerService extends SystemService {
}
@Override
public List<Association> getAssociationsForUser(int userId) {
public List<AssociationInfo> getAssociationsForUser(int userId) {
if (!callerCanManageCompanionDevices()) {
throw new SecurityException("Caller must hold "
+ android.Manifest.permission.MANAGE_COMPANION_DEVICES);
@@ -467,7 +467,7 @@ public class CompanionDeviceManagerService extends SystemService {
checkCallerIsSystemOr(packageName);
int userId = getCallingUserId();
Set<Association> deviceAssociations = filter(
Set<AssociationInfo> deviceAssociations = filter(
getAllAssociations(userId, packageName),
association -> deviceAddress.equals(association.getDeviceMacAddress()));
@@ -619,7 +619,7 @@ public class CompanionDeviceManagerService extends SystemService {
void createAssociationInternal(
int userId, String deviceMacAddress, String packageName, String deviceProfile) {
final Association association = new Association(
final AssociationInfo association = new AssociationInfo(
getNewAssociationIdForPackage(userId, packageName),
userId,
packageName,
@@ -648,7 +648,7 @@ public class CompanionDeviceManagerService extends SystemService {
// First: collect all IDs currently in use for this user's Associations.
final SparseBooleanArray usedIds = new SparseBooleanArray();
for (Association it : getAllAssociations(userId)) {
for (AssociationInfo it : getAllAssociations(userId)) {
usedIds.put(it.getAssociationId(), true);
}
@@ -698,7 +698,7 @@ public class CompanionDeviceManagerService extends SystemService {
}
}
void onAssociationPreRemove(Association association) {
void onAssociationPreRemove(AssociationInfo association) {
if (association.isNotifyOnDeviceNearby()) {
mCompanionDevicePresenceController.unbindDevicePresenceListener(
association.getPackageName(), association.getUserId());
@@ -706,7 +706,7 @@ public class CompanionDeviceManagerService extends SystemService {
String deviceProfile = association.getDeviceProfile();
if (deviceProfile != null) {
Association otherAssociationWithDeviceProfile = find(
AssociationInfo otherAssociationWithDeviceProfile = find(
getAllAssociations(association.getUserId()),
a -> !a.equals(association) && deviceProfile.equals(a.getDeviceProfile()));
if (otherAssociationWithDeviceProfile != null) {
@@ -737,7 +737,7 @@ public class CompanionDeviceManagerService extends SystemService {
}
}
private void updateSpecialAccessPermissionForAssociatedPackage(Association association) {
private void updateSpecialAccessPermissionForAssociatedPackage(AssociationInfo association) {
PackageInfo packageInfo = getPackageInfo(
association.getPackageName(),
association.getUserId());
@@ -751,7 +751,7 @@ public class CompanionDeviceManagerService extends SystemService {
}
private void updateSpecialAccessPermissionAsSystem(
Association association, PackageInfo packageInfo) {
AssociationInfo association, PackageInfo packageInfo) {
if (containsEither(packageInfo.requestedPermissions,
android.Manifest.permission.RUN_IN_BACKGROUND,
android.Manifest.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND)) {
@@ -816,20 +816,20 @@ public class CompanionDeviceManagerService extends SystemService {
}, getContext(), packageName, userId).recycleOnUse());
}
private void recordAssociation(Association association, int userId) {
private void recordAssociation(AssociationInfo association, int userId) {
Slog.i(LOG_TAG, "recordAssociation(" + association + ")");
updateAssociations(associations -> add(associations, association), userId);
}
private void updateAssociations(Function<Set<Association>, Set<Association>> update,
private void updateAssociations(Function<Set<AssociationInfo>, Set<AssociationInfo>> update,
int userId) {
synchronized (mLock) {
if (DEBUG) Slog.d(LOG_TAG, "Updating Associations set...");
final Set<Association> prevAssociations = getAllAssociations(userId);
final Set<AssociationInfo> prevAssociations = getAllAssociations(userId);
if (DEBUG) Slog.d(LOG_TAG, " > Before : " + prevAssociations + "...");
final Set<Association> updatedAssociations = update.apply(
final Set<AssociationInfo> updatedAssociations = update.apply(
new ArraySet<>(prevAssociations));
if (DEBUG) Slog.d(LOG_TAG, " > After: " + updatedAssociations);
@@ -846,9 +846,9 @@ public class CompanionDeviceManagerService extends SystemService {
}
}
private void updateAtm(int userId, Set<Association> associations) {
private void updateAtm(int userId, Set<AssociationInfo> associations) {
final Set<Integer> companionAppUids = new ArraySet<>();
for (Association association : associations) {
for (AssociationInfo association : associations) {
final int uid = mPackageManagerInternal.getPackageUid(association.getPackageName(),
0, userId);
if (uid >= 0) {
@@ -864,7 +864,7 @@ public class CompanionDeviceManagerService extends SystemService {
}
}
@NonNull Set<Association> getAllAssociations(int userId) {
@NonNull Set<AssociationInfo> getAllAssociations(int userId) {
synchronized (mLock) {
readPersistedStateForUserIfNeededLocked(userId);
// This returns non-null, because the readAssociationsInfoForUserIfNeededLocked() method
@@ -879,7 +879,7 @@ public class CompanionDeviceManagerService extends SystemService {
Slog.i(LOG_TAG, "Reading state for user " + userId + " from the disk");
final Set<Association> associations = new ArraySet<>();
final Set<AssociationInfo> associations = new ArraySet<>();
final Map<String, Set<Integer>> previouslyUsedIds = new ArrayMap<>();
mPersistentDataStore.readStateForUser(userId, associations, previouslyUsedIds);
@@ -901,17 +901,17 @@ public class CompanionDeviceManagerService extends SystemService {
}
}
Set<Association> getAllAssociations(int userId, @Nullable String packageFilter) {
Set<AssociationInfo> getAllAssociations(int userId, @Nullable String packageFilter) {
return filter(
getAllAssociations(userId),
// Null filter == get all associations
a -> packageFilter == null || Objects.equals(packageFilter, a.getPackageName()));
}
private Set<Association> getAllAssociations() {
private Set<AssociationInfo> getAllAssociations() {
final long identity = Binder.clearCallingIdentity();
try {
ArraySet<Association> result = new ArraySet<>();
ArraySet<AssociationInfo> result = new ArraySet<>();
for (UserInfo user : mUserManager.getAliveUsers()) {
result.addAll(getAllAssociations(user.id));
}
@@ -921,7 +921,7 @@ public class CompanionDeviceManagerService extends SystemService {
}
}
private Set<Association> getAllAssociations(
private Set<AssociationInfo> getAllAssociations(
int userId, @Nullable String packageFilter, @Nullable String addressFilter) {
return filter(
getAllAssociations(userId),
@@ -937,7 +937,7 @@ public class CompanionDeviceManagerService extends SystemService {
mCurrentlyConnectedDevices.add(address);
for (UserInfo user : getAllUsers()) {
for (Association association : getAllAssociations(user.id)) {
for (AssociationInfo association : getAllAssociations(user.id)) {
if (Objects.equals(address, association.getDeviceMacAddress())) {
if (association.getDeviceProfile() != null) {
Slog.i(LOG_TAG, "Granting role " + association.getDeviceProfile()
@@ -952,7 +952,7 @@ public class CompanionDeviceManagerService extends SystemService {
onDeviceNearby(address);
}
private void grantDeviceProfile(Association association) {
private void grantDeviceProfile(AssociationInfo association) {
Slog.i(LOG_TAG, "grantDeviceProfile(association = " + association + ")");
if (association.getDeviceProfile() != null) {
@@ -1059,7 +1059,7 @@ public class CompanionDeviceManagerService extends SystemService {
Date lastNearby = mDevicesLastNearby.valueAt(i);
if (isDeviceDisappeared(lastNearby)) {
for (Association association : getAllAssociations(address)) {
for (AssociationInfo association : getAllAssociations(address)) {
if (association.isNotifyOnDeviceNearby()) {
mCompanionDevicePresenceController.unbindDevicePresenceListener(
association.getPackageName(), association.getUserId());
@@ -1101,12 +1101,12 @@ public class CompanionDeviceManagerService extends SystemService {
}
}
private Set<Association> getAllAssociations(String deviceAddress) {
private Set<AssociationInfo> getAllAssociations(String deviceAddress) {
List<UserInfo> aliveUsers = mUserManager.getAliveUsers();
Set<Association> result = new ArraySet<>();
Set<AssociationInfo> result = new ArraySet<>();
for (int i = 0, size = aliveUsers.size(); i < size; i++) {
UserInfo user = aliveUsers.get(i);
for (Association association : getAllAssociations(user.id)) {
for (AssociationInfo association : getAllAssociations(user.id)) {
if (Objects.equals(association.getDeviceMacAddress(), deviceAddress)) {
result.add(association);
}
@@ -1130,7 +1130,7 @@ public class CompanionDeviceManagerService extends SystemService {
|| timestamp.getTime() - oldTimestamp.getTime() >= DEVICE_DISAPPEARED_TIMEOUT_MS;
if (justAppeared) {
Slog.i(LOG_TAG, "onDeviceNearby(justAppeared, address = " + address + ")");
for (Association association : getAllAssociations(address)) {
for (AssociationInfo association : getAllAssociations(address)) {
if (association.isNotifyOnDeviceNearby()) {
mCompanionDevicePresenceController.onDeviceNotifyAppeared(association,
getContext(), mMainHandler);
@@ -1143,7 +1143,7 @@ public class CompanionDeviceManagerService extends SystemService {
Slog.i(LOG_TAG, "onDeviceDisappeared(address = " + address + ")");
boolean hasDeviceListeners = false;
for (Association association : getAllAssociations(address)) {
for (AssociationInfo association : getAllAssociations(address)) {
if (association.isNotifyOnDeviceNearby()) {
mCompanionDevicePresenceController.onDeviceNotifyDisappeared(
association, getContext(), mMainHandler);
@@ -1212,7 +1212,7 @@ public class CompanionDeviceManagerService extends SystemService {
private List<ScanFilter> getBleScanFilters() {
ArrayList<ScanFilter> result = new ArrayList<>();
ArraySet<String> addressesSeen = new ArraySet<>();
for (Association association : getAllAssociations()) {
for (AssociationInfo association : getAllAssociations()) {
String address = association.getDeviceMacAddress();
if (addressesSeen.contains(address)) {
continue;

View File

@@ -22,7 +22,7 @@ import static android.content.Context.BIND_IMPORTANT;
import static com.android.internal.util.CollectionUtils.filter;
import android.annotation.NonNull;
import android.companion.Association;
import android.companion.AssociationInfo;
import android.companion.CompanionDeviceService;
import android.companion.ICompanionDeviceService;
import android.content.ComponentName;
@@ -60,7 +60,7 @@ public class CompanionDevicePresenceController {
};
}
void onDeviceNotifyAppeared(Association association, Context context, Handler handler) {
void onDeviceNotifyAppeared(AssociationInfo association, Context context, Handler handler) {
ServiceConnector<ICompanionDeviceService> primaryConnector =
getPrimaryServiceConnector(association, context, handler);
if (primaryConnector != null) {
@@ -71,7 +71,7 @@ public class CompanionDevicePresenceController {
}
}
void onDeviceNotifyDisappeared(Association association, Context context, Handler handler) {
void onDeviceNotifyDisappeared(AssociationInfo association, Context context, Handler handler) {
ServiceConnector<ICompanionDeviceService> primaryConnector =
getPrimaryServiceConnector(association, context, handler);
if (primaryConnector != null) {
@@ -94,7 +94,7 @@ public class CompanionDevicePresenceController {
}
private ServiceConnector<ICompanionDeviceService> getPrimaryServiceConnector(
Association association, Context context, Handler handler) {
AssociationInfo association, Context context, Handler handler) {
for (BoundService boundService: getDeviceListenerServiceConnector(association, context,
handler)) {
if (boundService.mIsPrimary) {
@@ -104,15 +104,15 @@ public class CompanionDevicePresenceController {
return null;
}
private List<BoundService> getDeviceListenerServiceConnector(Association a, Context context,
private List<BoundService> getDeviceListenerServiceConnector(AssociationInfo a, Context context,
Handler handler) {
return mBoundServices.forUser(a.getUserId()).computeIfAbsent(
a.getPackageName(),
pkg -> createDeviceListenerServiceConnector(a, context, handler));
}
private List<BoundService> createDeviceListenerServiceConnector(Association a, Context context,
Handler handler) {
private List<BoundService> createDeviceListenerServiceConnector(AssociationInfo a,
Context context, Handler handler) {
List<ResolveInfo> resolveInfos = context
.getPackageManager()
.queryIntentServicesAsUser(new Intent(CompanionDeviceService.SERVICE_INTERFACE),
@@ -161,7 +161,7 @@ public class CompanionDevicePresenceController {
}
private boolean validatePackageInfo(List<ResolveInfo> packageResolveInfos,
Association association) {
AssociationInfo association) {
if (packageResolveInfos.size() == 0 || packageResolveInfos.size() > 5) {
Slog.e(LOG_TAG, "Device presence listener package must have at least one and not "
+ "more than five CompanionDeviceService(s) declared. But "

View File

@@ -34,7 +34,7 @@ import static org.xmlpull.v1.XmlPullParser.START_TAG;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.companion.Association;
import android.companion.AssociationInfo;
import android.companion.DeviceId;
import android.os.Environment;
import android.util.AtomicFile;
@@ -179,11 +179,11 @@ final class PersistentDataStore {
* Reads previously persisted data for the given user "into" the provided containers.
*
* @param userId Android UserID
* @param associationsOut a container to read the {@link Association}s "into".
* @param associationsOut a container to read the {@link AssociationInfo}s "into".
* @param previouslyUsedIdsPerPackageOut a container to read the used IDs "into".
*/
void readStateForUser(@UserIdInt int userId,
@NonNull Set<Association> associationsOut,
@NonNull Set<AssociationInfo> associationsOut,
@NonNull Map<String, Set<Integer>> previouslyUsedIdsPerPackageOut) {
Slog.i(LOG_TAG, "Reading associations for user " + userId + " from disk");
final AtomicFile file = getStorageFileForUser(userId);
@@ -244,7 +244,7 @@ final class PersistentDataStore {
* @param associations a set of user's associations.
* @param previouslyUsedIdsPerPackage a set previously used Association IDs for the user.
*/
void persistStateForUser(@UserIdInt int userId, @NonNull Set<Association> associations,
void persistStateForUser(@UserIdInt int userId, @NonNull Set<AssociationInfo> associations,
@NonNull Map<String, Set<Integer>> previouslyUsedIdsPerPackage) {
Slog.i(LOG_TAG, "Writing associations for user " + userId + " to disk");
if (DEBUG) Slog.d(LOG_TAG, " > " + associations);
@@ -257,7 +257,7 @@ final class PersistentDataStore {
}
private int readStateFromFileLocked(@UserIdInt int userId, @NonNull AtomicFile file,
@NonNull String rootTag, @Nullable Set<Association> associationsOut,
@NonNull String rootTag, @Nullable Set<AssociationInfo> associationsOut,
@NonNull Map<String, Set<Integer>> previouslyUsedIdsPerPackageOut) {
try (FileInputStream in = file.openRead()) {
final TypedXmlPullParser parser = Xml.resolvePullParser(in);
@@ -289,7 +289,7 @@ final class PersistentDataStore {
}
private void persistStateToFileLocked(@NonNull AtomicFile file,
@Nullable Set<Association> associations,
@Nullable Set<AssociationInfo> associations,
@NonNull Map<String, Set<Integer>> previouslyUsedIdsPerPackage) {
file.write(out -> {
try {
@@ -328,7 +328,7 @@ final class PersistentDataStore {
}
private static void readAssociationsV0(@NonNull TypedXmlPullParser parser,
@UserIdInt int userId, @NonNull Set<Association> out)
@UserIdInt int userId, @NonNull Set<AssociationInfo> out)
throws XmlPullParserException, IOException {
requireStartOfTag(parser, XML_TAG_ASSOCIATIONS);
@@ -349,7 +349,7 @@ final class PersistentDataStore {
}
private static void readAssociationV0(@NonNull TypedXmlPullParser parser, @UserIdInt int userId,
int associationId, @NonNull Set<Association> out) throws XmlPullParserException {
int associationId, @NonNull Set<AssociationInfo> out) throws XmlPullParserException {
requireStartOfTag(parser, XML_TAG_ASSOCIATION);
final String appPackage = readStringAttribute(parser, XML_ATTR_PACKAGE);
@@ -366,12 +366,12 @@ final class PersistentDataStore {
// "Convert" MAC address into a DeviceId.
final List<DeviceId> deviceIds = Arrays.asList(
new DeviceId(TYPE_MAC_ADDRESS, deviceAddress));
out.add(new Association(associationId, userId, appPackage, deviceIds, profile,
out.add(new AssociationInfo(associationId, userId, appPackage, deviceIds, profile,
/* managedByCompanionApp */false, notify, timeApproved));
}
private static void readAssociationsV1(@NonNull TypedXmlPullParser parser,
@UserIdInt int userId, @NonNull Set<Association> out)
@UserIdInt int userId, @NonNull Set<AssociationInfo> out)
throws XmlPullParserException, IOException {
requireStartOfTag(parser, XML_TAG_ASSOCIATIONS);
@@ -385,7 +385,7 @@ final class PersistentDataStore {
}
private static void readAssociationV1(@NonNull TypedXmlPullParser parser, @UserIdInt int userId,
@NonNull Set<Association> out) throws XmlPullParserException, IOException {
@NonNull Set<AssociationInfo> out) throws XmlPullParserException, IOException {
requireStartOfTag(parser, XML_TAG_ASSOCIATION);
final int associationId = readIntAttribute(parser, XML_ATTR_ID);
@@ -406,8 +406,8 @@ final class PersistentDataStore {
deviceIds.add(new DeviceId(type, value));
}
out.add(new Association(associationId, userId, appPackage, deviceIds, profile, managedByApp,
notify, timeApproved));
out.add(new AssociationInfo(associationId, userId, appPackage, deviceIds, profile,
managedByApp, notify, timeApproved));
}
private static void readPreviouslyUsedIdsV1(@NonNull TypedXmlPullParser parser,
@@ -437,13 +437,13 @@ final class PersistentDataStore {
}
private static void writeAssociations(@NonNull XmlSerializer parent,
@Nullable Set<Association> associations) throws IOException {
@Nullable Set<AssociationInfo> associations) throws IOException {
final XmlSerializer serializer = parent.startTag(null, XML_TAG_ASSOCIATIONS);
forEach(associations, it -> writeAssociation(serializer, it));
serializer.endTag(null, XML_TAG_ASSOCIATIONS);
}
private static void writeAssociation(@NonNull XmlSerializer parent, @NonNull Association a)
private static void writeAssociation(@NonNull XmlSerializer parent, @NonNull AssociationInfo a)
throws IOException {
final XmlSerializer serializer = parent.startTag(null, XML_TAG_ASSOCIATION);