1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.media; 18 19 import android.annotation.NonNull; 20 import android.compat.annotation.UnsupportedAppUsage; 21 import android.os.Build; 22 23 import java.util.Arrays; 24 import java.util.List; 25 26 /** 27 * The AudioDevicePort is a specialized type of AudioPort 28 * describing an input (e.g microphone) or output device (e.g speaker) 29 * of the system. 30 * An AudioDevicePort is an AudioPort controlled by the audio HAL, almost always a physical 31 * device at the boundary of the audio system. 32 * In addition to base audio port attributes, the device descriptor contains: 33 * - the device type (e.g AudioManager.DEVICE_OUT_SPEAKER) 34 * - the device address (e.g MAC adddress for AD2P sink). 35 * @see AudioPort 36 * @hide 37 */ 38 39 public class AudioDevicePort extends AudioPort { 40 41 private final int mType; 42 private final String mAddress; 43 private final int[] mEncapsulationModes; 44 private final int[] mEncapsulationMetadataTypes; 45 46 @UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553) AudioDevicePort(AudioHandle handle, String deviceName, int[] samplingRates, int[] channelMasks, int[] channelIndexMasks, int[] formats, AudioGain[] gains, int type, String address, int[] encapsulationModes, @AudioTrack.EncapsulationMetadataType int[] encapsulationMetadataTypes)47 AudioDevicePort(AudioHandle handle, String deviceName, 48 int[] samplingRates, int[] channelMasks, int[] channelIndexMasks, 49 int[] formats, AudioGain[] gains, int type, String address, int[] encapsulationModes, 50 @AudioTrack.EncapsulationMetadataType int[] encapsulationMetadataTypes) { 51 super(handle, 52 (AudioManager.isInputDevice(type) == true) ? 53 AudioPort.ROLE_SOURCE : AudioPort.ROLE_SINK, 54 deviceName, samplingRates, channelMasks, channelIndexMasks, formats, gains); 55 mType = type; 56 mAddress = address; 57 mEncapsulationModes = encapsulationModes; 58 mEncapsulationMetadataTypes = encapsulationMetadataTypes; 59 } 60 AudioDevicePort(AudioHandle handle, String deviceName, List<AudioProfile> profiles, AudioGain[] gains, int type, String address, int[] encapsulationModes, @AudioTrack.EncapsulationMetadataType int[] encapsulationMetadataTypes, List<AudioDescriptor> descriptors)61 AudioDevicePort(AudioHandle handle, String deviceName, List<AudioProfile> profiles, 62 AudioGain[] gains, int type, String address, int[] encapsulationModes, 63 @AudioTrack.EncapsulationMetadataType int[] encapsulationMetadataTypes, 64 List<AudioDescriptor> descriptors) { 65 super(handle, 66 AudioManager.isInputDevice(type) ? AudioPort.ROLE_SOURCE : AudioPort.ROLE_SINK, 67 deviceName, profiles, gains, descriptors); 68 mType = type; 69 mAddress = address; 70 mEncapsulationModes = encapsulationModes; 71 mEncapsulationMetadataTypes = encapsulationMetadataTypes; 72 } 73 74 /** 75 * Get the device type (e.g AudioManager.DEVICE_OUT_SPEAKER) 76 */ 77 @UnsupportedAppUsage type()78 public int type() { 79 return mType; 80 } 81 82 /** 83 * Get the device address. Address format varies with the device type. 84 * - USB devices ({@link AudioManager#DEVICE_OUT_USB_DEVICE}, 85 * {@link AudioManager#DEVICE_IN_USB_DEVICE}) use an address composed of the ALSA card number 86 * and device number: "card=2;device=1" 87 * - Bluetooth devices ({@link AudioManager#DEVICE_OUT_BLUETOOTH_SCO}, 88 * {@link AudioManager#DEVICE_OUT_BLUETOOTH_SCO}, 89 * {@link AudioManager#DEVICE_OUT_BLUETOOTH_A2DP}), 90 * {@link AudioManager#DEVICE_OUT_BLE_HEADSET}, {@link AudioManager#DEVICE_OUT_BLE_SPEAKER}) 91 * use the MAC address of the bluetooth device in the form "00:11:22:AA:BB:CC" as reported by 92 * {@link BluetoothDevice#getAddress()}. 93 * - Bluetooth LE broadcast group ({@link AudioManager#DEVICE_OUT_BLE_BROADCAST} use the group number. 94 * - Devices that do not have an address will indicate an empty string "". 95 */ address()96 public String address() { 97 return mAddress; 98 } 99 100 /** 101 * Get supported encapsulation modes. 102 */ encapsulationModes()103 public @NonNull @AudioTrack.EncapsulationMode int[] encapsulationModes() { 104 if (mEncapsulationModes == null) { 105 return new int[0]; 106 } 107 return Arrays.stream(mEncapsulationModes).boxed() 108 .filter(mode -> mode != AudioTrack.ENCAPSULATION_MODE_HANDLE) 109 .mapToInt(Integer::intValue).toArray(); 110 } 111 112 /** 113 * Get supported encapsulation metadata types. 114 */ encapsulationMetadataTypes()115 public @NonNull @AudioTrack.EncapsulationMetadataType int[] encapsulationMetadataTypes() { 116 if (mEncapsulationMetadataTypes == null) { 117 return new int[0]; 118 } 119 int[] encapsulationMetadataTypes = new int[mEncapsulationMetadataTypes.length]; 120 System.arraycopy(mEncapsulationMetadataTypes, 0, 121 encapsulationMetadataTypes, 0, mEncapsulationMetadataTypes.length); 122 return encapsulationMetadataTypes; 123 } 124 125 /** 126 * Build a specific configuration of this audio device port for use by methods 127 * like AudioManager.connectAudioPatch(). 128 */ buildConfig(int samplingRate, int channelMask, int format, AudioGainConfig gain)129 public AudioDevicePortConfig buildConfig(int samplingRate, int channelMask, int format, 130 AudioGainConfig gain) { 131 return new AudioDevicePortConfig(this, samplingRate, channelMask, format, gain); 132 } 133 134 @Override equals(Object o)135 public boolean equals(Object o) { 136 if (o == null || !(o instanceof AudioDevicePort)) { 137 return false; 138 } 139 AudioDevicePort other = (AudioDevicePort)o; 140 if (mType != other.type()) { 141 return false; 142 } 143 if (mAddress == null && other.address() != null) { 144 return false; 145 } 146 if (!mAddress.equals(other.address())) { 147 return false; 148 } 149 return super.equals(o); 150 } 151 152 @Override toString()153 public String toString() { 154 String type = (mRole == ROLE_SOURCE ? 155 AudioSystem.getInputDeviceName(mType) : 156 AudioSystem.getOutputDeviceName(mType)); 157 return "{" + super.toString() 158 + ", mType: " + type 159 + ", mAddress: " + mAddress 160 + "}"; 161 } 162 } 163