AudioService: ensure sink role for communication device

Make sure that devices selected for communication have a sink
role (output) and clarify the AudioManager documentation.

Bug: 247659585
Test: make
Change-Id: I6b1bc0430a7c5f8a5019fb723a3d9d9e5fcd36c6
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index d975e96..d696ecf 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -7663,8 +7663,10 @@
      * or video calls. This method can be used by voice or video chat applications to select a
      * different audio device than the one selected by default by the platform.
      * <p>The device selection is expressed as an {@link AudioDeviceInfo} among devices returned by
-     * {@link #getAvailableCommunicationDevices()}.
-     * The selection is active as long as the requesting application process lives, until
+     * {@link #getAvailableCommunicationDevices()}. Note that only devices in a sink role
+     * (AKA output devices, see {@link AudioDeviceInfo#isSink()}) can be specified. The matching
+     * source device is selected automatically by the platform.
+     * <p>The selection is active as long as the requesting application process lives, until
      * {@link #clearCommunicationDevice} is called or until the device is disconnected.
      * It is therefore important for applications to clear the request when a call ends or the
      * the requesting activity or service is stopped or destroyed.
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index 4fda233..fa3c210 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -5804,6 +5804,9 @@
     };
 
     private boolean isValidCommunicationDevice(AudioDeviceInfo device) {
+        if (!device.isSink()) {
+            return false;
+        }
         for (int type : VALID_COMMUNICATION_DEVICE_TYPES) {
             if (device.getType() == type) {
                 return true;
@@ -5838,7 +5841,11 @@
                 throw new IllegalArgumentException("invalid portID " + portId);
             }
             if (!isValidCommunicationDevice(device)) {
-                throw new IllegalArgumentException("invalid device type " + device.getType());
+                if (!device.isSink()) {
+                    throw new IllegalArgumentException("device must have sink role");
+                } else {
+                    throw new IllegalArgumentException("invalid device type: " + device.getType());
+                }
             }
         }
         final String eventSource = new StringBuilder()