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
17package android.media;
18
19import android.annotation.NonNull;
20import android.util.SparseIntArray;
21
22import java.util.TreeSet;
23
24/**
25 * Class to provide information about the audio devices.
26 */
27public final class AudioDeviceInfo {
28
29    /**
30     * A device type associated with an unknown or uninitialized device.
31     */
32    public static final int TYPE_UNKNOWN          = 0;
33    /**
34     * A device type describing the attached earphone speaker.
35     */
36    public static final int TYPE_BUILTIN_EARPIECE = 1;
37    /**
38     * A device type describing the speaker system (i.e. a mono speaker or stereo speakers) built
39     * in a device.
40     */
41    public static final int TYPE_BUILTIN_SPEAKER  = 2;
42    /**
43     * A device type describing a headset, which is the combination of a headphones and microphone.
44     */
45    public static final int TYPE_WIRED_HEADSET    = 3;
46    /**
47     * A device type describing a pair of wired headphones.
48     */
49    public static final int TYPE_WIRED_HEADPHONES = 4;
50    /**
51     * A device type describing an analog line-level connection.
52     */
53    public static final int TYPE_LINE_ANALOG      = 5;
54    /**
55     * A device type describing a digital line connection (e.g. SPDIF).
56     */
57    public static final int TYPE_LINE_DIGITAL     = 6;
58    /**
59     * A device type describing a Bluetooth device typically used for telephony.
60     */
61    public static final int TYPE_BLUETOOTH_SCO    = 7;
62    /**
63     * A device type describing a Bluetooth device supporting the A2DP profile.
64     */
65    public static final int TYPE_BLUETOOTH_A2DP   = 8;
66    /**
67     * A device type describing an HDMI connection .
68     */
69    public static final int TYPE_HDMI             = 9;
70    /**
71     * A device type describing the Audio Return Channel of an HDMI connection.
72     */
73    public static final int TYPE_HDMI_ARC         = 10;
74    /**
75     * A device type describing a USB audio device.
76     */
77    public static final int TYPE_USB_DEVICE       = 11;
78    /**
79     * A device type describing a USB audio device in accessory mode.
80     */
81    public static final int TYPE_USB_ACCESSORY    = 12;
82    /**
83     * A device type describing the audio device associated with a dock.
84     */
85    public static final int TYPE_DOCK             = 13;
86    /**
87     * A device type associated with the transmission of audio signals over FM.
88     */
89    public static final int TYPE_FM               = 14;
90    /**
91     * A device type describing the microphone(s) built in a device.
92     */
93    public static final int TYPE_BUILTIN_MIC      = 15;
94    /**
95     * A device type for accessing the audio content transmitted over FM.
96     */
97    public static final int TYPE_FM_TUNER         = 16;
98    /**
99     * A device type for accessing the audio content transmitted over the TV tuner system.
100     */
101    public static final int TYPE_TV_TUNER         = 17;
102    /**
103     * A device type describing the transmission of audio signals over the telephony network.
104     */
105    public static final int TYPE_TELEPHONY        = 18;
106    /**
107     * A device type describing the auxiliary line-level connectors.
108     */
109    public static final int TYPE_AUX_LINE         = 19;
110    /**
111     * A device type connected over IP.
112     */
113    public static final int TYPE_IP               = 20;
114    /**
115     * A type-agnostic device used for communication with external audio systems
116     */
117    public static final int TYPE_BUS              = 21;
118    /**
119     * A device type describing a USB audio headset.
120     */
121    public static final int TYPE_USB_HEADSET       = 22;
122
123    private final AudioDevicePort mPort;
124
125    AudioDeviceInfo(AudioDevicePort port) {
126       mPort = port;
127    }
128
129    /**
130     * @return The internal device ID.
131     */
132    public int getId() {
133        return mPort.handle().id();
134    }
135
136    /**
137     * @return The human-readable name of the audio device.
138     */
139    public CharSequence getProductName() {
140        String portName = mPort.name();
141        return portName.length() != 0 ? portName : android.os.Build.MODEL;
142    }
143
144    /**
145     * @hide
146     * @return The "address" string of the device. This generally contains device-specific
147     * parameters.
148     */
149    public String getAddress() {
150        return mPort.address();
151    }
152
153   /**
154     * @return true if the audio device is a source for audio data (e.e an input).
155     */
156    public boolean isSource() {
157        return mPort.role() == AudioPort.ROLE_SOURCE;
158    }
159
160    /**
161     * @return true if the audio device is a sink for audio data (i.e. an output).
162     */
163    public boolean isSink() {
164        return mPort.role() == AudioPort.ROLE_SINK;
165    }
166
167    /**
168     * @return An array of sample rates supported by the audio device.
169     *
170     * Note: an empty array indicates that the device supports arbitrary rates.
171     */
172    public @NonNull int[] getSampleRates() {
173        return mPort.samplingRates();
174    }
175
176    /**
177     * @return An array of channel position masks (e.g. {@link AudioFormat#CHANNEL_IN_STEREO},
178     * {@link AudioFormat#CHANNEL_OUT_7POINT1}) for which this audio device can be configured.
179     *
180     * @see AudioFormat
181     *
182     * Note: an empty array indicates that the device supports arbitrary channel masks.
183     */
184    public @NonNull int[] getChannelMasks() {
185        return mPort.channelMasks();
186    }
187
188    /**
189     * @return An array of channel index masks for which this audio device can be configured.
190     *
191     * @see AudioFormat
192     *
193     * Note: an empty array indicates that the device supports arbitrary channel index masks.
194     */
195    public @NonNull int[] getChannelIndexMasks() {
196        return mPort.channelIndexMasks();
197    }
198
199    /**
200     * @return An array of channel counts (1, 2, 4, ...) for which this audio device
201     * can be configured.
202     *
203     * Note: an empty array indicates that the device supports arbitrary channel counts.
204     */
205    public @NonNull int[] getChannelCounts() {
206        TreeSet<Integer> countSet = new TreeSet<Integer>();
207
208        // Channel Masks
209        for (int mask : getChannelMasks()) {
210            countSet.add(isSink() ?
211                    AudioFormat.channelCountFromOutChannelMask(mask)
212                    : AudioFormat.channelCountFromInChannelMask(mask));
213        }
214
215        // Index Masks
216        for (int index_mask : getChannelIndexMasks()) {
217            countSet.add(Integer.bitCount(index_mask));
218        }
219
220        int[] counts = new int[countSet.size()];
221        int index = 0;
222        for (int count : countSet) {
223            counts[index++] = count;
224        }
225        return counts;
226    }
227
228    /**
229     * @return An array of audio encodings (e.g. {@link AudioFormat#ENCODING_PCM_16BIT},
230     * {@link AudioFormat#ENCODING_PCM_FLOAT}) supported by the audio device.
231     * <code>ENCODING_PCM_FLOAT</code> indicates the device supports more
232     * than 16 bits of integer precision.  As there is no AudioFormat constant
233     * specifically defined for 24-bit PCM, the value <code>ENCODING_PCM_FLOAT</code>
234     * indicates that {@link AudioTrack} or {@link AudioRecord} can preserve at least 24 bits of
235     * integer precision to that device.
236     *
237     * @see AudioFormat
238     *
239     * Note: an empty array indicates that the device supports arbitrary encodings.
240     */
241    public @NonNull int[] getEncodings() {
242        return AudioFormat.filterPublicFormats(mPort.formats());
243    }
244
245   /**
246     * @return The device type identifier of the audio device (i.e. TYPE_BUILTIN_SPEAKER).
247     */
248    public int getType() {
249        return INT_TO_EXT_DEVICE_MAPPING.get(mPort.type(), TYPE_UNKNOWN);
250    }
251
252    /** @hide */
253    public static int convertDeviceTypeToInternalDevice(int deviceType) {
254        return EXT_TO_INT_DEVICE_MAPPING.get(deviceType, AudioSystem.DEVICE_NONE);
255    }
256
257    /** @hide */
258    public static int convertInternalDeviceToDeviceType(int intDevice) {
259        return INT_TO_EXT_DEVICE_MAPPING.get(intDevice, TYPE_UNKNOWN);
260    }
261
262    private static final SparseIntArray INT_TO_EXT_DEVICE_MAPPING;
263
264    private static final SparseIntArray EXT_TO_INT_DEVICE_MAPPING;
265
266    static {
267        INT_TO_EXT_DEVICE_MAPPING = new SparseIntArray();
268        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_EARPIECE, TYPE_BUILTIN_EARPIECE);
269        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_SPEAKER, TYPE_BUILTIN_SPEAKER);
270        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_WIRED_HEADSET, TYPE_WIRED_HEADSET);
271        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, TYPE_WIRED_HEADPHONES);
272        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, TYPE_BLUETOOTH_SCO);
273        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET, TYPE_BLUETOOTH_SCO);
274        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT, TYPE_BLUETOOTH_SCO);
275        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, TYPE_BLUETOOTH_A2DP);
276        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, TYPE_BLUETOOTH_A2DP);
277        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, TYPE_BLUETOOTH_A2DP);
278        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HDMI, TYPE_HDMI);
279        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, TYPE_DOCK);
280        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET, TYPE_DOCK);
281        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_USB_ACCESSORY, TYPE_USB_ACCESSORY);
282        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_USB_DEVICE, TYPE_USB_DEVICE);
283        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_USB_HEADSET, TYPE_USB_HEADSET);
284        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_TELEPHONY_TX, TYPE_TELEPHONY);
285        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_LINE, TYPE_LINE_ANALOG);
286        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HDMI_ARC, TYPE_HDMI_ARC);
287        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_SPDIF, TYPE_LINE_DIGITAL);
288        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_FM, TYPE_FM);
289        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_AUX_LINE, TYPE_AUX_LINE);
290        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_IP, TYPE_IP);
291        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BUS, TYPE_BUS);
292
293        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BUILTIN_MIC, TYPE_BUILTIN_MIC);
294        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET, TYPE_BLUETOOTH_SCO);
295        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_WIRED_HEADSET, TYPE_WIRED_HEADSET);
296        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_HDMI, TYPE_HDMI);
297        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_TELEPHONY_RX, TYPE_TELEPHONY);
298        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BACK_MIC, TYPE_BUILTIN_MIC);
299        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET, TYPE_DOCK);
300        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_DGTL_DOCK_HEADSET, TYPE_DOCK);
301        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_USB_ACCESSORY, TYPE_USB_ACCESSORY);
302        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_USB_DEVICE, TYPE_USB_DEVICE);
303        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_USB_HEADSET, TYPE_USB_HEADSET);
304        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_FM_TUNER, TYPE_FM_TUNER);
305        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_TV_TUNER, TYPE_TV_TUNER);
306        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_LINE, TYPE_LINE_ANALOG);
307        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_SPDIF, TYPE_LINE_DIGITAL);
308        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, TYPE_BLUETOOTH_A2DP);
309        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_IP, TYPE_IP);
310        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BUS, TYPE_BUS);
311
312        // not covered here, legacy
313        //AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
314        //AudioSystem.DEVICE_IN_REMOTE_SUBMIX
315
316        // privileges mapping to output device
317        EXT_TO_INT_DEVICE_MAPPING = new SparseIntArray();
318        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUILTIN_EARPIECE, AudioSystem.DEVICE_OUT_EARPIECE);
319        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUILTIN_SPEAKER, AudioSystem.DEVICE_OUT_SPEAKER);
320        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_WIRED_HEADSET, AudioSystem.DEVICE_OUT_WIRED_HEADSET);
321        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_WIRED_HEADPHONES, AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
322        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_LINE_ANALOG, AudioSystem.DEVICE_OUT_LINE);
323        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_LINE_DIGITAL, AudioSystem.DEVICE_OUT_SPDIF);
324        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLUETOOTH_SCO, AudioSystem.DEVICE_OUT_BLUETOOTH_SCO);
325        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLUETOOTH_A2DP, AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
326        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_HDMI, AudioSystem.DEVICE_OUT_HDMI);
327        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_HDMI_ARC, AudioSystem.DEVICE_OUT_HDMI_ARC);
328        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_DEVICE, AudioSystem.DEVICE_OUT_USB_DEVICE);
329        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_HEADSET, AudioSystem.DEVICE_OUT_USB_HEADSET);
330        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_ACCESSORY, AudioSystem.DEVICE_OUT_USB_ACCESSORY);
331        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_DOCK, AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET);
332        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_FM, AudioSystem.DEVICE_OUT_FM);
333        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUILTIN_MIC, AudioSystem.DEVICE_IN_BUILTIN_MIC);
334        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_FM_TUNER, AudioSystem.DEVICE_IN_FM_TUNER);
335        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_TV_TUNER, AudioSystem.DEVICE_IN_TV_TUNER);
336        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_TELEPHONY, AudioSystem.DEVICE_OUT_TELEPHONY_TX);
337        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_AUX_LINE, AudioSystem.DEVICE_OUT_AUX_LINE);
338        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_IP, AudioSystem.DEVICE_OUT_IP);
339        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUS, AudioSystem.DEVICE_OUT_BUS);
340    }
341}
342
343