Loading packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java +10 −15 Original line number Diff line number Diff line Loading @@ -363,13 +363,6 @@ public class CompanionDeviceActivity extends FragmentActivity implements mCdmServiceReceiver.send(RESULT_CODE_ASSOCIATION_APPROVED, data); } private void onAssociationCreated(@NonNull AssociationInfo association) { if (DEBUG) Log.i(TAG, "onAssociationCreated(), association=" + association); // Don't need to notify the app, CdmService has already done that. Just finish. setResultAndFinish(association, RESULT_OK); } private void cancel(boolean discoveryTimeout, boolean userRejected) { if (DEBUG) { Log.i(TAG, "cancel(), discoveryTimeout=" Loading Loading @@ -413,7 +406,9 @@ public class CompanionDeviceActivity extends FragmentActivity implements } private void setResultAndFinish(@Nullable AssociationInfo association, int resultCode) { if (DEBUG) Log.i(TAG, "setResultAndFinish(), association=" + association); Log.i(TAG, "setResultAndFinish(), association=" + (association == null ? "null" : association) + "resultCode=" + resultCode); final Intent data = new Intent(); if (association != null) { Loading Loading @@ -652,14 +647,14 @@ public class CompanionDeviceActivity extends FragmentActivity implements new ResultReceiver(Handler.getMain()) { @Override protected void onReceiveResult(int resultCode, Bundle data) { if (resultCode != RESULT_CODE_ASSOCIATION_CREATED) { throw new RuntimeException("Unknown result code: " + resultCode); } final AssociationInfo association = data.getParcelable(EXTRA_ASSOCIATION); if (resultCode == RESULT_CODE_ASSOCIATION_CREATED) { final AssociationInfo association = data.getParcelable( EXTRA_ASSOCIATION, AssociationInfo.class); requireNonNull(association); onAssociationCreated(association); setResultAndFinish(association, RESULT_OK); } else { setResultAndFinish(null, resultCode); } } }; Loading services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java +102 −22 Original line number Diff line number Diff line Loading @@ -23,8 +23,10 @@ import static android.companion.CompanionDeviceManager.COMPANION_DEVICE_DISCOVER import static android.content.ComponentName.createRelative; import static com.android.server.companion.CompanionDeviceManagerService.DEBUG; import static com.android.server.companion.MetricUtils.logCreateAssociation; import static com.android.server.companion.PackageUtils.enforceUsesCompanionDeviceFeature; import static com.android.server.companion.PermissionsUtils.enforcePermissionsForAssociation; import static com.android.server.companion.RolesUtils.addRoleHolderForAssociation; import static com.android.server.companion.RolesUtils.isRoleHolder; import static com.android.server.companion.Utils.prepareForIpc; Loading @@ -35,8 +37,10 @@ import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.UserIdInt; import android.app.PendingIntent; import android.companion.AssociatedDevice; import android.companion.AssociationInfo; import android.companion.AssociationRequest; import android.companion.CompanionDeviceManager; import android.companion.IAssociationRequestCallback; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -87,7 +91,7 @@ import java.util.Set; * required. * * If the user's approval is NOT required: an {@link AssociationRequestsProcessor} invokes * {@link #createAssociationAndNotifyApplication(AssociationRequest, String, int, MacAddress, IAssociationRequestCallback)} * {@link #createAssociationAndNotifyApplication(AssociationRequest, String, int, MacAddress, IAssociationRequestCallback, ResultReceiver)} * which after calling to {@link CompanionDeviceManagerService} to create an association, notifies * the requester via * {@link android.companion.CompanionDeviceManager.Callback#onAssociationCreated(AssociationInfo)}. Loading @@ -99,7 +103,7 @@ import java.util.Set; * from the Approval UI in via {@link #mOnRequestConfirmationReceiver} and invokes * {@link #processAssociationRequestApproval(AssociationRequest, IAssociationRequestCallback, ResultReceiver, MacAddress)} * which one more time checks that the packages holds all necessary permissions before proceeding to * {@link #createAssociationAndNotifyApplication(AssociationRequest, String, int, MacAddress, IAssociationRequestCallback)}. * {@link #createAssociationAndNotifyApplication(AssociationRequest, String, int, MacAddress, IAssociationRequestCallback, ResultReceiver)}. * * @see #processNewAssociationRequest(AssociationRequest, String, int, IAssociationRequestCallback) * @see #processAssociationRequestApproval(AssociationRequest, IAssociationRequestCallback, Loading Loading @@ -132,10 +136,10 @@ class AssociationRequestsProcessor { private final @NonNull Context mContext; private final @NonNull CompanionDeviceManagerService mService; private final @NonNull PackageManagerInternal mPackageManager; private final @NonNull AssociationStore mAssociationStore; private final @NonNull AssociationStoreImpl mAssociationStore; AssociationRequestsProcessor(@NonNull CompanionDeviceManagerService service, @NonNull AssociationStore associationStore) { @NonNull AssociationStoreImpl associationStore) { mContext = service.getContext(); mService = service; mPackageManager = service.mPackageManagerInternal; Loading Loading @@ -174,7 +178,7 @@ class AssociationRequestsProcessor { && !willAddRoleHolder(request, packageName, userId)) { // 2a. Create association right away. createAssociationAndNotifyApplication(request, packageName, userId, /*macAddress*/ null, callback); /* macAddress */ null, callback, /* resultReceiver */ null); return; } Loading Loading @@ -253,34 +257,110 @@ class AssociationRequestsProcessor { } // 2. Create association and notify the application. final AssociationInfo association = createAssociationAndNotifyApplication( request, packageName, userId, macAddress, callback); // 3. Send the association back the Approval Activity, so that it can report back to the app // via Activity.setResult(). final Bundle data = new Bundle(); data.putParcelable(EXTRA_ASSOCIATION, association); resultReceiver.send(RESULT_CODE_ASSOCIATION_CREATED, data); createAssociationAndNotifyApplication(request, packageName, userId, macAddress, callback, resultReceiver); } private AssociationInfo createAssociationAndNotifyApplication( private void createAssociationAndNotifyApplication( @NonNull AssociationRequest request, @NonNull String packageName, @UserIdInt int userId, @Nullable MacAddress macAddress, @NonNull IAssociationRequestCallback callback) { final AssociationInfo association; @Nullable MacAddress macAddress, @NonNull IAssociationRequestCallback callback, @NonNull ResultReceiver resultReceiver) { final long callingIdentity = Binder.clearCallingIdentity(); try { association = mService.createAssociation(userId, packageName, macAddress, createAssociation(userId, packageName, macAddress, request.getDisplayName(), request.getDeviceProfile(), request.getAssociatedDevice(), request.isSelfManaged()); request.getAssociatedDevice(), request.isSelfManaged(), callback, resultReceiver); } finally { Binder.restoreCallingIdentity(callingIdentity); } } public void createAssociation(@UserIdInt int userId, @NonNull String packageName, @Nullable MacAddress macAddress, @Nullable CharSequence displayName, @Nullable String deviceProfile, @Nullable AssociatedDevice associatedDevice, boolean selfManaged, @Nullable IAssociationRequestCallback callback, @Nullable ResultReceiver resultReceiver) { final int id = mService.getNewAssociationIdForPackage(userId, packageName); final long timestamp = System.currentTimeMillis(); final AssociationInfo association = new AssociationInfo(id, userId, packageName, macAddress, displayName, deviceProfile, associatedDevice, selfManaged, /* notifyOnDeviceNearby */ false, /* revoked */ false, timestamp, Long.MAX_VALUE); if (deviceProfile != null) { // If the "Device Profile" is specified, make the companion application a holder of the // corresponding role. addRoleHolderForAssociation(mService.getContext(), association, success -> { if (success) { addAssociationToStore(association, deviceProfile); sendCallbackAndFinish(association, callback, resultReceiver); } else { Slog.e(TAG, "Failed to add u" + userId + "\\" + packageName + " to the list of " + deviceProfile + " holders."); sendCallbackAndFinish(null, callback, resultReceiver); } }); } else { addAssociationToStore(association, null); sendCallbackAndFinish(association, callback, resultReceiver); } // Don't need to update the mRevokedAssociationsPendingRoleHolderRemoval since // maybeRemoveRoleHolderForAssociation in PackageInactivityListener will handle the case // that there are other devices with the same profile, so the role holder won't be removed. } private void addAssociationToStore(@NonNull AssociationInfo association, @Nullable String deviceProfile) { Slog.i(TAG, "New CDM association created=" + association); mAssociationStore.addAssociation(association); mService.updateSpecialAccessPermissionForAssociatedPackage(association); logCreateAssociation(deviceProfile); } private void sendCallbackAndFinish(@Nullable AssociationInfo association, @Nullable IAssociationRequestCallback callback, @Nullable ResultReceiver resultReceiver) { if (association != null) { // Send the association back via the app's callback if (callback != null) { try { callback.onAssociationCreated(association); } catch (RemoteException ignore) { } } catch (RemoteException ignore) { } } return association; // Send the association back to CompanionDeviceActivity, so that it can report // back to the app via Activity.setResult(). if (resultReceiver != null) { final Bundle data = new Bundle(); data.putParcelable(EXTRA_ASSOCIATION, association); resultReceiver.send(RESULT_CODE_ASSOCIATION_CREATED, data); } } else { // Send the association back via the app's callback if (callback != null) { try { // TODO: update to INTERNAL_ERROR once it's added. callback.onFailure(CompanionDeviceManager.REASON_CANCELED); } catch (RemoteException ignore) { } } // Send the association back to CompanionDeviceActivity, so that it can report // back to the app via Activity.setResult(). if (resultReceiver != null) { final Bundle data = new Bundle(); resultReceiver.send(CompanionDeviceManager.RESULT_INTERNAL_ERROR, data); } } } private boolean willAddRoleHolder(@NonNull AssociationRequest request, Loading services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +9 −44 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import static com.android.internal.util.CollectionUtils.any; import static com.android.internal.util.Preconditions.checkState; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import static com.android.server.companion.AssociationStore.CHANGE_TYPE_UPDATED_ADDRESS_UNCHANGED; import static com.android.server.companion.MetricUtils.logCreateAssociation; import static com.android.server.companion.MetricUtils.logRemoveAssociation; import static com.android.server.companion.PackageUtils.enforceUsesCompanionDeviceFeature; import static com.android.server.companion.PackageUtils.getPackageInfo; Loading @@ -38,7 +37,6 @@ import static com.android.server.companion.PermissionsUtils.enforceCallerCanMana import static com.android.server.companion.PermissionsUtils.enforceCallerIsSystemOr; import static com.android.server.companion.PermissionsUtils.enforceCallerIsSystemOrCanInteractWithUserId; import static com.android.server.companion.PermissionsUtils.sanitizeWithCallerChecks; import static com.android.server.companion.RolesUtils.addRoleHolderForAssociation; import static com.android.server.companion.RolesUtils.removeRoleHolderForAssociation; import static java.util.Objects.requireNonNull; Loading @@ -55,7 +53,6 @@ import android.app.ActivityManagerInternal; import android.app.AppOpsManager; import android.app.NotificationManager; import android.app.PendingIntent; import android.companion.AssociatedDevice; import android.companion.AssociationInfo; import android.companion.AssociationRequest; import android.companion.DeviceNotAssociatedException; Loading Loading @@ -819,7 +816,8 @@ public class CompanionDeviceManagerService extends SystemService { getContext().enforceCallingOrSelfPermission( android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES, "createAssociation"); legacyCreateAssociation(userId, macAddress, packageName, null); final MacAddress macAddressObj = MacAddress.fromString(macAddress); createNewAssociation(userId, packageName, macAddressObj, null, null, false); } private void checkCanCallNotificationApi(String callingPackage) { Loading Loading @@ -871,45 +869,12 @@ public class CompanionDeviceManagerService extends SystemService { } } /** * @deprecated use * {@link #createAssociation(int, String, MacAddress, CharSequence, String, AssociatedDevice, * boolean)} */ @Deprecated void legacyCreateAssociation(@UserIdInt int userId, @NonNull String deviceMacAddress, @NonNull String packageName, @Nullable String deviceProfile) { final MacAddress macAddress = MacAddress.fromString(deviceMacAddress); createAssociation(userId, packageName, macAddress, null, deviceProfile, null, false); } AssociationInfo createAssociation(@UserIdInt int userId, @NonNull String packageName, void createNewAssociation(@UserIdInt int userId, @NonNull String packageName, @Nullable MacAddress macAddress, @Nullable CharSequence displayName, @Nullable String deviceProfile, @Nullable AssociatedDevice associatedDevice, boolean selfManaged) { final int id = getNewAssociationIdForPackage(userId, packageName); final long timestamp = System.currentTimeMillis(); final AssociationInfo association = new AssociationInfo(id, userId, packageName, macAddress, displayName, deviceProfile, associatedDevice, selfManaged, /* notifyOnDeviceNearby */ false, /* revoked */ false, timestamp, Long.MAX_VALUE); Slog.i(TAG, "New CDM association created=" + association); mAssociationStore.addAssociation(association); // If the "Device Profile" is specified, make the companion application a holder of the // corresponding role. if (deviceProfile != null) { addRoleHolderForAssociation(getContext(), association); } updateSpecialAccessPermissionForAssociatedPackage(association); logCreateAssociation(deviceProfile); // Don't need to update the mRevokedAssociationsPendingRoleHolderRemoval since // maybeRemoveRoleHolderForAssociation in PackageInactivityListener will handle the case // that there are other devices with the same profile, so the role holder won't be removed. return association; @Nullable String deviceProfile, boolean isSelfManaged) { mAssociationRequestsProcessor.createAssociation(userId, packageName, macAddress, displayName, deviceProfile, /* associatedDevice */ null, isSelfManaged, /* callback */ null, /* resultReceiver */ null); } @NonNull Loading Loading @@ -946,7 +911,7 @@ public class CompanionDeviceManagerService extends SystemService { return usedIdsForPackage; } private int getNewAssociationIdForPackage(@UserIdInt int userId, @NonNull String packageName) { int getNewAssociationIdForPackage(@UserIdInt int userId, @NonNull String packageName) { synchronized (mPreviouslyUsedIds) { // First: collect all IDs currently in use for this user's Associations. final SparseBooleanArray usedIds = new SparseBooleanArray(); Loading Loading @@ -1170,7 +1135,7 @@ public class CompanionDeviceManagerService extends SystemService { } } private void updateSpecialAccessPermissionForAssociatedPackage(AssociationInfo association) { void updateSpecialAccessPermissionForAssociatedPackage(AssociationInfo association) { final PackageInfo packageInfo = getPackageInfo(getContext(), association.getUserId(), association.getPackageName()); Loading services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java +4 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.companion; import android.companion.AssociationInfo; import android.net.MacAddress; import android.os.Binder; import android.os.ShellCommand; Loading Loading @@ -63,7 +64,9 @@ class CompanionDeviceShellCommand extends ShellCommand { int userId = getNextIntArgRequired(); String packageName = getNextArgRequired(); String address = getNextArgRequired(); mService.legacyCreateAssociation(userId, address, packageName, null); final MacAddress macAddress = MacAddress.fromString(address); mService.createNewAssociation(userId, packageName, macAddress, null, null, false); } break; Loading services/companion/java/com/android/server/companion/RolesUtils.java +4 −7 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.util.Log; import android.util.Slog; import java.util.List; import java.util.function.Consumer; /** Utility methods for accessing {@link RoleManager} APIs. */ @SuppressLint("LongLogTag") Loading @@ -46,7 +47,8 @@ final class RolesUtils { } static void addRoleHolderForAssociation( @NonNull Context context, @NonNull AssociationInfo associationInfo) { @NonNull Context context, @NonNull AssociationInfo associationInfo, @NonNull Consumer<Boolean> roleGrantResult) { if (DEBUG) { Log.d(TAG, "addRoleHolderForAssociation() associationInfo=" + associationInfo); } Loading @@ -62,12 +64,7 @@ final class RolesUtils { roleManager.addRoleHolderAsUser(deviceProfile, packageName, MANAGE_HOLDERS_FLAG_DONT_KILL_APP, userHandle, context.getMainExecutor(), success -> { if (!success) { Slog.e(TAG, "Failed to add u" + userId + "\\" + packageName + " to the list of " + deviceProfile + " holders."); } }); roleGrantResult); } static void removeRoleHolderForAssociation( Loading Loading
packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java +10 −15 Original line number Diff line number Diff line Loading @@ -363,13 +363,6 @@ public class CompanionDeviceActivity extends FragmentActivity implements mCdmServiceReceiver.send(RESULT_CODE_ASSOCIATION_APPROVED, data); } private void onAssociationCreated(@NonNull AssociationInfo association) { if (DEBUG) Log.i(TAG, "onAssociationCreated(), association=" + association); // Don't need to notify the app, CdmService has already done that. Just finish. setResultAndFinish(association, RESULT_OK); } private void cancel(boolean discoveryTimeout, boolean userRejected) { if (DEBUG) { Log.i(TAG, "cancel(), discoveryTimeout=" Loading Loading @@ -413,7 +406,9 @@ public class CompanionDeviceActivity extends FragmentActivity implements } private void setResultAndFinish(@Nullable AssociationInfo association, int resultCode) { if (DEBUG) Log.i(TAG, "setResultAndFinish(), association=" + association); Log.i(TAG, "setResultAndFinish(), association=" + (association == null ? "null" : association) + "resultCode=" + resultCode); final Intent data = new Intent(); if (association != null) { Loading Loading @@ -652,14 +647,14 @@ public class CompanionDeviceActivity extends FragmentActivity implements new ResultReceiver(Handler.getMain()) { @Override protected void onReceiveResult(int resultCode, Bundle data) { if (resultCode != RESULT_CODE_ASSOCIATION_CREATED) { throw new RuntimeException("Unknown result code: " + resultCode); } final AssociationInfo association = data.getParcelable(EXTRA_ASSOCIATION); if (resultCode == RESULT_CODE_ASSOCIATION_CREATED) { final AssociationInfo association = data.getParcelable( EXTRA_ASSOCIATION, AssociationInfo.class); requireNonNull(association); onAssociationCreated(association); setResultAndFinish(association, RESULT_OK); } else { setResultAndFinish(null, resultCode); } } }; Loading
services/companion/java/com/android/server/companion/AssociationRequestsProcessor.java +102 −22 Original line number Diff line number Diff line Loading @@ -23,8 +23,10 @@ import static android.companion.CompanionDeviceManager.COMPANION_DEVICE_DISCOVER import static android.content.ComponentName.createRelative; import static com.android.server.companion.CompanionDeviceManagerService.DEBUG; import static com.android.server.companion.MetricUtils.logCreateAssociation; import static com.android.server.companion.PackageUtils.enforceUsesCompanionDeviceFeature; import static com.android.server.companion.PermissionsUtils.enforcePermissionsForAssociation; import static com.android.server.companion.RolesUtils.addRoleHolderForAssociation; import static com.android.server.companion.RolesUtils.isRoleHolder; import static com.android.server.companion.Utils.prepareForIpc; Loading @@ -35,8 +37,10 @@ import android.annotation.Nullable; import android.annotation.SuppressLint; import android.annotation.UserIdInt; import android.app.PendingIntent; import android.companion.AssociatedDevice; import android.companion.AssociationInfo; import android.companion.AssociationRequest; import android.companion.CompanionDeviceManager; import android.companion.IAssociationRequestCallback; import android.content.ComponentName; import android.content.Context; Loading Loading @@ -87,7 +91,7 @@ import java.util.Set; * required. * * If the user's approval is NOT required: an {@link AssociationRequestsProcessor} invokes * {@link #createAssociationAndNotifyApplication(AssociationRequest, String, int, MacAddress, IAssociationRequestCallback)} * {@link #createAssociationAndNotifyApplication(AssociationRequest, String, int, MacAddress, IAssociationRequestCallback, ResultReceiver)} * which after calling to {@link CompanionDeviceManagerService} to create an association, notifies * the requester via * {@link android.companion.CompanionDeviceManager.Callback#onAssociationCreated(AssociationInfo)}. Loading @@ -99,7 +103,7 @@ import java.util.Set; * from the Approval UI in via {@link #mOnRequestConfirmationReceiver} and invokes * {@link #processAssociationRequestApproval(AssociationRequest, IAssociationRequestCallback, ResultReceiver, MacAddress)} * which one more time checks that the packages holds all necessary permissions before proceeding to * {@link #createAssociationAndNotifyApplication(AssociationRequest, String, int, MacAddress, IAssociationRequestCallback)}. * {@link #createAssociationAndNotifyApplication(AssociationRequest, String, int, MacAddress, IAssociationRequestCallback, ResultReceiver)}. * * @see #processNewAssociationRequest(AssociationRequest, String, int, IAssociationRequestCallback) * @see #processAssociationRequestApproval(AssociationRequest, IAssociationRequestCallback, Loading Loading @@ -132,10 +136,10 @@ class AssociationRequestsProcessor { private final @NonNull Context mContext; private final @NonNull CompanionDeviceManagerService mService; private final @NonNull PackageManagerInternal mPackageManager; private final @NonNull AssociationStore mAssociationStore; private final @NonNull AssociationStoreImpl mAssociationStore; AssociationRequestsProcessor(@NonNull CompanionDeviceManagerService service, @NonNull AssociationStore associationStore) { @NonNull AssociationStoreImpl associationStore) { mContext = service.getContext(); mService = service; mPackageManager = service.mPackageManagerInternal; Loading Loading @@ -174,7 +178,7 @@ class AssociationRequestsProcessor { && !willAddRoleHolder(request, packageName, userId)) { // 2a. Create association right away. createAssociationAndNotifyApplication(request, packageName, userId, /*macAddress*/ null, callback); /* macAddress */ null, callback, /* resultReceiver */ null); return; } Loading Loading @@ -253,34 +257,110 @@ class AssociationRequestsProcessor { } // 2. Create association and notify the application. final AssociationInfo association = createAssociationAndNotifyApplication( request, packageName, userId, macAddress, callback); // 3. Send the association back the Approval Activity, so that it can report back to the app // via Activity.setResult(). final Bundle data = new Bundle(); data.putParcelable(EXTRA_ASSOCIATION, association); resultReceiver.send(RESULT_CODE_ASSOCIATION_CREATED, data); createAssociationAndNotifyApplication(request, packageName, userId, macAddress, callback, resultReceiver); } private AssociationInfo createAssociationAndNotifyApplication( private void createAssociationAndNotifyApplication( @NonNull AssociationRequest request, @NonNull String packageName, @UserIdInt int userId, @Nullable MacAddress macAddress, @NonNull IAssociationRequestCallback callback) { final AssociationInfo association; @Nullable MacAddress macAddress, @NonNull IAssociationRequestCallback callback, @NonNull ResultReceiver resultReceiver) { final long callingIdentity = Binder.clearCallingIdentity(); try { association = mService.createAssociation(userId, packageName, macAddress, createAssociation(userId, packageName, macAddress, request.getDisplayName(), request.getDeviceProfile(), request.getAssociatedDevice(), request.isSelfManaged()); request.getAssociatedDevice(), request.isSelfManaged(), callback, resultReceiver); } finally { Binder.restoreCallingIdentity(callingIdentity); } } public void createAssociation(@UserIdInt int userId, @NonNull String packageName, @Nullable MacAddress macAddress, @Nullable CharSequence displayName, @Nullable String deviceProfile, @Nullable AssociatedDevice associatedDevice, boolean selfManaged, @Nullable IAssociationRequestCallback callback, @Nullable ResultReceiver resultReceiver) { final int id = mService.getNewAssociationIdForPackage(userId, packageName); final long timestamp = System.currentTimeMillis(); final AssociationInfo association = new AssociationInfo(id, userId, packageName, macAddress, displayName, deviceProfile, associatedDevice, selfManaged, /* notifyOnDeviceNearby */ false, /* revoked */ false, timestamp, Long.MAX_VALUE); if (deviceProfile != null) { // If the "Device Profile" is specified, make the companion application a holder of the // corresponding role. addRoleHolderForAssociation(mService.getContext(), association, success -> { if (success) { addAssociationToStore(association, deviceProfile); sendCallbackAndFinish(association, callback, resultReceiver); } else { Slog.e(TAG, "Failed to add u" + userId + "\\" + packageName + " to the list of " + deviceProfile + " holders."); sendCallbackAndFinish(null, callback, resultReceiver); } }); } else { addAssociationToStore(association, null); sendCallbackAndFinish(association, callback, resultReceiver); } // Don't need to update the mRevokedAssociationsPendingRoleHolderRemoval since // maybeRemoveRoleHolderForAssociation in PackageInactivityListener will handle the case // that there are other devices with the same profile, so the role holder won't be removed. } private void addAssociationToStore(@NonNull AssociationInfo association, @Nullable String deviceProfile) { Slog.i(TAG, "New CDM association created=" + association); mAssociationStore.addAssociation(association); mService.updateSpecialAccessPermissionForAssociatedPackage(association); logCreateAssociation(deviceProfile); } private void sendCallbackAndFinish(@Nullable AssociationInfo association, @Nullable IAssociationRequestCallback callback, @Nullable ResultReceiver resultReceiver) { if (association != null) { // Send the association back via the app's callback if (callback != null) { try { callback.onAssociationCreated(association); } catch (RemoteException ignore) { } } catch (RemoteException ignore) { } } return association; // Send the association back to CompanionDeviceActivity, so that it can report // back to the app via Activity.setResult(). if (resultReceiver != null) { final Bundle data = new Bundle(); data.putParcelable(EXTRA_ASSOCIATION, association); resultReceiver.send(RESULT_CODE_ASSOCIATION_CREATED, data); } } else { // Send the association back via the app's callback if (callback != null) { try { // TODO: update to INTERNAL_ERROR once it's added. callback.onFailure(CompanionDeviceManager.REASON_CANCELED); } catch (RemoteException ignore) { } } // Send the association back to CompanionDeviceActivity, so that it can report // back to the app via Activity.setResult(). if (resultReceiver != null) { final Bundle data = new Bundle(); resultReceiver.send(CompanionDeviceManager.RESULT_INTERNAL_ERROR, data); } } } private boolean willAddRoleHolder(@NonNull AssociationRequest request, Loading
services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +9 −44 Original line number Diff line number Diff line Loading @@ -28,7 +28,6 @@ import static com.android.internal.util.CollectionUtils.any; import static com.android.internal.util.Preconditions.checkState; import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage; import static com.android.server.companion.AssociationStore.CHANGE_TYPE_UPDATED_ADDRESS_UNCHANGED; import static com.android.server.companion.MetricUtils.logCreateAssociation; import static com.android.server.companion.MetricUtils.logRemoveAssociation; import static com.android.server.companion.PackageUtils.enforceUsesCompanionDeviceFeature; import static com.android.server.companion.PackageUtils.getPackageInfo; Loading @@ -38,7 +37,6 @@ import static com.android.server.companion.PermissionsUtils.enforceCallerCanMana import static com.android.server.companion.PermissionsUtils.enforceCallerIsSystemOr; import static com.android.server.companion.PermissionsUtils.enforceCallerIsSystemOrCanInteractWithUserId; import static com.android.server.companion.PermissionsUtils.sanitizeWithCallerChecks; import static com.android.server.companion.RolesUtils.addRoleHolderForAssociation; import static com.android.server.companion.RolesUtils.removeRoleHolderForAssociation; import static java.util.Objects.requireNonNull; Loading @@ -55,7 +53,6 @@ import android.app.ActivityManagerInternal; import android.app.AppOpsManager; import android.app.NotificationManager; import android.app.PendingIntent; import android.companion.AssociatedDevice; import android.companion.AssociationInfo; import android.companion.AssociationRequest; import android.companion.DeviceNotAssociatedException; Loading Loading @@ -819,7 +816,8 @@ public class CompanionDeviceManagerService extends SystemService { getContext().enforceCallingOrSelfPermission( android.Manifest.permission.ASSOCIATE_COMPANION_DEVICES, "createAssociation"); legacyCreateAssociation(userId, macAddress, packageName, null); final MacAddress macAddressObj = MacAddress.fromString(macAddress); createNewAssociation(userId, packageName, macAddressObj, null, null, false); } private void checkCanCallNotificationApi(String callingPackage) { Loading Loading @@ -871,45 +869,12 @@ public class CompanionDeviceManagerService extends SystemService { } } /** * @deprecated use * {@link #createAssociation(int, String, MacAddress, CharSequence, String, AssociatedDevice, * boolean)} */ @Deprecated void legacyCreateAssociation(@UserIdInt int userId, @NonNull String deviceMacAddress, @NonNull String packageName, @Nullable String deviceProfile) { final MacAddress macAddress = MacAddress.fromString(deviceMacAddress); createAssociation(userId, packageName, macAddress, null, deviceProfile, null, false); } AssociationInfo createAssociation(@UserIdInt int userId, @NonNull String packageName, void createNewAssociation(@UserIdInt int userId, @NonNull String packageName, @Nullable MacAddress macAddress, @Nullable CharSequence displayName, @Nullable String deviceProfile, @Nullable AssociatedDevice associatedDevice, boolean selfManaged) { final int id = getNewAssociationIdForPackage(userId, packageName); final long timestamp = System.currentTimeMillis(); final AssociationInfo association = new AssociationInfo(id, userId, packageName, macAddress, displayName, deviceProfile, associatedDevice, selfManaged, /* notifyOnDeviceNearby */ false, /* revoked */ false, timestamp, Long.MAX_VALUE); Slog.i(TAG, "New CDM association created=" + association); mAssociationStore.addAssociation(association); // If the "Device Profile" is specified, make the companion application a holder of the // corresponding role. if (deviceProfile != null) { addRoleHolderForAssociation(getContext(), association); } updateSpecialAccessPermissionForAssociatedPackage(association); logCreateAssociation(deviceProfile); // Don't need to update the mRevokedAssociationsPendingRoleHolderRemoval since // maybeRemoveRoleHolderForAssociation in PackageInactivityListener will handle the case // that there are other devices with the same profile, so the role holder won't be removed. return association; @Nullable String deviceProfile, boolean isSelfManaged) { mAssociationRequestsProcessor.createAssociation(userId, packageName, macAddress, displayName, deviceProfile, /* associatedDevice */ null, isSelfManaged, /* callback */ null, /* resultReceiver */ null); } @NonNull Loading Loading @@ -946,7 +911,7 @@ public class CompanionDeviceManagerService extends SystemService { return usedIdsForPackage; } private int getNewAssociationIdForPackage(@UserIdInt int userId, @NonNull String packageName) { int getNewAssociationIdForPackage(@UserIdInt int userId, @NonNull String packageName) { synchronized (mPreviouslyUsedIds) { // First: collect all IDs currently in use for this user's Associations. final SparseBooleanArray usedIds = new SparseBooleanArray(); Loading Loading @@ -1170,7 +1135,7 @@ public class CompanionDeviceManagerService extends SystemService { } } private void updateSpecialAccessPermissionForAssociatedPackage(AssociationInfo association) { void updateSpecialAccessPermissionForAssociatedPackage(AssociationInfo association) { final PackageInfo packageInfo = getPackageInfo(getContext(), association.getUserId(), association.getPackageName()); Loading
services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java +4 −1 Original line number Diff line number Diff line Loading @@ -17,6 +17,7 @@ package com.android.server.companion; import android.companion.AssociationInfo; import android.net.MacAddress; import android.os.Binder; import android.os.ShellCommand; Loading Loading @@ -63,7 +64,9 @@ class CompanionDeviceShellCommand extends ShellCommand { int userId = getNextIntArgRequired(); String packageName = getNextArgRequired(); String address = getNextArgRequired(); mService.legacyCreateAssociation(userId, address, packageName, null); final MacAddress macAddress = MacAddress.fromString(address); mService.createNewAssociation(userId, packageName, macAddress, null, null, false); } break; Loading
services/companion/java/com/android/server/companion/RolesUtils.java +4 −7 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import android.util.Log; import android.util.Slog; import java.util.List; import java.util.function.Consumer; /** Utility methods for accessing {@link RoleManager} APIs. */ @SuppressLint("LongLogTag") Loading @@ -46,7 +47,8 @@ final class RolesUtils { } static void addRoleHolderForAssociation( @NonNull Context context, @NonNull AssociationInfo associationInfo) { @NonNull Context context, @NonNull AssociationInfo associationInfo, @NonNull Consumer<Boolean> roleGrantResult) { if (DEBUG) { Log.d(TAG, "addRoleHolderForAssociation() associationInfo=" + associationInfo); } Loading @@ -62,12 +64,7 @@ final class RolesUtils { roleManager.addRoleHolderAsUser(deviceProfile, packageName, MANAGE_HOLDERS_FLAG_DONT_KILL_APP, userHandle, context.getMainExecutor(), success -> { if (!success) { Slog.e(TAG, "Failed to add u" + userId + "\\" + packageName + " to the list of " + deviceProfile + " holders."); } }); roleGrantResult); } static void removeRoleHolderForAssociation( Loading