summaryrefslogtreecommitdiffstats
path: root/media/java/android/media/AudioDeviceInfo.java
blob: 7f22b8a1ab17a6ba34098f29dd64df99f9f4f626 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
/*
 * Copyright (C) 2014 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package android.media;

import android.annotation.NonNull;
import android.util.SparseIntArray;

import java.util.TreeSet;

/**
 * Class to provide information about the audio devices.
 */
public final class AudioDeviceInfo {

    /**
     * A device type associated with an unknown or uninitialized device.
     */
    public static final int TYPE_UNKNOWN          = 0;
    /**
     * A device type describing the attached earphone speaker.
     */
    public static final int TYPE_BUILTIN_EARPIECE = 1;
    /**
     * A device type describing the speaker system (i.e. a mono speaker or stereo speakers) built
     * in a device.
     */
    public static final int TYPE_BUILTIN_SPEAKER  = 2;
    /**
     * A device type describing a headset, which is the combination of a headphones and microphone.
     */
    public static final int TYPE_WIRED_HEADSET    = 3;
    /**
     * A device type describing a pair of wired headphones.
     */
    public static final int TYPE_WIRED_HEADPHONES = 4;
    /**
     * A device type describing an analog line-level connection.
     */
    public static final int TYPE_LINE_ANALOG      = 5;
    /**
     * A device type describing a digital line connection (e.g. SPDIF).
     */
    public static final int TYPE_LINE_DIGITAL     = 6;
    /**
     * A device type describing a Bluetooth device typically used for telephony.
     */
    public static final int TYPE_BLUETOOTH_SCO    = 7;
    /**
     * A device type describing a Bluetooth device supporting the A2DP profile.
     */
    public static final int TYPE_BLUETOOTH_A2DP   = 8;
    /**
     * A device type describing an HDMI connection .
     */
    public static final int TYPE_HDMI             = 9;
    /**
     * A device type describing the Audio Return Channel of an HDMI connection.
     */
    public static final int TYPE_HDMI_ARC         = 10;
    /**
     * A device type describing a USB audio device.
     */
    public static final int TYPE_USB_DEVICE       = 11;
    /**
     * A device type describing a USB audio device in accessory mode.
     */
    public static final int TYPE_USB_ACCESSORY    = 12;
    /**
     * A device type describing the audio device associated with a dock.
     */
    public static final int TYPE_DOCK             = 13;
    /**
     * A device type associated with the transmission of audio signals over FM.
     */
    public static final int TYPE_FM               = 14;
    /**
     * A device type describing the microphone(s) built in a device.
     */
    public static final int TYPE_BUILTIN_MIC      = 15;
    /**
     * A device type for accessing the audio content transmitted over FM.
     */
    public static final int TYPE_FM_TUNER         = 16;
    /**
     * A device type for accessing the audio content transmitted over the TV tuner system.
     */
    public static final int TYPE_TV_TUNER         = 17;
    /**
     * A device type describing the transmission of audio signals over the telephony network.
     */
    public static final int TYPE_TELEPHONY        = 18;
    /**
     * A device type describing the auxiliary line-level connectors.
     */
    public static final int TYPE_AUX_LINE         = 19;
    /**
     * A device type connected over IP.
     */
    public static final int TYPE_IP               = 20;

    private final AudioDevicePort mPort;

    AudioDeviceInfo(AudioDevicePort port) {
       mPort = port;
    }

    /**
     * @return The internal device ID.
     */
    public int getId() {
        return mPort.handle().id();
    }

    /**
     * @return The human-readable name of the audio device.
     */
    public CharSequence getProductName() {
        String portName = mPort.name();
        return portName.length() != 0 ? portName : android.os.Build.MODEL;
    }

    /**
     * @hide
     * @return The "address" string of the device. This generally contains device-specific
     * parameters.
     */
    public String getAddress() {
        return mPort.address();
    }

   /**
     * @return true if the audio device is a source for audio data (e.e an input).
     */
    public boolean isSource() {
        return mPort.role() == AudioPort.ROLE_SOURCE;
    }

