Loading core/java/android/companion/CompanionDeviceManager.java +214 −48 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; Loading Loading @@ -80,25 +81,27 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; /** * System level service for managing companion devices * Public interfaces for managing companion devices. * * See <a href="{@docRoot}guide/topics/connectivity/companion-device-pairing">this guide</a> * for a usage example. * <p>The interfaces in this class allow companion apps to * {@link #associate(AssociationRequest, Executor, Callback)} discover and request device profiles} * for companion devices, {@link #startObservingDevicePresence(String) listen to device presence * events}, {@link #startSystemDataTransfer(int, Executor, OutcomeReceiver) transfer system level * data} via {@link #attachSystemDataTransport(int, InputStream, OutputStream) the reported * channel} and more.</p> * * <p>To obtain an instance call {@link Context#getSystemService}({@link * Context#COMPANION_DEVICE_SERVICE}) Then, call {@link #associate(AssociationRequest, * Callback, Handler)} to initiate the flow of associating current package with a * device selected by user.</p> * * @see CompanionDeviceManager#associate * @see AssociationRequest * <div class="special reference"> * <h3>Developer Guides</h3> * <p>For more information about managing companion devices, read the <a href= * "{@docRoot}guide/topics/connectivity/companion-device-pairing">Companion Device Pairing</a> * developer guide. * </div> */ @SuppressLint("LongLogTag") @SystemService(Context.COMPANION_DEVICE_SERVICE) @RequiresFeature(PackageManager.FEATURE_COMPANION_DEVICE_SETUP) public final class CompanionDeviceManager { private static final boolean DEBUG = false; private static final String LOG_TAG = "CDM_CompanionDeviceManager"; private static final String TAG = "CDM_CompanionDeviceManager"; /** @hide */ @IntDef(prefix = {"RESULT_"}, value = { Loading Loading @@ -374,7 +377,7 @@ public final class CompanionDeviceManager { } private final ICompanionDeviceManager mService; private Context mContext; private final Context mContext; @GuardedBy("mListeners") private final ArrayList<OnAssociationsChangedListenerProxy> mListeners = new ArrayList<>(); Loading Loading @@ -432,7 +435,11 @@ public final class CompanionDeviceManager { @NonNull AssociationRequest request, @NonNull Callback callback, @Nullable Handler handler) { if (!checkFeaturePresent()) return; if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Objects.requireNonNull(request, "Request cannot be null"); Objects.requireNonNull(callback, "Callback cannot be null"); handler = Handler.mainIfNull(handler); Loading Loading @@ -492,7 +499,11 @@ public final class CompanionDeviceManager { @NonNull AssociationRequest request, @NonNull Executor executor, @NonNull Callback callback) { if (!checkFeaturePresent()) return; if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Objects.requireNonNull(request, "Request cannot be null"); Objects.requireNonNull(executor, "Executor cannot be null"); Objects.requireNonNull(callback, "Callback cannot be null"); Loading Loading @@ -521,7 +532,10 @@ public final class CompanionDeviceManager { @UserHandleAware @Nullable public IntentSender buildAssociationCancellationIntent() { if (!checkFeaturePresent()) return null; if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return null; } try { PendingIntent pendingIntent = mService.buildAssociationCancellationIntent( Loading @@ -543,7 +557,8 @@ public final class CompanionDeviceManager { * @param flags system data types to be enabled. */ public void enableSystemDataSyncForTypes(int associationId, @DataSyncTypes int flags) { if (!checkFeaturePresent()) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Loading @@ -565,7 +580,8 @@ public final class CompanionDeviceManager { * @param flags system data types to be disabled. */ public void disableSystemDataSyncForTypes(int associationId, @DataSyncTypes int flags) { if (!checkFeaturePresent()) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Loading @@ -580,6 +596,11 @@ public final class CompanionDeviceManager { * @hide */ public void enablePermissionsSync(int associationId) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.enablePermissionsSync(associationId); } catch (RemoteException e) { Loading @@ -591,6 +612,11 @@ public final class CompanionDeviceManager { * @hide */ public void disablePermissionsSync(int associationId) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.disablePermissionsSync(associationId); } catch (RemoteException e) { Loading @@ -602,6 +628,11 @@ public final class CompanionDeviceManager { * @hide */ public PermissionSyncRequest getPermissionSyncRequest(int associationId) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return null; } try { return mService.getPermissionSyncRequest(associationId); } catch (RemoteException e) { Loading Loading @@ -636,7 +667,10 @@ public final class CompanionDeviceManager { @UserHandleAware @NonNull public List<AssociationInfo> getMyAssociations() { if (!checkFeaturePresent()) return Collections.emptyList(); if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return Collections.emptyList(); } try { return mService.getAssociations(mContext.getOpPackageName(), mContext.getUserId()); Loading Loading @@ -665,7 +699,10 @@ public final class CompanionDeviceManager { @UserHandleAware @Deprecated public void disassociate(@NonNull String deviceMacAddress) { if (!checkFeaturePresent()) return; if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.legacyDisassociate(deviceMacAddress, mContext.getOpPackageName(), Loading @@ -690,7 +727,10 @@ public final class CompanionDeviceManager { */ @UserHandleAware public void disassociate(int associationId) { if (!checkFeaturePresent()) return; if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.disassociate(associationId); Loading @@ -716,9 +756,11 @@ public final class CompanionDeviceManager { */ @UserHandleAware public void requestNotificationAccess(ComponentName component) { if (!checkFeaturePresent()) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { PendingIntent pendingIntent = mService.requestNotificationAccess( component, mContext.getUserId()); Loading Loading @@ -755,9 +797,11 @@ public final class CompanionDeviceManager { */ @Deprecated public boolean hasNotificationAccess(ComponentName component) { if (!checkFeaturePresent()) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return false; } try { return mService.hasNotificationAccess(component); } catch (RemoteException e) { Loading Loading @@ -793,7 +837,11 @@ public final class CompanionDeviceManager { @NonNull String packageName, @NonNull MacAddress macAddress, @NonNull UserHandle user) { if (!checkFeaturePresent()) return false; if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return false; } Objects.requireNonNull(packageName, "package name cannot be null"); Objects.requireNonNull(macAddress, "mac address cannot be null"); Objects.requireNonNull(user, "user cannot be null"); Loading @@ -816,7 +864,8 @@ public final class CompanionDeviceManager { @SystemApi @UserHandleAware @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES) public @NonNull List<AssociationInfo> getAllAssociations() { @NonNull public List<AssociationInfo> getAllAssociations() { return getAllAssociations(mContext.getUserId()); } Loading @@ -826,8 +875,13 @@ public final class CompanionDeviceManager { * @hide */ @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES) public @NonNull List<AssociationInfo> getAllAssociations(@UserIdInt int userId) { if (!checkFeaturePresent()) return Collections.emptyList(); @NonNull public List<AssociationInfo> getAllAssociations(@UserIdInt int userId) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return Collections.emptyList(); } try { return mService.getAllAssociationsForUser(userId); } catch (RemoteException e) { Loading Loading @@ -875,7 +929,11 @@ public final class CompanionDeviceManager { public void addOnAssociationsChangedListener( @NonNull Executor executor, @NonNull OnAssociationsChangedListener listener, @UserIdInt int userId) { if (!checkFeaturePresent()) return; if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } synchronized (mListeners) { final OnAssociationsChangedListenerProxy proxy = new OnAssociationsChangedListenerProxy( executor, listener); Loading @@ -899,7 +957,11 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES) public void removeOnAssociationsChangedListener( @NonNull OnAssociationsChangedListener listener) { if (!checkFeaturePresent()) return; if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } synchronized (mListeners) { final Iterator<OnAssociationsChangedListenerProxy> iterator = mListeners.iterator(); while (iterator.hasNext()) { Loading Loading @@ -931,6 +993,11 @@ public final class CompanionDeviceManager { public void addOnTransportsChangedListener( @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<List<AssociationInfo>> listener) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } final OnTransportsChangedListenerProxy proxy = new OnTransportsChangedListenerProxy( executor, listener); try { Loading @@ -950,6 +1017,11 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void removeOnTransportsChangedListener( @NonNull Consumer<List<AssociationInfo>> listener) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } final OnTransportsChangedListenerProxy proxy = new OnTransportsChangedListenerProxy( null, listener); try { Loading @@ -969,6 +1041,11 @@ public final class CompanionDeviceManager { */ @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void sendMessage(int messageType, @NonNull byte[] data, @NonNull int[] associationIds) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.sendMessage(messageType, data, associationIds); } catch (RemoteException e) { Loading @@ -989,6 +1066,11 @@ public final class CompanionDeviceManager { public void addOnMessageReceivedListener( @NonNull @CallbackExecutor Executor executor, int messageType, @NonNull BiConsumer<Integer, byte[]> listener) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } final OnMessageReceivedListenerProxy proxy = new OnMessageReceivedListenerProxy( executor, listener); try { Loading @@ -1006,6 +1088,11 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void removeOnMessageReceivedListener(int messageType, @NonNull BiConsumer<Integer, byte[]> listener) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } final OnMessageReceivedListenerProxy proxy = new OnMessageReceivedListenerProxy( null, listener); try { Loading @@ -1031,9 +1118,11 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES) public boolean canPairWithoutPrompt(@NonNull String packageName, @NonNull String deviceMacAddress, @NonNull UserHandle user) { if (!checkFeaturePresent()) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return false; } Objects.requireNonNull(packageName, "package name cannot be null"); Objects.requireNonNull(deviceMacAddress, "device mac address cannot be null"); Objects.requireNonNull(user, "user handle cannot be null"); Loading Loading @@ -1081,9 +1170,11 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void startObservingDevicePresence(@NonNull String deviceAddress) throws DeviceNotAssociatedException { if (!checkFeaturePresent()) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Objects.requireNonNull(deviceAddress, "address cannot be null"); try { mService.legacyStartObservingDevicePresence(deviceAddress, Loading Loading @@ -1123,9 +1214,11 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void stopObservingDevicePresence(@NonNull String deviceAddress) throws DeviceNotAssociatedException { if (!checkFeaturePresent()) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Objects.requireNonNull(deviceAddress, "address cannot be null"); try { mService.legacyStopObservingDevicePresence(deviceAddress, Loading Loading @@ -1171,6 +1264,11 @@ public final class CompanionDeviceManager { @FlaggedApi(Flags.FLAG_DEVICE_PRESENCE) @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void startObservingDevicePresence(@NonNull ObservingDevicePresenceRequest request) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Objects.requireNonNull(request, "request cannot be null"); try { Loading @@ -1192,6 +1290,11 @@ public final class CompanionDeviceManager { @FlaggedApi(Flags.FLAG_DEVICE_PRESENCE) @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void stopObservingDevicePresence(@NonNull ObservingDevicePresenceRequest request) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Objects.requireNonNull(request, "request cannot be null"); try { Loading Loading @@ -1222,7 +1325,7 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.DELIVER_COMPANION_MESSAGES) public void dispatchMessage(int messageId, int associationId, @NonNull byte[] message) throws DeviceNotAssociatedException { Log.w(LOG_TAG, "dispatchMessage replaced by attachSystemDataTransport"); Log.w(TAG, "dispatchMessage replaced by attachSystemDataTransport"); } /** Loading @@ -1244,6 +1347,11 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.DELIVER_COMPANION_MESSAGES) public void attachSystemDataTransport(int associationId, @NonNull InputStream in, @NonNull OutputStream out) throws DeviceNotAssociatedException { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } synchronized (mTransports) { if (mTransports.contains(associationId)) { detachSystemDataTransport(associationId); Loading Loading @@ -1272,6 +1380,11 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.DELIVER_COMPANION_MESSAGES) public void detachSystemDataTransport(int associationId) throws DeviceNotAssociatedException { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } synchronized (mTransports) { final Transport transport = mTransports.get(associationId); if (transport != null) { Loading @@ -1296,9 +1409,11 @@ public final class CompanionDeviceManager { @NonNull String packageName, @NonNull MacAddress macAddress, @NonNull byte[] certificate) { if (!checkFeaturePresent()) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Objects.requireNonNull(packageName, "package name cannot be null"); Objects.requireNonNull(macAddress, "mac address cannot be null"); Loading Loading @@ -1327,6 +1442,11 @@ public final class CompanionDeviceManager { @SystemApi @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED) public void notifyDeviceAppeared(int associationId) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.notifySelfManagedDeviceAppeared(associationId); } catch (RemoteException e) { Loading @@ -1349,6 +1469,11 @@ public final class CompanionDeviceManager { @SystemApi @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED) public void notifyDeviceDisappeared(int associationId) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.notifySelfManagedDeviceDisappeared(associationId); } catch (RemoteException e) { Loading Loading @@ -1384,6 +1509,11 @@ public final class CompanionDeviceManager { @Nullable public IntentSender buildPermissionTransferUserConsentIntent(int associationId) throws DeviceNotAssociatedException { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return null; } try { PendingIntent pendingIntent = mService.buildPermissionTransferUserConsentIntent( mContext.getOpPackageName(), Loading Loading @@ -1420,6 +1550,11 @@ public final class CompanionDeviceManager { @UserHandleAware @FlaggedApi(Flags.FLAG_PERM_SYNC_USER_CONSENT) public boolean isPermissionTransferUserConsented(int associationId) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return false; } try { return mService.isPermissionTransferUserConsented(mContext.getOpPackageName(), mContext.getUserId(), associationId); Loading @@ -1446,6 +1581,11 @@ public final class CompanionDeviceManager { @Deprecated @UserHandleAware public void startSystemDataTransfer(int associationId) throws DeviceNotAssociatedException { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.startSystemDataTransfer(mContext.getOpPackageName(), mContext.getUserId(), associationId, null); Loading Loading @@ -1478,6 +1618,11 @@ public final class CompanionDeviceManager { @NonNull Executor executor, @NonNull OutcomeReceiver<Void, CompanionException> result) throws DeviceNotAssociatedException { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.startSystemDataTransfer(mContext.getOpPackageName(), mContext.getUserId(), associationId, new SystemDataTransferCallbackProxy(executor, result)); Loading @@ -1495,6 +1640,11 @@ public final class CompanionDeviceManager { */ @UserHandleAware public boolean isCompanionApplicationBound() { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return false; } try { return mService.isCompanionApplicationBound( mContext.getOpPackageName(), mContext.getUserId()); Loading @@ -1513,6 +1663,11 @@ public final class CompanionDeviceManager { @TestApi @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES) public void enableSecureTransport(boolean enabled) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.enableSecureTransport(enabled); } catch (RemoteException e) { Loading @@ -1534,6 +1689,11 @@ public final class CompanionDeviceManager { @FlaggedApi(Flags.FLAG_ASSOCIATION_TAG) @UserHandleAware public void setAssociationTag(int associationId, @NonNull String tag) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Objects.requireNonNull(tag, "tag cannot be null"); if (tag.length() > ASSOCIATION_TAG_LENGTH_LIMIT) { Loading @@ -1560,6 +1720,11 @@ public final class CompanionDeviceManager { @FlaggedApi(Flags.FLAG_ASSOCIATION_TAG) @UserHandleAware public void clearAssociationTag(int associationId) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.clearAssociationTag(associationId); } catch (RemoteException e) { Loading @@ -1567,15 +1732,6 @@ public final class CompanionDeviceManager { } } private boolean checkFeaturePresent() { boolean featurePresent = mService != null; if (!featurePresent && DEBUG) { Log.d(LOG_TAG, "Feature " + PackageManager.FEATURE_COMPANION_DEVICE_SETUP + " not available"); } return featurePresent; } private static class AssociationRequestCallbackProxy extends IAssociationRequestCallback.Stub { private final Handler mHandler; private final Callback mCallback; Loading Loading @@ -1613,7 +1769,7 @@ public final class CompanionDeviceManager { private <T> void execute(Consumer<T> callback, T arg) { if (mExecutor != null) { mExecutor.execute(() -> callback.accept(arg)); } else { } else if (mHandler != null) { mHandler.post(() -> callback.accept(arg)); } } Loading Loading @@ -1716,6 +1872,11 @@ public final class CompanionDeviceManager { } public void start() throws IOException { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } final ParcelFileDescriptor[] pair = ParcelFileDescriptor.createSocketPair(); final ParcelFileDescriptor localFd = pair[0]; final ParcelFileDescriptor remoteFd = pair[1]; Loading @@ -1734,7 +1895,7 @@ public final class CompanionDeviceManager { copyWithFlushing(mLocalIn, mRemoteOut); } catch (IOException e) { if (!mStopped) { Log.w(LOG_TAG, "Trouble during outgoing transport", e); Log.w(TAG, "Trouble during outgoing transport", e); stop(); } } Loading @@ -1744,7 +1905,7 @@ public final class CompanionDeviceManager { copyWithFlushing(mRemoteIn, mLocalOut); } catch (IOException e) { if (!mStopped) { Log.w(LOG_TAG, "Trouble during incoming transport", e); Log.w(TAG, "Trouble during incoming transport", e); stop(); } } Loading @@ -1752,13 +1913,18 @@ public final class CompanionDeviceManager { } public void stop() { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } mStopped = true; try { mService.detachSystemDataTransport(mContext.getPackageName(), mContext.getUserId(), mAssociationId); } catch (RemoteException e) { Log.w(LOG_TAG, "Failed to detach transport", e); Log.w(TAG, "Failed to detach transport", e); } IoUtils.closeQuietly(mRemoteIn); Loading services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +4 −13 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
core/java/android/companion/CompanionDeviceManager.java +214 −48 Original line number Diff line number Diff line Loading @@ -26,6 +26,7 @@ import android.annotation.FlaggedApi; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.RequiresFeature; import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; Loading Loading @@ -80,25 +81,27 @@ import java.util.function.BiConsumer; import java.util.function.Consumer; /** * System level service for managing companion devices * Public interfaces for managing companion devices. * * See <a href="{@docRoot}guide/topics/connectivity/companion-device-pairing">this guide</a> * for a usage example. * <p>The interfaces in this class allow companion apps to * {@link #associate(AssociationRequest, Executor, Callback)} discover and request device profiles} * for companion devices, {@link #startObservingDevicePresence(String) listen to device presence * events}, {@link #startSystemDataTransfer(int, Executor, OutcomeReceiver) transfer system level * data} via {@link #attachSystemDataTransport(int, InputStream, OutputStream) the reported * channel} and more.</p> * * <p>To obtain an instance call {@link Context#getSystemService}({@link * Context#COMPANION_DEVICE_SERVICE}) Then, call {@link #associate(AssociationRequest, * Callback, Handler)} to initiate the flow of associating current package with a * device selected by user.</p> * * @see CompanionDeviceManager#associate * @see AssociationRequest * <div class="special reference"> * <h3>Developer Guides</h3> * <p>For more information about managing companion devices, read the <a href= * "{@docRoot}guide/topics/connectivity/companion-device-pairing">Companion Device Pairing</a> * developer guide. * </div> */ @SuppressLint("LongLogTag") @SystemService(Context.COMPANION_DEVICE_SERVICE) @RequiresFeature(PackageManager.FEATURE_COMPANION_DEVICE_SETUP) public final class CompanionDeviceManager { private static final boolean DEBUG = false; private static final String LOG_TAG = "CDM_CompanionDeviceManager"; private static final String TAG = "CDM_CompanionDeviceManager"; /** @hide */ @IntDef(prefix = {"RESULT_"}, value = { Loading Loading @@ -374,7 +377,7 @@ public final class CompanionDeviceManager { } private final ICompanionDeviceManager mService; private Context mContext; private final Context mContext; @GuardedBy("mListeners") private final ArrayList<OnAssociationsChangedListenerProxy> mListeners = new ArrayList<>(); Loading Loading @@ -432,7 +435,11 @@ public final class CompanionDeviceManager { @NonNull AssociationRequest request, @NonNull Callback callback, @Nullable Handler handler) { if (!checkFeaturePresent()) return; if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Objects.requireNonNull(request, "Request cannot be null"); Objects.requireNonNull(callback, "Callback cannot be null"); handler = Handler.mainIfNull(handler); Loading Loading @@ -492,7 +499,11 @@ public final class CompanionDeviceManager { @NonNull AssociationRequest request, @NonNull Executor executor, @NonNull Callback callback) { if (!checkFeaturePresent()) return; if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Objects.requireNonNull(request, "Request cannot be null"); Objects.requireNonNull(executor, "Executor cannot be null"); Objects.requireNonNull(callback, "Callback cannot be null"); Loading Loading @@ -521,7 +532,10 @@ public final class CompanionDeviceManager { @UserHandleAware @Nullable public IntentSender buildAssociationCancellationIntent() { if (!checkFeaturePresent()) return null; if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return null; } try { PendingIntent pendingIntent = mService.buildAssociationCancellationIntent( Loading @@ -543,7 +557,8 @@ public final class CompanionDeviceManager { * @param flags system data types to be enabled. */ public void enableSystemDataSyncForTypes(int associationId, @DataSyncTypes int flags) { if (!checkFeaturePresent()) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Loading @@ -565,7 +580,8 @@ public final class CompanionDeviceManager { * @param flags system data types to be disabled. */ public void disableSystemDataSyncForTypes(int associationId, @DataSyncTypes int flags) { if (!checkFeaturePresent()) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Loading @@ -580,6 +596,11 @@ public final class CompanionDeviceManager { * @hide */ public void enablePermissionsSync(int associationId) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.enablePermissionsSync(associationId); } catch (RemoteException e) { Loading @@ -591,6 +612,11 @@ public final class CompanionDeviceManager { * @hide */ public void disablePermissionsSync(int associationId) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.disablePermissionsSync(associationId); } catch (RemoteException e) { Loading @@ -602,6 +628,11 @@ public final class CompanionDeviceManager { * @hide */ public PermissionSyncRequest getPermissionSyncRequest(int associationId) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return null; } try { return mService.getPermissionSyncRequest(associationId); } catch (RemoteException e) { Loading Loading @@ -636,7 +667,10 @@ public final class CompanionDeviceManager { @UserHandleAware @NonNull public List<AssociationInfo> getMyAssociations() { if (!checkFeaturePresent()) return Collections.emptyList(); if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return Collections.emptyList(); } try { return mService.getAssociations(mContext.getOpPackageName(), mContext.getUserId()); Loading Loading @@ -665,7 +699,10 @@ public final class CompanionDeviceManager { @UserHandleAware @Deprecated public void disassociate(@NonNull String deviceMacAddress) { if (!checkFeaturePresent()) return; if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.legacyDisassociate(deviceMacAddress, mContext.getOpPackageName(), Loading @@ -690,7 +727,10 @@ public final class CompanionDeviceManager { */ @UserHandleAware public void disassociate(int associationId) { if (!checkFeaturePresent()) return; if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.disassociate(associationId); Loading @@ -716,9 +756,11 @@ public final class CompanionDeviceManager { */ @UserHandleAware public void requestNotificationAccess(ComponentName component) { if (!checkFeaturePresent()) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { PendingIntent pendingIntent = mService.requestNotificationAccess( component, mContext.getUserId()); Loading Loading @@ -755,9 +797,11 @@ public final class CompanionDeviceManager { */ @Deprecated public boolean hasNotificationAccess(ComponentName component) { if (!checkFeaturePresent()) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return false; } try { return mService.hasNotificationAccess(component); } catch (RemoteException e) { Loading Loading @@ -793,7 +837,11 @@ public final class CompanionDeviceManager { @NonNull String packageName, @NonNull MacAddress macAddress, @NonNull UserHandle user) { if (!checkFeaturePresent()) return false; if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return false; } Objects.requireNonNull(packageName, "package name cannot be null"); Objects.requireNonNull(macAddress, "mac address cannot be null"); Objects.requireNonNull(user, "user cannot be null"); Loading @@ -816,7 +864,8 @@ public final class CompanionDeviceManager { @SystemApi @UserHandleAware @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES) public @NonNull List<AssociationInfo> getAllAssociations() { @NonNull public List<AssociationInfo> getAllAssociations() { return getAllAssociations(mContext.getUserId()); } Loading @@ -826,8 +875,13 @@ public final class CompanionDeviceManager { * @hide */ @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES) public @NonNull List<AssociationInfo> getAllAssociations(@UserIdInt int userId) { if (!checkFeaturePresent()) return Collections.emptyList(); @NonNull public List<AssociationInfo> getAllAssociations(@UserIdInt int userId) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return Collections.emptyList(); } try { return mService.getAllAssociationsForUser(userId); } catch (RemoteException e) { Loading Loading @@ -875,7 +929,11 @@ public final class CompanionDeviceManager { public void addOnAssociationsChangedListener( @NonNull Executor executor, @NonNull OnAssociationsChangedListener listener, @UserIdInt int userId) { if (!checkFeaturePresent()) return; if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } synchronized (mListeners) { final OnAssociationsChangedListenerProxy proxy = new OnAssociationsChangedListenerProxy( executor, listener); Loading @@ -899,7 +957,11 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES) public void removeOnAssociationsChangedListener( @NonNull OnAssociationsChangedListener listener) { if (!checkFeaturePresent()) return; if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } synchronized (mListeners) { final Iterator<OnAssociationsChangedListenerProxy> iterator = mListeners.iterator(); while (iterator.hasNext()) { Loading Loading @@ -931,6 +993,11 @@ public final class CompanionDeviceManager { public void addOnTransportsChangedListener( @NonNull @CallbackExecutor Executor executor, @NonNull Consumer<List<AssociationInfo>> listener) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } final OnTransportsChangedListenerProxy proxy = new OnTransportsChangedListenerProxy( executor, listener); try { Loading @@ -950,6 +1017,11 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void removeOnTransportsChangedListener( @NonNull Consumer<List<AssociationInfo>> listener) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } final OnTransportsChangedListenerProxy proxy = new OnTransportsChangedListenerProxy( null, listener); try { Loading @@ -969,6 +1041,11 @@ public final class CompanionDeviceManager { */ @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void sendMessage(int messageType, @NonNull byte[] data, @NonNull int[] associationIds) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.sendMessage(messageType, data, associationIds); } catch (RemoteException e) { Loading @@ -989,6 +1066,11 @@ public final class CompanionDeviceManager { public void addOnMessageReceivedListener( @NonNull @CallbackExecutor Executor executor, int messageType, @NonNull BiConsumer<Integer, byte[]> listener) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } final OnMessageReceivedListenerProxy proxy = new OnMessageReceivedListenerProxy( executor, listener); try { Loading @@ -1006,6 +1088,11 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void removeOnMessageReceivedListener(int messageType, @NonNull BiConsumer<Integer, byte[]> listener) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } final OnMessageReceivedListenerProxy proxy = new OnMessageReceivedListenerProxy( null, listener); try { Loading @@ -1031,9 +1118,11 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES) public boolean canPairWithoutPrompt(@NonNull String packageName, @NonNull String deviceMacAddress, @NonNull UserHandle user) { if (!checkFeaturePresent()) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return false; } Objects.requireNonNull(packageName, "package name cannot be null"); Objects.requireNonNull(deviceMacAddress, "device mac address cannot be null"); Objects.requireNonNull(user, "user handle cannot be null"); Loading Loading @@ -1081,9 +1170,11 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void startObservingDevicePresence(@NonNull String deviceAddress) throws DeviceNotAssociatedException { if (!checkFeaturePresent()) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Objects.requireNonNull(deviceAddress, "address cannot be null"); try { mService.legacyStartObservingDevicePresence(deviceAddress, Loading Loading @@ -1123,9 +1214,11 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void stopObservingDevicePresence(@NonNull String deviceAddress) throws DeviceNotAssociatedException { if (!checkFeaturePresent()) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Objects.requireNonNull(deviceAddress, "address cannot be null"); try { mService.legacyStopObservingDevicePresence(deviceAddress, Loading Loading @@ -1171,6 +1264,11 @@ public final class CompanionDeviceManager { @FlaggedApi(Flags.FLAG_DEVICE_PRESENCE) @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void startObservingDevicePresence(@NonNull ObservingDevicePresenceRequest request) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Objects.requireNonNull(request, "request cannot be null"); try { Loading @@ -1192,6 +1290,11 @@ public final class CompanionDeviceManager { @FlaggedApi(Flags.FLAG_DEVICE_PRESENCE) @RequiresPermission(android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE) public void stopObservingDevicePresence(@NonNull ObservingDevicePresenceRequest request) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Objects.requireNonNull(request, "request cannot be null"); try { Loading Loading @@ -1222,7 +1325,7 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.DELIVER_COMPANION_MESSAGES) public void dispatchMessage(int messageId, int associationId, @NonNull byte[] message) throws DeviceNotAssociatedException { Log.w(LOG_TAG, "dispatchMessage replaced by attachSystemDataTransport"); Log.w(TAG, "dispatchMessage replaced by attachSystemDataTransport"); } /** Loading @@ -1244,6 +1347,11 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.DELIVER_COMPANION_MESSAGES) public void attachSystemDataTransport(int associationId, @NonNull InputStream in, @NonNull OutputStream out) throws DeviceNotAssociatedException { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } synchronized (mTransports) { if (mTransports.contains(associationId)) { detachSystemDataTransport(associationId); Loading Loading @@ -1272,6 +1380,11 @@ public final class CompanionDeviceManager { @RequiresPermission(android.Manifest.permission.DELIVER_COMPANION_MESSAGES) public void detachSystemDataTransport(int associationId) throws DeviceNotAssociatedException { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } synchronized (mTransports) { final Transport transport = mTransports.get(associationId); if (transport != null) { Loading @@ -1296,9 +1409,11 @@ public final class CompanionDeviceManager { @NonNull String packageName, @NonNull MacAddress macAddress, @NonNull byte[] certificate) { if (!checkFeaturePresent()) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Objects.requireNonNull(packageName, "package name cannot be null"); Objects.requireNonNull(macAddress, "mac address cannot be null"); Loading Loading @@ -1327,6 +1442,11 @@ public final class CompanionDeviceManager { @SystemApi @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED) public void notifyDeviceAppeared(int associationId) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.notifySelfManagedDeviceAppeared(associationId); } catch (RemoteException e) { Loading @@ -1349,6 +1469,11 @@ public final class CompanionDeviceManager { @SystemApi @RequiresPermission(android.Manifest.permission.REQUEST_COMPANION_SELF_MANAGED) public void notifyDeviceDisappeared(int associationId) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.notifySelfManagedDeviceDisappeared(associationId); } catch (RemoteException e) { Loading Loading @@ -1384,6 +1509,11 @@ public final class CompanionDeviceManager { @Nullable public IntentSender buildPermissionTransferUserConsentIntent(int associationId) throws DeviceNotAssociatedException { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return null; } try { PendingIntent pendingIntent = mService.buildPermissionTransferUserConsentIntent( mContext.getOpPackageName(), Loading Loading @@ -1420,6 +1550,11 @@ public final class CompanionDeviceManager { @UserHandleAware @FlaggedApi(Flags.FLAG_PERM_SYNC_USER_CONSENT) public boolean isPermissionTransferUserConsented(int associationId) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return false; } try { return mService.isPermissionTransferUserConsented(mContext.getOpPackageName(), mContext.getUserId(), associationId); Loading @@ -1446,6 +1581,11 @@ public final class CompanionDeviceManager { @Deprecated @UserHandleAware public void startSystemDataTransfer(int associationId) throws DeviceNotAssociatedException { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.startSystemDataTransfer(mContext.getOpPackageName(), mContext.getUserId(), associationId, null); Loading Loading @@ -1478,6 +1618,11 @@ public final class CompanionDeviceManager { @NonNull Executor executor, @NonNull OutcomeReceiver<Void, CompanionException> result) throws DeviceNotAssociatedException { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.startSystemDataTransfer(mContext.getOpPackageName(), mContext.getUserId(), associationId, new SystemDataTransferCallbackProxy(executor, result)); Loading @@ -1495,6 +1640,11 @@ public final class CompanionDeviceManager { */ @UserHandleAware public boolean isCompanionApplicationBound() { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return false; } try { return mService.isCompanionApplicationBound( mContext.getOpPackageName(), mContext.getUserId()); Loading @@ -1513,6 +1663,11 @@ public final class CompanionDeviceManager { @TestApi @RequiresPermission(android.Manifest.permission.MANAGE_COMPANION_DEVICES) public void enableSecureTransport(boolean enabled) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.enableSecureTransport(enabled); } catch (RemoteException e) { Loading @@ -1534,6 +1689,11 @@ public final class CompanionDeviceManager { @FlaggedApi(Flags.FLAG_ASSOCIATION_TAG) @UserHandleAware public void setAssociationTag(int associationId, @NonNull String tag) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } Objects.requireNonNull(tag, "tag cannot be null"); if (tag.length() > ASSOCIATION_TAG_LENGTH_LIMIT) { Loading @@ -1560,6 +1720,11 @@ public final class CompanionDeviceManager { @FlaggedApi(Flags.FLAG_ASSOCIATION_TAG) @UserHandleAware public void clearAssociationTag(int associationId) { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } try { mService.clearAssociationTag(associationId); } catch (RemoteException e) { Loading @@ -1567,15 +1732,6 @@ public final class CompanionDeviceManager { } } private boolean checkFeaturePresent() { boolean featurePresent = mService != null; if (!featurePresent && DEBUG) { Log.d(LOG_TAG, "Feature " + PackageManager.FEATURE_COMPANION_DEVICE_SETUP + " not available"); } return featurePresent; } private static class AssociationRequestCallbackProxy extends IAssociationRequestCallback.Stub { private final Handler mHandler; private final Callback mCallback; Loading Loading @@ -1613,7 +1769,7 @@ public final class CompanionDeviceManager { private <T> void execute(Consumer<T> callback, T arg) { if (mExecutor != null) { mExecutor.execute(() -> callback.accept(arg)); } else { } else if (mHandler != null) { mHandler.post(() -> callback.accept(arg)); } } Loading Loading @@ -1716,6 +1872,11 @@ public final class CompanionDeviceManager { } public void start() throws IOException { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } final ParcelFileDescriptor[] pair = ParcelFileDescriptor.createSocketPair(); final ParcelFileDescriptor localFd = pair[0]; final ParcelFileDescriptor remoteFd = pair[1]; Loading @@ -1734,7 +1895,7 @@ public final class CompanionDeviceManager { copyWithFlushing(mLocalIn, mRemoteOut); } catch (IOException e) { if (!mStopped) { Log.w(LOG_TAG, "Trouble during outgoing transport", e); Log.w(TAG, "Trouble during outgoing transport", e); stop(); } } Loading @@ -1744,7 +1905,7 @@ public final class CompanionDeviceManager { copyWithFlushing(mRemoteIn, mLocalOut); } catch (IOException e) { if (!mStopped) { Log.w(LOG_TAG, "Trouble during incoming transport", e); Log.w(TAG, "Trouble during incoming transport", e); stop(); } } Loading @@ -1752,13 +1913,18 @@ public final class CompanionDeviceManager { } public void stop() { if (mService == null) { Log.w(TAG, "CompanionDeviceManager service is not available."); return; } mStopped = true; try { mService.detachSystemDataTransport(mContext.getPackageName(), mContext.getUserId(), mAssociationId); } catch (RemoteException e) { Log.w(LOG_TAG, "Failed to detach transport", e); Log.w(TAG, "Failed to detach transport", e); } IoUtils.closeQuietly(mRemoteIn); Loading
services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +4 −13 File changed.Preview size limit exceeded, changes collapsed. Show changes