Loading core/java/android/companion/AssociationInfo.java +8 −0 Original line number Diff line number Diff line Loading @@ -251,6 +251,14 @@ public final class AssociationInfo implements Parcelable { return mPending; } /** * @return true if the association is not revoked nor pending * @hide */ public boolean isActive() { return !mRevoked && !mPending; } /** * @return the last time self reported disconnected for selfManaged only. * @hide Loading services/companion/java/com/android/server/companion/BackupRestoreProcessor.java +54 −67 Original line number Diff line number Diff line Loading @@ -18,7 +18,8 @@ package com.android.server.companion; import static android.os.UserHandle.getCallingUserId; import static com.android.server.companion.CompanionDeviceManagerService.PerUserAssociationSet; import static com.android.server.companion.association.AssociationDiskStore.readAssociationsFromPayload; import static com.android.server.companion.utils.RolesUtils.addRoleHolderForAssociation; import android.annotation.NonNull; import android.annotation.SuppressLint; Loading @@ -26,62 +27,50 @@ import android.annotation.UserIdInt; import android.companion.AssociationInfo; import android.companion.Flags; import android.companion.datatransfer.SystemDataTransferRequest; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManagerInternal; import android.util.ArraySet; import android.util.Log; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.CollectionUtils; import com.android.server.companion.association.AssociationDiskStore; import com.android.server.companion.association.AssociationRequestsProcessor; import com.android.server.companion.association.AssociationStore; import com.android.server.companion.association.Associations; import com.android.server.companion.datatransfer.SystemDataTransferRequestStore; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.function.Predicate; @SuppressLint("LongLogTag") class BackupRestoreProcessor { static final String TAG = "CDM_BackupRestoreProcessor"; private static final String TAG = "CDM_BackupRestoreProcessor"; private static final int BACKUP_AND_RESTORE_VERSION = 0; private final Context mContext; @NonNull private final CompanionDeviceManagerService mService; @NonNull private final PackageManagerInternal mPackageManager; private final PackageManagerInternal mPackageManagerInternal; @NonNull private final AssociationStore mAssociationStore; @NonNull private final AssociationDiskStore mPersistentStore; private final AssociationDiskStore mAssociationDiskStore; @NonNull private final SystemDataTransferRequestStore mSystemDataTransferRequestStore; @NonNull private final AssociationRequestsProcessor mAssociationRequestsProcessor; /** * A structure that consists of a set of restored associations that are pending corresponding * companion app to be installed. */ @GuardedBy("mAssociationsPendingAppInstall") private final PerUserAssociationSet mAssociationsPendingAppInstall = new PerUserAssociationSet(); BackupRestoreProcessor(@NonNull CompanionDeviceManagerService service, BackupRestoreProcessor(@NonNull Context context, @NonNull PackageManagerInternal packageManagerInternal, @NonNull AssociationStore associationStore, @NonNull AssociationDiskStore persistentStore, @NonNull AssociationDiskStore associationDiskStore, @NonNull SystemDataTransferRequestStore systemDataTransferRequestStore, @NonNull AssociationRequestsProcessor associationRequestsProcessor) { mService = service; mPackageManager = service.mPackageManagerInternal; mContext = context; mPackageManagerInternal = packageManagerInternal; mAssociationStore = associationStore; mPersistentStore = persistentStore; mAssociationDiskStore = associationDiskStore; mSystemDataTransferRequestStore = systemDataTransferRequestStore; mAssociationRequestsProcessor = associationRequestsProcessor; } Loading @@ -93,9 +82,9 @@ class BackupRestoreProcessor { * | (4) SystemDataTransferRequest length | SystemDataTransferRequest XML (without userId)| */ byte[] getBackupPayload(int userId) { // Persist state first to generate an up-to-date XML file mService.persistStateForUser(userId); byte[] associationsPayload = mPersistentStore.getBackupPayload(userId); Slog.i(TAG, "getBackupPayload() userId=[" + userId + "]."); byte[] associationsPayload = mAssociationDiskStore.getBackupPayload(userId); int associationsPayloadLength = associationsPayload.length; // System data transfer requests are persisted up-to-date already Loading @@ -119,6 +108,9 @@ class BackupRestoreProcessor { * Create new associations and system data transfer request consents using backed up payload. */ void applyRestoredPayload(byte[] payload, int userId) { Slog.i(TAG, "applyRestoredPayload() userId=[" + userId + "], payload size=[" + payload.length + "]."); ByteBuffer buffer = ByteBuffer.wrap(payload); // Make sure that payload version matches current version to ensure proper deserialization Loading @@ -131,9 +123,8 @@ class BackupRestoreProcessor { // Read the bytes containing backed-up associations byte[] associationsPayload = new byte[buffer.getInt()]; buffer.get(associationsPayload); final Set<AssociationInfo> restoredAssociations = new HashSet<>(); mPersistentStore.readStateFromPayload(associationsPayload, userId, restoredAssociations, new HashMap<>()); final Associations restoredAssociations = readAssociationsFromPayload( associationsPayload, userId); // Read the bytes containing backed-up system data transfer requests user consent byte[] requestsPayload = new byte[buffer.getInt()]; Loading @@ -142,13 +133,13 @@ class BackupRestoreProcessor { mSystemDataTransferRequestStore.readRequestsFromPayload(requestsPayload, userId); // Get a list of installed packages ahead of time. List<ApplicationInfo> installedApps = mPackageManager.getInstalledApplications( List<ApplicationInfo> installedApps = mPackageManagerInternal.getInstalledApplications( 0, userId, getCallingUserId()); // Restored device may have a different user ID than the backed-up user's user-ID. Since // association ID is dependent on the user ID, restored associations must account for // this potential difference on their association IDs. for (AssociationInfo restored : restoredAssociations) { for (AssociationInfo restored : restoredAssociations.getAssociations()) { // Don't restore a revoked association. Since they weren't added to the device being // restored in the first place, there is no need to worry about revoking a role that // was never granted either. Loading @@ -168,10 +159,9 @@ class BackupRestoreProcessor { // Create a new association reassigned to this user and a valid association ID final String packageName = restored.getPackageName(); final int newId = mService.getNewAssociationIdForPackage(userId, packageName); AssociationInfo newAssociation = new AssociationInfo.Builder(newId, userId, packageName, restored) .build(); final int newId = mAssociationStore.getNextId(userId); AssociationInfo newAssociation = new AssociationInfo.Builder(newId, userId, packageName, restored).build(); // Check if the companion app for this association is already installed, then do one // of the following: Loading @@ -179,13 +169,15 @@ class BackupRestoreProcessor { // the role attached to this association to the app. // (2) If the app isn't yet installed, then add this association to the list of pending // associations to be added when the package is installed in the future. boolean isPackageInstalled = installedApps.stream() .anyMatch(app -> packageName.equals(app.packageName)); boolean isPackageInstalled = installedApps.stream().anyMatch( app -> packageName.equals(app.packageName)); if (isPackageInstalled) { mAssociationRequestsProcessor.maybeGrantRoleAndStoreAssociation(newAssociation, null, null); } else { addToPendingAppInstall(newAssociation); newAssociation = (new AssociationInfo.Builder(newAssociation)).setPending(true) .build(); mAssociationStore.addAssociation(newAssociation); } // Re-map restored system data transfer requests to newly created associations Loading @@ -195,32 +187,27 @@ class BackupRestoreProcessor { mSystemDataTransferRequestStore.writeRequest(userId, newRequest); } } // Persist restored state. mService.persistStateForUser(userId); } void addToPendingAppInstall(@NonNull AssociationInfo association) { association = (new AssociationInfo.Builder(association)) .setPending(true) .build(); synchronized (mAssociationsPendingAppInstall) { mAssociationsPendingAppInstall.forUser(association.getUserId()).add(association); } } void removeFromPendingAppInstall(@NonNull AssociationInfo association) { synchronized (mAssociationsPendingAppInstall) { mAssociationsPendingAppInstall.forUser(association.getUserId()).remove(association); public void restorePendingAssociations(int userId, String packageName) { List<AssociationInfo> pendingAssociations = mAssociationStore.getPendingAssociations(userId, packageName); if (!pendingAssociations.isEmpty()) { Slog.i(TAG, "Found pending associations for package=[" + packageName + "]. Restoring..."); } for (AssociationInfo association : pendingAssociations) { AssociationInfo newAssociation = new AssociationInfo.Builder(association) .setPending(false) .build(); addRoleHolderForAssociation(mContext, newAssociation, success -> { if (success) { mAssociationStore.updateAssociation(newAssociation); Slog.i(TAG, "Association=[" + association + "] is restored."); } else { Slog.e(TAG, "Failed to restore association=[" + association + "]."); } @NonNull Set<AssociationInfo> getAssociationsPendingAppInstallForUser(@UserIdInt int userId) { synchronized (mAssociationsPendingAppInstall) { // Return a copy. return new ArraySet<>(mAssociationsPendingAppInstall.forUser(userId)); }); } } Loading @@ -231,7 +218,7 @@ class BackupRestoreProcessor { private boolean handleCollision(@UserIdInt int userId, AssociationInfo restored, List<SystemDataTransferRequest> restoredRequests) { List<AssociationInfo> localAssociations = mAssociationStore.getAssociationsForPackage( List<AssociationInfo> localAssociations = mAssociationStore.getActiveAssociationsByPackage( restored.getUserId(), restored.getPackageName()); Predicate<AssociationInfo> isSameDevice = associationInfo -> { boolean matchesMacAddress = Objects.equals( Loading @@ -248,7 +235,7 @@ class BackupRestoreProcessor { return false; } Log.d(TAG, "Conflict detected with association id=" + local.getId() Slog.d(TAG, "Conflict detected with association id=" + local.getId() + " while restoring CDM backup. Keeping local association."); List<SystemDataTransferRequest> localRequests = mSystemDataTransferRequestStore Loading @@ -266,8 +253,8 @@ class BackupRestoreProcessor { continue; } Log.d(TAG, "Restoring " + restoredRequest.getClass().getSimpleName() + " to an existing association id=" + local.getId() + "."); Slog.d(TAG, "Restoring " + restoredRequest.getClass().getSimpleName() + " to an existing association id=[" + local.getId() + "]."); SystemDataTransferRequest newRequest = restoredRequest.copyWithNewId(local.getId()); Loading services/companion/java/com/android/server/companion/CompanionApplicationController.java +2 −2 Original line number Diff line number Diff line Loading @@ -397,7 +397,7 @@ public class CompanionApplicationController { // First, disable hint mode for Auto profile and mark not BOUND for primary service ONLY. if (isPrimary) { final List<AssociationInfo> associations = mAssociationStore.getAssociationsForPackage(userId, packageName); mAssociationStore.getActiveAssociationsByPackage(userId, packageName); for (AssociationInfo association : associations) { final String deviceProfile = association.getDeviceProfile(); Loading Loading @@ -442,7 +442,7 @@ public class CompanionApplicationController { mObservableUuidStore.getObservableUuidsForPackage(userId, packageName); for (AssociationInfo ai : mAssociationStore.getAssociationsForPackage(userId, packageName)) { mAssociationStore.getActiveAssociationsByPackage(userId, packageName)) { final int associationId = ai.getId(); stillAssociated = true; if (ai.isSelfManaged()) { Loading services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +95 −385 File changed.Preview size limit exceeded, changes collapsed. Show changes services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java +15 −16 Original line number Diff line number Diff line Loading @@ -33,8 +33,8 @@ import android.util.Base64; import android.util.proto.ProtoOutputStream; import com.android.server.companion.association.AssociationRequestsProcessor; import com.android.server.companion.association.AssociationRevokeProcessor; import com.android.server.companion.association.AssociationStore; import com.android.server.companion.association.DisassociationProcessor; import com.android.server.companion.datatransfer.SystemDataTransferProcessor; import com.android.server.companion.datatransfer.contextsync.BitmapUtils; import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncController; Loading @@ -49,7 +49,7 @@ class CompanionDeviceShellCommand extends ShellCommand { private static final String TAG = "CDM_CompanionDeviceShellCommand"; private final CompanionDeviceManagerService mService; private final AssociationRevokeProcessor mRevokeProcessor; private final DisassociationProcessor mDisassociationProcessor; private final AssociationStore mAssociationStore; private final CompanionDevicePresenceMonitor mDevicePresenceMonitor; private final CompanionTransportManager mTransportManager; Loading @@ -65,7 +65,7 @@ class CompanionDeviceShellCommand extends ShellCommand { SystemDataTransferProcessor systemDataTransferProcessor, AssociationRequestsProcessor associationRequestsProcessor, BackupRestoreProcessor backupRestoreProcessor, AssociationRevokeProcessor revokeProcessor) { DisassociationProcessor disassociationProcessor) { mService = service; mAssociationStore = associationStore; mDevicePresenceMonitor = devicePresenceMonitor; Loading @@ -73,7 +73,7 @@ class CompanionDeviceShellCommand extends ShellCommand { mSystemDataTransferProcessor = systemDataTransferProcessor; mAssociationRequestsProcessor = associationRequestsProcessor; mBackupRestoreProcessor = backupRestoreProcessor; mRevokeProcessor = revokeProcessor; mDisassociationProcessor = disassociationProcessor; } @Override Loading Loading @@ -105,12 +105,15 @@ class CompanionDeviceShellCommand extends ShellCommand { case "list": { final int userId = getNextIntArgRequired(); final List<AssociationInfo> associationsForUser = mAssociationStore.getAssociationsForUser(userId); mAssociationStore.getActiveAssociationsByUser(userId); final int maxId = mAssociationStore.getMaxId(userId); out.println("Max ID: " + maxId); out.println("Association ID | Package Name | Mac Address"); for (AssociationInfo association : associationsForUser) { // TODO(b/212535524): use AssociationInfo.toShortString(), once it's not // longer referenced in tests. out.println(association.getPackageName() + " " + association.getDeviceMacAddress() + " " + association.getId()); out.println(association.getId() + " | " + association.getPackageName() + " | " + association.getDeviceMacAddress()); } } break; Loading @@ -132,28 +135,24 @@ class CompanionDeviceShellCommand extends ShellCommand { final String address = getNextArgRequired(); final AssociationInfo association = mService.getAssociationWithCallerChecks(userId, packageName, address); if (association != null) { mRevokeProcessor.disassociateInternal(association.getId()); } mDisassociationProcessor.disassociate(association.getId()); } break; case "disassociate-all": { final int userId = getNextIntArgRequired(); final String packageName = getNextArgRequired(); final List<AssociationInfo> userAssociations = mAssociationStore.getAssociationsForPackage(userId, packageName); mAssociationStore.getAssociationsByUser(userId); for (AssociationInfo association : userAssociations) { if (sanitizeWithCallerChecks(mService.getContext(), association) != null) { mRevokeProcessor.disassociateInternal(association.getId()); mDisassociationProcessor.disassociate(association.getId()); } } } break; case "clear-association-memory-cache": mService.persistState(); mService.loadAssociationsFromDisk(); case "refresh-cache": mAssociationStore.refreshCache(); break; case "simulate-device-appeared": Loading Loading
core/java/android/companion/AssociationInfo.java +8 −0 Original line number Diff line number Diff line Loading @@ -251,6 +251,14 @@ public final class AssociationInfo implements Parcelable { return mPending; } /** * @return true if the association is not revoked nor pending * @hide */ public boolean isActive() { return !mRevoked && !mPending; } /** * @return the last time self reported disconnected for selfManaged only. * @hide Loading
services/companion/java/com/android/server/companion/BackupRestoreProcessor.java +54 −67 Original line number Diff line number Diff line Loading @@ -18,7 +18,8 @@ package com.android.server.companion; import static android.os.UserHandle.getCallingUserId; import static com.android.server.companion.CompanionDeviceManagerService.PerUserAssociationSet; import static com.android.server.companion.association.AssociationDiskStore.readAssociationsFromPayload; import static com.android.server.companion.utils.RolesUtils.addRoleHolderForAssociation; import android.annotation.NonNull; import android.annotation.SuppressLint; Loading @@ -26,62 +27,50 @@ import android.annotation.UserIdInt; import android.companion.AssociationInfo; import android.companion.Flags; import android.companion.datatransfer.SystemDataTransferRequest; import android.content.Context; import android.content.pm.ApplicationInfo; import android.content.pm.PackageManagerInternal; import android.util.ArraySet; import android.util.Log; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import com.android.internal.util.CollectionUtils; import com.android.server.companion.association.AssociationDiskStore; import com.android.server.companion.association.AssociationRequestsProcessor; import com.android.server.companion.association.AssociationStore; import com.android.server.companion.association.Associations; import com.android.server.companion.datatransfer.SystemDataTransferRequestStore; import java.nio.ByteBuffer; import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.function.Predicate; @SuppressLint("LongLogTag") class BackupRestoreProcessor { static final String TAG = "CDM_BackupRestoreProcessor"; private static final String TAG = "CDM_BackupRestoreProcessor"; private static final int BACKUP_AND_RESTORE_VERSION = 0; private final Context mContext; @NonNull private final CompanionDeviceManagerService mService; @NonNull private final PackageManagerInternal mPackageManager; private final PackageManagerInternal mPackageManagerInternal; @NonNull private final AssociationStore mAssociationStore; @NonNull private final AssociationDiskStore mPersistentStore; private final AssociationDiskStore mAssociationDiskStore; @NonNull private final SystemDataTransferRequestStore mSystemDataTransferRequestStore; @NonNull private final AssociationRequestsProcessor mAssociationRequestsProcessor; /** * A structure that consists of a set of restored associations that are pending corresponding * companion app to be installed. */ @GuardedBy("mAssociationsPendingAppInstall") private final PerUserAssociationSet mAssociationsPendingAppInstall = new PerUserAssociationSet(); BackupRestoreProcessor(@NonNull CompanionDeviceManagerService service, BackupRestoreProcessor(@NonNull Context context, @NonNull PackageManagerInternal packageManagerInternal, @NonNull AssociationStore associationStore, @NonNull AssociationDiskStore persistentStore, @NonNull AssociationDiskStore associationDiskStore, @NonNull SystemDataTransferRequestStore systemDataTransferRequestStore, @NonNull AssociationRequestsProcessor associationRequestsProcessor) { mService = service; mPackageManager = service.mPackageManagerInternal; mContext = context; mPackageManagerInternal = packageManagerInternal; mAssociationStore = associationStore; mPersistentStore = persistentStore; mAssociationDiskStore = associationDiskStore; mSystemDataTransferRequestStore = systemDataTransferRequestStore; mAssociationRequestsProcessor = associationRequestsProcessor; } Loading @@ -93,9 +82,9 @@ class BackupRestoreProcessor { * | (4) SystemDataTransferRequest length | SystemDataTransferRequest XML (without userId)| */ byte[] getBackupPayload(int userId) { // Persist state first to generate an up-to-date XML file mService.persistStateForUser(userId); byte[] associationsPayload = mPersistentStore.getBackupPayload(userId); Slog.i(TAG, "getBackupPayload() userId=[" + userId + "]."); byte[] associationsPayload = mAssociationDiskStore.getBackupPayload(userId); int associationsPayloadLength = associationsPayload.length; // System data transfer requests are persisted up-to-date already Loading @@ -119,6 +108,9 @@ class BackupRestoreProcessor { * Create new associations and system data transfer request consents using backed up payload. */ void applyRestoredPayload(byte[] payload, int userId) { Slog.i(TAG, "applyRestoredPayload() userId=[" + userId + "], payload size=[" + payload.length + "]."); ByteBuffer buffer = ByteBuffer.wrap(payload); // Make sure that payload version matches current version to ensure proper deserialization Loading @@ -131,9 +123,8 @@ class BackupRestoreProcessor { // Read the bytes containing backed-up associations byte[] associationsPayload = new byte[buffer.getInt()]; buffer.get(associationsPayload); final Set<AssociationInfo> restoredAssociations = new HashSet<>(); mPersistentStore.readStateFromPayload(associationsPayload, userId, restoredAssociations, new HashMap<>()); final Associations restoredAssociations = readAssociationsFromPayload( associationsPayload, userId); // Read the bytes containing backed-up system data transfer requests user consent byte[] requestsPayload = new byte[buffer.getInt()]; Loading @@ -142,13 +133,13 @@ class BackupRestoreProcessor { mSystemDataTransferRequestStore.readRequestsFromPayload(requestsPayload, userId); // Get a list of installed packages ahead of time. List<ApplicationInfo> installedApps = mPackageManager.getInstalledApplications( List<ApplicationInfo> installedApps = mPackageManagerInternal.getInstalledApplications( 0, userId, getCallingUserId()); // Restored device may have a different user ID than the backed-up user's user-ID. Since // association ID is dependent on the user ID, restored associations must account for // this potential difference on their association IDs. for (AssociationInfo restored : restoredAssociations) { for (AssociationInfo restored : restoredAssociations.getAssociations()) { // Don't restore a revoked association. Since they weren't added to the device being // restored in the first place, there is no need to worry about revoking a role that // was never granted either. Loading @@ -168,10 +159,9 @@ class BackupRestoreProcessor { // Create a new association reassigned to this user and a valid association ID final String packageName = restored.getPackageName(); final int newId = mService.getNewAssociationIdForPackage(userId, packageName); AssociationInfo newAssociation = new AssociationInfo.Builder(newId, userId, packageName, restored) .build(); final int newId = mAssociationStore.getNextId(userId); AssociationInfo newAssociation = new AssociationInfo.Builder(newId, userId, packageName, restored).build(); // Check if the companion app for this association is already installed, then do one // of the following: Loading @@ -179,13 +169,15 @@ class BackupRestoreProcessor { // the role attached to this association to the app. // (2) If the app isn't yet installed, then add this association to the list of pending // associations to be added when the package is installed in the future. boolean isPackageInstalled = installedApps.stream() .anyMatch(app -> packageName.equals(app.packageName)); boolean isPackageInstalled = installedApps.stream().anyMatch( app -> packageName.equals(app.packageName)); if (isPackageInstalled) { mAssociationRequestsProcessor.maybeGrantRoleAndStoreAssociation(newAssociation, null, null); } else { addToPendingAppInstall(newAssociation); newAssociation = (new AssociationInfo.Builder(newAssociation)).setPending(true) .build(); mAssociationStore.addAssociation(newAssociation); } // Re-map restored system data transfer requests to newly created associations Loading @@ -195,32 +187,27 @@ class BackupRestoreProcessor { mSystemDataTransferRequestStore.writeRequest(userId, newRequest); } } // Persist restored state. mService.persistStateForUser(userId); } void addToPendingAppInstall(@NonNull AssociationInfo association) { association = (new AssociationInfo.Builder(association)) .setPending(true) .build(); synchronized (mAssociationsPendingAppInstall) { mAssociationsPendingAppInstall.forUser(association.getUserId()).add(association); } } void removeFromPendingAppInstall(@NonNull AssociationInfo association) { synchronized (mAssociationsPendingAppInstall) { mAssociationsPendingAppInstall.forUser(association.getUserId()).remove(association); public void restorePendingAssociations(int userId, String packageName) { List<AssociationInfo> pendingAssociations = mAssociationStore.getPendingAssociations(userId, packageName); if (!pendingAssociations.isEmpty()) { Slog.i(TAG, "Found pending associations for package=[" + packageName + "]. Restoring..."); } for (AssociationInfo association : pendingAssociations) { AssociationInfo newAssociation = new AssociationInfo.Builder(association) .setPending(false) .build(); addRoleHolderForAssociation(mContext, newAssociation, success -> { if (success) { mAssociationStore.updateAssociation(newAssociation); Slog.i(TAG, "Association=[" + association + "] is restored."); } else { Slog.e(TAG, "Failed to restore association=[" + association + "]."); } @NonNull Set<AssociationInfo> getAssociationsPendingAppInstallForUser(@UserIdInt int userId) { synchronized (mAssociationsPendingAppInstall) { // Return a copy. return new ArraySet<>(mAssociationsPendingAppInstall.forUser(userId)); }); } } Loading @@ -231,7 +218,7 @@ class BackupRestoreProcessor { private boolean handleCollision(@UserIdInt int userId, AssociationInfo restored, List<SystemDataTransferRequest> restoredRequests) { List<AssociationInfo> localAssociations = mAssociationStore.getAssociationsForPackage( List<AssociationInfo> localAssociations = mAssociationStore.getActiveAssociationsByPackage( restored.getUserId(), restored.getPackageName()); Predicate<AssociationInfo> isSameDevice = associationInfo -> { boolean matchesMacAddress = Objects.equals( Loading @@ -248,7 +235,7 @@ class BackupRestoreProcessor { return false; } Log.d(TAG, "Conflict detected with association id=" + local.getId() Slog.d(TAG, "Conflict detected with association id=" + local.getId() + " while restoring CDM backup. Keeping local association."); List<SystemDataTransferRequest> localRequests = mSystemDataTransferRequestStore Loading @@ -266,8 +253,8 @@ class BackupRestoreProcessor { continue; } Log.d(TAG, "Restoring " + restoredRequest.getClass().getSimpleName() + " to an existing association id=" + local.getId() + "."); Slog.d(TAG, "Restoring " + restoredRequest.getClass().getSimpleName() + " to an existing association id=[" + local.getId() + "]."); SystemDataTransferRequest newRequest = restoredRequest.copyWithNewId(local.getId()); Loading
services/companion/java/com/android/server/companion/CompanionApplicationController.java +2 −2 Original line number Diff line number Diff line Loading @@ -397,7 +397,7 @@ public class CompanionApplicationController { // First, disable hint mode for Auto profile and mark not BOUND for primary service ONLY. if (isPrimary) { final List<AssociationInfo> associations = mAssociationStore.getAssociationsForPackage(userId, packageName); mAssociationStore.getActiveAssociationsByPackage(userId, packageName); for (AssociationInfo association : associations) { final String deviceProfile = association.getDeviceProfile(); Loading Loading @@ -442,7 +442,7 @@ public class CompanionApplicationController { mObservableUuidStore.getObservableUuidsForPackage(userId, packageName); for (AssociationInfo ai : mAssociationStore.getAssociationsForPackage(userId, packageName)) { mAssociationStore.getActiveAssociationsByPackage(userId, packageName)) { final int associationId = ai.getId(); stillAssociated = true; if (ai.isSelfManaged()) { Loading
services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +95 −385 File changed.Preview size limit exceeded, changes collapsed. Show changes
services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java +15 −16 Original line number Diff line number Diff line Loading @@ -33,8 +33,8 @@ import android.util.Base64; import android.util.proto.ProtoOutputStream; import com.android.server.companion.association.AssociationRequestsProcessor; import com.android.server.companion.association.AssociationRevokeProcessor; import com.android.server.companion.association.AssociationStore; import com.android.server.companion.association.DisassociationProcessor; import com.android.server.companion.datatransfer.SystemDataTransferProcessor; import com.android.server.companion.datatransfer.contextsync.BitmapUtils; import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncController; Loading @@ -49,7 +49,7 @@ class CompanionDeviceShellCommand extends ShellCommand { private static final String TAG = "CDM_CompanionDeviceShellCommand"; private final CompanionDeviceManagerService mService; private final AssociationRevokeProcessor mRevokeProcessor; private final DisassociationProcessor mDisassociationProcessor; private final AssociationStore mAssociationStore; private final CompanionDevicePresenceMonitor mDevicePresenceMonitor; private final CompanionTransportManager mTransportManager; Loading @@ -65,7 +65,7 @@ class CompanionDeviceShellCommand extends ShellCommand { SystemDataTransferProcessor systemDataTransferProcessor, AssociationRequestsProcessor associationRequestsProcessor, BackupRestoreProcessor backupRestoreProcessor, AssociationRevokeProcessor revokeProcessor) { DisassociationProcessor disassociationProcessor) { mService = service; mAssociationStore = associationStore; mDevicePresenceMonitor = devicePresenceMonitor; Loading @@ -73,7 +73,7 @@ class CompanionDeviceShellCommand extends ShellCommand { mSystemDataTransferProcessor = systemDataTransferProcessor; mAssociationRequestsProcessor = associationRequestsProcessor; mBackupRestoreProcessor = backupRestoreProcessor; mRevokeProcessor = revokeProcessor; mDisassociationProcessor = disassociationProcessor; } @Override Loading Loading @@ -105,12 +105,15 @@ class CompanionDeviceShellCommand extends ShellCommand { case "list": { final int userId = getNextIntArgRequired(); final List<AssociationInfo> associationsForUser = mAssociationStore.getAssociationsForUser(userId); mAssociationStore.getActiveAssociationsByUser(userId); final int maxId = mAssociationStore.getMaxId(userId); out.println("Max ID: " + maxId); out.println("Association ID | Package Name | Mac Address"); for (AssociationInfo association : associationsForUser) { // TODO(b/212535524): use AssociationInfo.toShortString(), once it's not // longer referenced in tests. out.println(association.getPackageName() + " " + association.getDeviceMacAddress() + " " + association.getId()); out.println(association.getId() + " | " + association.getPackageName() + " | " + association.getDeviceMacAddress()); } } break; Loading @@ -132,28 +135,24 @@ class CompanionDeviceShellCommand extends ShellCommand { final String address = getNextArgRequired(); final AssociationInfo association = mService.getAssociationWithCallerChecks(userId, packageName, address); if (association != null) { mRevokeProcessor.disassociateInternal(association.getId()); } mDisassociationProcessor.disassociate(association.getId()); } break; case "disassociate-all": { final int userId = getNextIntArgRequired(); final String packageName = getNextArgRequired(); final List<AssociationInfo> userAssociations = mAssociationStore.getAssociationsForPackage(userId, packageName); mAssociationStore.getAssociationsByUser(userId); for (AssociationInfo association : userAssociations) { if (sanitizeWithCallerChecks(mService.getContext(), association) != null) { mRevokeProcessor.disassociateInternal(association.getId()); mDisassociationProcessor.disassociate(association.getId()); } } } break; case "clear-association-memory-cache": mService.persistState(); mService.loadAssociationsFromDisk(); case "refresh-cache": mAssociationStore.refreshCache(); break; case "simulate-device-appeared": Loading