    /**
     * @return true if the audio device is a sink for audio data (i.e. an output).
     */
    public boolean isSink() {
        return mPort.role() == AudioPort.ROLE_SINK;
    }

    /**
     * @return An array of sample rates supported by the audio device.
     *
     * Note: an empty array indicates that the device supports arbitrary rates.
     */
    public @NonNull int[] getSampleRates() {
        return mPort.samplingRates();
    }

    /**
     * @return An array of channel position masks (e.g. {@link AudioFormat#CHANNEL_IN_STEREO},
     * {@link AudioFormat#CHANNEL_OUT_7POINT1}) for which this audio device can be configured.
     *
     * @see AudioFormat
     *
     * Note: an empty array indicates that the device supports arbitrary channel masks.
     */
    public @NonNull int[] getChannelMasks() {
        return mPort.channelMasks();
    }

    /**
     * @return An array of channel index masks for which this audio device can be configured.
     *
     * @see AudioFormat
     *
     * Note: an empty array indicates that the device supports arbitrary channel index masks.
     */
    public @NonNull int[] getChannelIndexMasks() {
        return mPort.channelIndexMasks();
    }

    /**
     * @return An array of channel counts (1, 2, 4, ...) for which this audio device
     * can be configured.
     *
     * Note: an empty array indicates that the device supports arbitrary channel counts.
     */
    public @NonNull int[] getChannelCounts() {
        TreeSet<Integer> countSet = new TreeSet<Integer>();

        // Channel Masks
        for (int mask : getChannelMasks()) {
            countSet.add(isSink() ?
                    AudioFormat.channelCountFromOutChannelMask(mask)
                    : AudioFormat.channelCountFromInChannelMask(mask));
        }

        // Index Masks
        for (int index_mask : getChannelIndexMasks()) {
            countSet.add(Integer.bitCount(index_mask));
        }

        int[] counts = new int[countSet.size()];
        int index = 0;
        for (int count : countSet) {
            counts[index++] = count; 
        }
        return counts;
    }

    /**
     * @return An array of audio encodings (e.g. {@link AudioFormat#ENCODING_PCM_16BIT},
     * {@link AudioFormat#ENCODING_PCM_FLOAT}) supported by the audio device.
     * <code>ENCODING_PCM_FLOAT</code> indicates the device supports more
     * than 16 bits of integer precision.  Specifying <code>ENCODING_PCM_FLOAT</code>
     * with {@link AudioTrack} or {@link AudioRecord} can preserve at least 24 bits of
     * integer precision to that device.
     *
     * @see AudioFormat
     *
     * Note: an empty array indicates that the device supports arbitrary encodings.
     */
    public @NonNull int[] getEncodings() {
        return AudioFormat.filterPublicFormats(mPort.formats());
    }

   /**
     * @return The device type identifier of the audio device (i.e. TYPE_BUILTIN_SPEAKER).
     */
    public int getType() {
        return INT_TO_EXT_DEVICE_MAPPING.get(mPort.type(), TYPE_UNKNOWN);
    }

    /** @hide */
    public static int convertDeviceTypeToInternalDevice(int deviceType) {
        return EXT_TO_INT_DEVICE_MAPPING.get(deviceType, AudioSystem.DEVICE_NONE);
    }

    /** @hide */
    public static int convertInternalDeviceToDeviceType(int intDevice) {
        return INT_TO_EXT_DEVICE_MAPPING.get(intDevice, TYPE_UNKNOWN);
    }

    private static final SparseIntArray INT_TO_EXT_DEVICE_MAPPING;

    private static final SparseIntArray EXT_TO_INT_DEVICE_MAPPING;

