diff options
12 files changed, 147 insertions, 39 deletions
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt index 7cfa1e377933..b1feb419ecde 100644 --- a/core/api/module-lib-current.txt +++ b/core/api/module-lib-current.txt @@ -6,6 +6,7 @@ package android { field public static final String CONTROL_AUTOMOTIVE_GNSS = "android.permission.CONTROL_AUTOMOTIVE_GNSS"; field public static final String GET_INTENT_SENDER_INTENT = "android.permission.GET_INTENT_SENDER_INTENT"; field public static final String MAKE_UID_VISIBLE = "android.permission.MAKE_UID_VISIBLE"; + field public static final String USE_COMPANION_TRANSPORTS = "android.permission.USE_COMPANION_TRANSPORTS"; } } @@ -81,6 +82,29 @@ package android.app.admin { } +package android.companion { + + public final class CompanionDeviceManager { + method @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void addOnMessageReceivedListener(@NonNull java.util.concurrent.Executor, int, @NonNull android.companion.CompanionDeviceManager.OnMessageReceivedListener); + method @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void addOnTransportsChangedListener(@NonNull java.util.concurrent.Executor, @NonNull android.companion.CompanionDeviceManager.OnTransportsChangedListener); + method @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void removeOnMessageReceivedListener(int, @NonNull android.companion.CompanionDeviceManager.OnMessageReceivedListener); + method @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void removeOnTransportsChangedListener(@NonNull android.companion.CompanionDeviceManager.OnTransportsChangedListener); + method @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void sendMessage(int, @NonNull byte[], @NonNull int[]); + field public static final int MESSAGE_REQUEST_CONTEXT_SYNC = 1667729539; // 0x63678883 + field public static final int MESSAGE_REQUEST_PERMISSION_RESTORE = 1669491075; // 0x63826983 + field public static final int MESSAGE_REQUEST_REMOTE_AUTHENTICATION = 1669494629; // 0x63827765 + } + + public static interface CompanionDeviceManager.OnMessageReceivedListener { + method public void onMessageReceived(int, @NonNull byte[]); + } + + public static interface CompanionDeviceManager.OnTransportsChangedListener { + method public void onTransportsChanged(@NonNull java.util.List<android.companion.AssociationInfo>); + } + +} + package android.content { public abstract class ContentProvider implements android.content.ComponentCallbacks2 { diff --git a/core/api/test-current.txt b/core/api/test-current.txt index 05d22dc6d69b..54633c05b6bc 100644 --- a/core/api/test-current.txt +++ b/core/api/test-current.txt @@ -852,6 +852,10 @@ package android.companion { method @NonNull public android.companion.AssociationInfo.Builder setTimeApproved(long); } + public final class CompanionDeviceManager { + field public static final int MESSAGE_REQUEST_PING = 1669362552; // 0x63807378 + } + public abstract class CompanionDeviceService extends android.app.Service { method public void onBindCompanionDeviceService(@NonNull android.content.Intent); } diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java index 4dea4a7e3aca..c77c3c48dde4 100644 --- a/core/java/android/companion/CompanionDeviceManager.java +++ b/core/java/android/companion/CompanionDeviceManager.java @@ -20,7 +20,9 @@ import static android.Manifest.permission.REQUEST_COMPANION_PROFILE_APP_STREAMIN import static android.Manifest.permission.REQUEST_COMPANION_PROFILE_AUTOMOTIVE_PROJECTION; import static android.Manifest.permission.REQUEST_COMPANION_PROFILE_COMPUTER; import static android.Manifest.permission.REQUEST_COMPANION_PROFILE_WATCH; +import static android.annotation.SystemApi.Client.MODULE_LIBRARIES; +import android.annotation.CallbackExecutor; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; @@ -28,6 +30,7 @@ import android.annotation.RequiresPermission; import android.annotation.SuppressLint; import android.annotation.SystemApi; import android.annotation.SystemService; +import android.annotation.TestApi; import android.annotation.UserHandleAware; import android.app.Activity; import android.app.ActivityManager; @@ -216,6 +219,34 @@ public final class CompanionDeviceManager { "com.android.companiondevicemanager"; /** + * Test message type without a designated callback. + * + * @hide + */ + @TestApi public static final int MESSAGE_REQUEST_PING = 0x63807378; // ?PIN + /** + * Message header assigned to the remote authentication handshakes. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int MESSAGE_REQUEST_REMOTE_AUTHENTICATION = 0x63827765; // ?RMA + /** + * Message header assigned to the telecom context sync metadata. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int MESSAGE_REQUEST_CONTEXT_SYNC = 0x63678883; // ?CXS + /** + * Message header assigned to the permission restore request. + * + * @hide + */ + @SystemApi(client = MODULE_LIBRARIES) + public static final int MESSAGE_REQUEST_PERMISSION_RESTORE = 0x63826983; // ?RES + + /** * Callback for applications to receive updates about and the outcome of * {@link AssociationRequest} issued via {@code associate()} call. * @@ -804,28 +835,36 @@ public final class CompanionDeviceManager { } /** - * Listener for any changes to {@link com.android.server.companion.transport.Transport}. + * Listener for any changes to the list of attached transports. + * + * @see com.android.server.companion.transport.Transport * * @hide */ + @SystemApi(client = MODULE_LIBRARIES) public interface OnTransportsChangedListener { /** - * Invoked when a change occurs to any of the transports + * Invoked when a transport is attached or detached. * - * @param associations all the associations which have connected transports + * @param associations all the associations which have connected transports. */ void onTransportsChanged(@NonNull List<AssociationInfo> associations); } /** - * Register a listener for any changes to - * {@link com.android.server.companion.transport.Transport}. Your app will receive a callback to - * {@link OnTransportsChangedListener} immediately with all the existing transports. + * Adds a listener for any changes to the list of attached transports. + * {@link OnTransportsChangedListener#onTransportsChanged(List)} will be triggered with a list + * of existing transports when a transport is detached or a new transport is attached. + * + * @see com.android.server.companion.transport.Transport * * @hide */ + @SystemApi(client = MODULE_LIBRARIES) + @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void addOnTransportsChangedListener( - @NonNull Executor executor, @NonNull OnTransportsChangedListener listener) { + @NonNull @CallbackExecutor Executor executor, + @NonNull OnTransportsChangedListener listener) { final OnTransportsChangedListenerProxy proxy = new OnTransportsChangedListenerProxy( executor, listener); try { @@ -836,11 +875,14 @@ public final class CompanionDeviceManager { } /** - * Unregister a listener to stop receiving any changes to - * {@link com.android.server.companion.transport.Transport}. + * Removes the registered listener for any changes to the list of attached transports. + * + * @see com.android.server.companion.transport.Transport * * @hide */ + @SystemApi(client = MODULE_LIBRARIES) + @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void removeOnTransportsChangedListener( @NonNull OnTransportsChangedListener listener) { final OnTransportsChangedListenerProxy proxy = new OnTransportsChangedListenerProxy( @@ -853,11 +895,16 @@ public final class CompanionDeviceManager { } /** - * Send a message to remote devices + * Sends a message to associated remote devices. The target associations must already have a + * connected transport. + * + * @see #attachSystemDataTransport(int, InputStream, OutputStream) * * @hide */ - public void sendMessage(int messageType, byte[] data, int[] associationIds) { + @SystemApi(client = MODULE_LIBRARIES) + @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) + public void sendMessage(int messageType, @NonNull byte[] data, @NonNull int[] associationIds) { try { mService.sendMessage(messageType, data, associationIds); } catch (RemoteException e) { @@ -866,28 +913,30 @@ public final class CompanionDeviceManager { } /** - * Listener when a message is received for the registered message type + * Listener that triggers a callback when a message is received through a connected transport. * * @see #addOnMessageReceivedListener(Executor, int, OnMessageReceivedListener) * * @hide */ + @SystemApi(client = MODULE_LIBRARIES) public interface OnMessageReceivedListener { /** - * Called when a message is received + * Called when a message is received. */ - void onMessageReceived(int associationId, byte[] data); + void onMessageReceived(int associationId, @NonNull byte[] data); } /** - * Register a listener to receive callbacks when a message is received by the given type - * - * @see com.android.server.companion.transport.Transport for supported message types + * Adds a listener to trigger callbacks when messages of given type are received. * * @hide */ - public void addOnMessageReceivedListener(@NonNull Executor executor, int messageType, - OnMessageReceivedListener listener) { + @SystemApi(client = MODULE_LIBRARIES) + @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) + public void addOnMessageReceivedListener( + @NonNull @CallbackExecutor Executor executor, int messageType, + @NonNull OnMessageReceivedListener listener) { final OnMessageReceivedListenerProxy proxy = new OnMessageReceivedListenerProxy( executor, listener); try { @@ -898,15 +947,14 @@ public final class CompanionDeviceManager { } /** - * Unregister a listener to stop receiving callbacks when a message is received by the given - * type - * - * @see com.android.server.companion.transport.Transport for supported message types + * Removes the registered listener for received messages of given type. * * @hide */ + @SystemApi(client = MODULE_LIBRARIES) + @RequiresPermission(android.Manifest.permission.USE_COMPANION_TRANSPORTS) public void removeOnMessageReceivedListener(int messageType, - OnMessageReceivedListener listener) { + @NonNull OnMessageReceivedListener listener) { final OnMessageReceivedListenerProxy proxy = new OnMessageReceivedListenerProxy( null, listener); try { diff --git a/core/java/android/companion/ICompanionDeviceManager.aidl b/core/java/android/companion/ICompanionDeviceManager.aidl index b5e2670e5299..1e95fb3fa532 100644 --- a/core/java/android/companion/ICompanionDeviceManager.aidl +++ b/core/java/android/companion/ICompanionDeviceManager.aidl @@ -69,14 +69,19 @@ interface ICompanionDeviceManager { void removeOnAssociationsChangedListener(IOnAssociationsChangedListener listener, int userId); + @EnforcePermission("USE_COMPANION_TRANSPORTS") void addOnTransportsChangedListener(IOnTransportsChangedListener listener); + @EnforcePermission("USE_COMPANION_TRANSPORTS") void removeOnTransportsChangedListener(IOnTransportsChangedListener listener); + @EnforcePermission("USE_COMPANION_TRANSPORTS") void sendMessage(int messageType, in byte[] data, in int[] associationIds); + @EnforcePermission("USE_COMPANION_TRANSPORTS") void addOnMessageReceivedListener(int messageType, IOnMessageReceivedListener listener); + @EnforcePermission("USE_COMPANION_TRANSPORTS") void removeOnMessageReceivedListener(int messageType, IOnMessageReceivedListener listener); void notifyDeviceAppeared(int associationId); diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml index 7d9d99113663..c16daccac081 100644 --- a/core/res/AndroidManifest.xml +++ b/core/res/AndroidManifest.xml @@ -5633,6 +5633,12 @@ android:description="@string/permdesc_deliverCompanionMessages" android:protectionLevel="normal" /> + <!-- @hide @SystemApi(client=android.annotation.SystemApi.Client.MODULE_LIBRARIES) + Allows an application to send and receive messages via CDM transports. + --> + <permission android:name="android.permission.USE_COMPANION_TRANSPORTS" + android:protectionLevel="signature|module" /> + <!-- Allows an application to create new companion device associations. @SystemApi @hide --> diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml index ee9883b0b0af..809202fa024d 100644 --- a/packages/Shell/AndroidManifest.xml +++ b/packages/Shell/AndroidManifest.xml @@ -337,6 +337,7 @@ <uses-permission android:name="android.permission.REQUEST_COMPANION_PROFILE_WATCH" /> <uses-permission android:name="android.permission.REQUEST_COMPANION_PROFILE_GLASSES" /> <uses-permission android:name="android.permission.REQUEST_COMPANION_SELF_MANAGED" /> + <uses-permission android:name="android.permission.USE_COMPANION_TRANSPORTS" /> <uses-permission android:name="android.permission.MANAGE_APPOPS" /> <uses-permission android:name="android.permission.WATCH_APPOPS" /> diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java index 6a58c2aeb7bd..9ac2b6dd69c7 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java @@ -18,6 +18,8 @@ package com.android.server.companion; import static android.Manifest.permission.MANAGE_COMPANION_DEVICES; +import static android.Manifest.permission.REQUEST_OBSERVE_COMPANION_DEVICE_PRESENCE; +import static android.Manifest.permission.USE_COMPANION_TRANSPORTS; import static android.app.ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; import static android.companion.AssociationRequest.DEVICE_PROFILE_AUTOMOTIVE_PROJECTION; import static android.content.pm.PackageManager.CERT_INPUT_SHA256; @@ -44,6 +46,7 @@ import static java.util.Objects.requireNonNull; import static java.util.concurrent.TimeUnit.DAYS; import static java.util.concurrent.TimeUnit.MINUTES; +import android.annotation.EnforcePermission; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.SuppressLint; @@ -632,29 +635,44 @@ public class CompanionDeviceManagerService extends SystemService { } @Override + @EnforcePermission(USE_COMPANION_TRANSPORTS) public void addOnTransportsChangedListener(IOnTransportsChangedListener listener) { + addOnTransportsChangedListener_enforcePermission(); + mTransportManager.addListener(listener); } @Override + @EnforcePermission(USE_COMPANION_TRANSPORTS) public void removeOnTransportsChangedListener(IOnTransportsChangedListener listener) { + removeOnTransportsChangedListener_enforcePermission(); + mTransportManager.removeListener(listener); } @Override + @EnforcePermission(USE_COMPANION_TRANSPORTS) public void sendMessage(int messageType, byte[] data, int[] associationIds) { + sendMessage_enforcePermission(); + mTransportManager.sendMessage(messageType, data, associationIds); } @Override + @EnforcePermission(USE_COMPANION_TRANSPORTS) public void addOnMessageReceivedListener(int messageType, IOnMessageReceivedListener listener) { + addOnMessageReceivedListener_enforcePermission(); + mTransportManager.addListener(messageType, listener); } @Override + @EnforcePermission(USE_COMPANION_TRANSPORTS) public void removeOnMessageReceivedListener(int messageType, IOnMessageReceivedListener listener) { + removeOnMessageReceivedListener_enforcePermission(); + mTransportManager.removeListener(messageType, listener); } diff --git a/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java b/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java index 04fbab434d1f..a86839293feb 100644 --- a/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java +++ b/services/companion/java/com/android/server/companion/CompanionDeviceShellCommand.java @@ -16,6 +16,8 @@ package com.android.server.companion; +import static android.companion.CompanionDeviceManager.MESSAGE_REQUEST_CONTEXT_SYNC; + import android.companion.AssociationInfo; import android.companion.ContextSyncMessage; import android.companion.Telecom; @@ -30,7 +32,6 @@ import com.android.server.companion.datatransfer.contextsync.BitmapUtils; import com.android.server.companion.datatransfer.contextsync.CrossDeviceSyncController; import com.android.server.companion.presence.CompanionDevicePresenceMonitor; import com.android.server.companion.transport.CompanionTransportManager; -import com.android.server.companion.transport.Transport; import java.io.PrintWriter; import java.util.List; @@ -135,7 +136,7 @@ class CompanionDeviceShellCommand extends ShellCommand { case "send-context-sync-empty-message": { associationId = getNextIntArgRequired(); mTransportManager.createEmulatedTransport(associationId) - .processMessage(Transport.MESSAGE_REQUEST_CONTEXT_SYNC, + .processMessage(MESSAGE_REQUEST_CONTEXT_SYNC, /* sequence= */ 0, CrossDeviceSyncController.createEmptyMessage()); break; @@ -147,7 +148,7 @@ class CompanionDeviceShellCommand extends ShellCommand { String address = getNextArgRequired(); String facilitator = getNextArgRequired(); mTransportManager.createEmulatedTransport(associationId) - .processMessage(Transport.MESSAGE_REQUEST_CONTEXT_SYNC, + .processMessage(MESSAGE_REQUEST_CONTEXT_SYNC, /* sequence= */ 0, CrossDeviceSyncController.createCallCreateMessage(callId, address, facilitator)); @@ -159,7 +160,7 @@ class CompanionDeviceShellCommand extends ShellCommand { String callId = getNextArgRequired(); int control = getNextIntArgRequired(); mTransportManager.createEmulatedTransport(associationId) - .processMessage(Transport.MESSAGE_REQUEST_CONTEXT_SYNC, + .processMessage(MESSAGE_REQUEST_CONTEXT_SYNC, /* sequence= */ 0, CrossDeviceSyncController.createCallControlMessage(callId, control)); @@ -184,7 +185,7 @@ class CompanionDeviceShellCommand extends ShellCommand { } pos.end(telecomToken); mTransportManager.createEmulatedTransport(associationId) - .processMessage(Transport.MESSAGE_REQUEST_CONTEXT_SYNC, + .processMessage(MESSAGE_REQUEST_CONTEXT_SYNC, /* sequence= */ 0, pos.getBytes()); break; } @@ -246,7 +247,7 @@ class CompanionDeviceShellCommand extends ShellCommand { pos.end(callsToken); pos.end(telecomToken); mTransportManager.createEmulatedTransport(associationId) - .processMessage(Transport.MESSAGE_REQUEST_CONTEXT_SYNC, + .processMessage(MESSAGE_REQUEST_CONTEXT_SYNC, /* sequence= */ 0, pos.getBytes()); break; } diff --git a/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java index dd7d38f34f28..fcc7a830e9be 100644 --- a/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java +++ b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java @@ -20,10 +20,10 @@ import static android.app.PendingIntent.FLAG_CANCEL_CURRENT; import static android.app.PendingIntent.FLAG_IMMUTABLE; import static android.app.PendingIntent.FLAG_ONE_SHOT; import static android.companion.CompanionDeviceManager.COMPANION_DEVICE_DISCOVERY_PACKAGE_NAME; +import static android.companion.CompanionDeviceManager.MESSAGE_REQUEST_PERMISSION_RESTORE; import static android.content.ComponentName.createRelative; import static com.android.server.companion.Utils.prepareForIpc; -import static com.android.server.companion.transport.Transport.MESSAGE_REQUEST_PERMISSION_RESTORE; import android.annotation.NonNull; import android.annotation.Nullable; diff --git a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java index 9bd5af956a6e..ad1eff8cebad 100644 --- a/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java +++ b/services/companion/java/com/android/server/companion/datatransfer/contextsync/CrossDeviceSyncController.java @@ -16,7 +16,7 @@ package com.android.server.companion.datatransfer.contextsync; -import static com.android.server.companion.transport.Transport.MESSAGE_REQUEST_CONTEXT_SYNC; +import static android.companion.CompanionDeviceManager.MESSAGE_REQUEST_CONTEXT_SYNC; import android.app.admin.DevicePolicyManager; import android.companion.AssociationInfo; diff --git a/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java b/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java index a49021a8eec4..ee285be970c9 100644 --- a/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java +++ b/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java @@ -17,8 +17,7 @@ package com.android.server.companion.transport; import static android.Manifest.permission.DELIVER_COMPANION_MESSAGES; - -import static com.android.server.companion.transport.Transport.MESSAGE_REQUEST_PERMISSION_RESTORE; +import static android.companion.CompanionDeviceManager.MESSAGE_REQUEST_PERMISSION_RESTORE; import android.annotation.NonNull; import android.annotation.SuppressLint; diff --git a/services/companion/java/com/android/server/companion/transport/Transport.java b/services/companion/java/com/android/server/companion/transport/Transport.java index 5af3b98d71cc..32d4061db1f7 100644 --- a/services/companion/java/com/android/server/companion/transport/Transport.java +++ b/services/companion/java/com/android/server/companion/transport/Transport.java @@ -16,6 +16,11 @@ package com.android.server.companion.transport; +import static android.companion.CompanionDeviceManager.MESSAGE_REQUEST_CONTEXT_SYNC; +import static android.companion.CompanionDeviceManager.MESSAGE_REQUEST_PERMISSION_RESTORE; +import static android.companion.CompanionDeviceManager.MESSAGE_REQUEST_PING; +import static android.companion.CompanionDeviceManager.MESSAGE_REQUEST_REMOTE_AUTHENTICATION; + import android.annotation.NonNull; import android.companion.IOnMessageReceivedListener; import android.content.Context; @@ -45,10 +50,6 @@ public abstract class Transport { protected static final String TAG = "CDM_CompanionTransport"; protected static final boolean DEBUG = Build.IS_DEBUGGABLE; - static final int MESSAGE_REQUEST_PING = 0x63807378; // ?PIN - public static final int MESSAGE_REQUEST_CONTEXT_SYNC = 0x63678883; // ?CXS - public static final int MESSAGE_REQUEST_PERMISSION_RESTORE = 0x63826983; // ?RES - static final int MESSAGE_RESPONSE_SUCCESS = 0x33838567; // !SUC static final int MESSAGE_RESPONSE_FAILURE = 0x33706573; // !FAI @@ -181,7 +182,8 @@ public abstract class Transport { sendMessage(MESSAGE_RESPONSE_SUCCESS, sequence, data); break; } - case MESSAGE_REQUEST_CONTEXT_SYNC: { + case MESSAGE_REQUEST_CONTEXT_SYNC: + case MESSAGE_REQUEST_REMOTE_AUTHENTICATION: { callback(message, data); sendMessage(MESSAGE_RESPONSE_SUCCESS, sequence, EmptyArray.BYTE); break; |