[CDM] Make CDM transport APIs available to the system services
Bug: 288297505
Test: atest CtsCompanionDeviceManagerCoreTestCases:TransportPermissionTest
Change-Id: If709de4f717546f3706bf08fd098b0dc78b61a44
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index c1f6219..3baa92c 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -6,6 +6,7 @@
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";
}
}
@@ -80,6 +81,29 @@
}
+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 3fb9fd9..833d9c6 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -839,6 +839,7 @@
public final class CompanionDeviceManager {
method @RequiresPermission("android.permission.MANAGE_COMPANION_DEVICES") public void enableSecureTransport(boolean);
+ field public static final int MESSAGE_REQUEST_PING = 1669362552; // 0x63807378
}
public abstract class CompanionDeviceService extends android.app.Service {
diff --git a/core/java/android/companion/CompanionDeviceManager.java b/core/java/android/companion/CompanionDeviceManager.java
index e45fa19..69e1653 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_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;
@@ -209,6 +211,34 @@
public static final String EXTRA_ASSOCIATION = "android.companion.extra.ASSOCIATION";
/**
+ * 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.
*
@@ -797,28 +827,36 @@
}
/**
- * 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 {
@@ -829,11 +867,14 @@
}
/**
- * 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(
@@ -846,11 +887,16 @@
}
/**
- * 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) {
@@ -859,28 +905,30 @@
}
/**
- * 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 {
@@ -891,15 +939,14 @@
}
/**
- * 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 2318e30..463dba2 100644
--- a/core/java/android/companion/ICompanionDeviceManager.aidl
+++ b/core/java/android/companion/ICompanionDeviceManager.aidl
@@ -74,14 +74,19 @@
@EnforcePermission("MANAGE_COMPANION_DEVICES")
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 baa47da..b29a4e6 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -5631,6 +5631,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 368115b..215cc8e 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 be52b1c..82d4d60 100644
--- a/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
+++ b/services/companion/java/com/android/server/companion/CompanionDeviceManagerService.java
@@ -21,6 +21,7 @@
import static android.Manifest.permission.DELIVER_COMPANION_MESSAGES;
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;
@@ -640,29 +641,44 @@
}
@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 c79466f..94cede8 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.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 @@
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 @@
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 @@
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 @@
}
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 @@
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 7af4957..13f41ed 100644
--- a/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
+++ b/services/companion/java/com/android/server/companion/datatransfer/SystemDataTransferProcessor.java
@@ -19,10 +19,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.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 9bd5af9..ad1eff8 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 41867f9..f648f09 100644
--- a/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java
+++ b/services/companion/java/com/android/server/companion/transport/CompanionTransportManager.java
@@ -16,7 +16,7 @@
package com.android.server.companion.transport;
-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 5af3b98..32d4061 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 @@
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 @@
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;