    static {
        INT_TO_EXT_DEVICE_MAPPING = new SparseIntArray();
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_EARPIECE, TYPE_BUILTIN_EARPIECE);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_SPEAKER, TYPE_BUILTIN_SPEAKER);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_WIRED_HEADSET, TYPE_WIRED_HEADSET);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE, TYPE_WIRED_HEADPHONES);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO, TYPE_BLUETOOTH_SCO);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_HEADSET, TYPE_BLUETOOTH_SCO);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_SCO_CARKIT, TYPE_BLUETOOTH_SCO);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP, TYPE_BLUETOOTH_A2DP);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES, TYPE_BLUETOOTH_A2DP);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER, TYPE_BLUETOOTH_A2DP);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HDMI, TYPE_HDMI);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET, TYPE_DOCK);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_DGTL_DOCK_HEADSET, TYPE_DOCK);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_USB_ACCESSORY, TYPE_USB_ACCESSORY);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_USB_DEVICE, TYPE_USB_DEVICE);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_TELEPHONY_TX, TYPE_TELEPHONY);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_LINE, TYPE_LINE_ANALOG);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_HDMI_ARC, TYPE_HDMI_ARC);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_SPDIF, TYPE_LINE_DIGITAL);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_FM, TYPE_FM);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_AUX_LINE, TYPE_AUX_LINE);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_OUT_IP, TYPE_IP);

        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BUILTIN_MIC, TYPE_BUILTIN_MIC);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_SCO_HEADSET, TYPE_BLUETOOTH_SCO);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_WIRED_HEADSET, TYPE_WIRED_HEADSET);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_HDMI, TYPE_HDMI);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_TELEPHONY_RX, TYPE_TELEPHONY);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BACK_MIC, TYPE_BUILTIN_MIC);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_ANLG_DOCK_HEADSET, TYPE_DOCK);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_DGTL_DOCK_HEADSET, TYPE_DOCK);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_USB_ACCESSORY, TYPE_USB_ACCESSORY);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_USB_DEVICE, TYPE_USB_DEVICE);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_FM_TUNER, TYPE_FM_TUNER);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_TV_TUNER, TYPE_TV_TUNER);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_LINE, TYPE_LINE_ANALOG);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_SPDIF, TYPE_LINE_DIGITAL);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_BLUETOOTH_A2DP, TYPE_BLUETOOTH_A2DP);
        INT_TO_EXT_DEVICE_MAPPING.put(AudioSystem.DEVICE_IN_IP, TYPE_IP);

        // not covered here, legacy
        //AudioSystem.DEVICE_OUT_REMOTE_SUBMIX
        //AudioSystem.DEVICE_IN_REMOTE_SUBMIX

        // privileges mapping to output device
        EXT_TO_INT_DEVICE_MAPPING = new SparseIntArray();
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUILTIN_EARPIECE, AudioSystem.DEVICE_OUT_EARPIECE);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUILTIN_SPEAKER, AudioSystem.DEVICE_OUT_SPEAKER);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_WIRED_HEADSET, AudioSystem.DEVICE_OUT_WIRED_HEADSET);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_WIRED_HEADPHONES, AudioSystem.DEVICE_OUT_WIRED_HEADPHONE);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_LINE_ANALOG, AudioSystem.DEVICE_OUT_LINE);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_LINE_DIGITAL, AudioSystem.DEVICE_OUT_SPDIF);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLUETOOTH_SCO, AudioSystem.DEVICE_OUT_BLUETOOTH_SCO);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BLUETOOTH_A2DP, AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_HDMI, AudioSystem.DEVICE_OUT_HDMI);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_HDMI_ARC, AudioSystem.DEVICE_OUT_HDMI_ARC);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_DEVICE, AudioSystem.DEVICE_OUT_USB_DEVICE);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_USB_ACCESSORY, AudioSystem.DEVICE_OUT_USB_ACCESSORY);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_DOCK, AudioSystem.DEVICE_OUT_ANLG_DOCK_HEADSET);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_FM, AudioSystem.DEVICE_OUT_FM);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_BUILTIN_MIC, AudioSystem.DEVICE_IN_BUILTIN_MIC);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_FM_TUNER, AudioSystem.DEVICE_IN_FM_TUNER);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_TV_TUNER, AudioSystem.DEVICE_IN_TV_TUNER);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_TELEPHONY, AudioSystem.DEVICE_OUT_TELEPHONY_TX);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_AUX_LINE, AudioSystem.DEVICE_OUT_AUX_LINE);
        EXT_TO_INT_DEVICE_MAPPING.put(TYPE_IP, AudioSystem.DEVICE_OUT_IP);
    }
}