Engine.cpp revision 5c233f8b772719371475624edf1002ed80e1d0e8
1/*
2 * Copyright (C) 2015 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#define LOG_TAG "APM::AudioPolicyEngine"
18//#define LOG_NDEBUG 0
19
20//#define VERY_VERBOSE_LOGGING
21#ifdef VERY_VERBOSE_LOGGING
22#define ALOGVV ALOGV
23#else
24#define ALOGVV(a...) do { } while(0)
25#endif
26
27#include "Engine.h"
28#include "Gains.h"
29#include <AudioPolicyManagerObserver.h>
30#include <AudioPort.h>
31#include <IOProfile.h>
32#include <policy.h>
33#include <utils/String8.h>
34#include <utils/Log.h>
35
36namespace android
37{
38namespace audio_policy
39{
40
41Engine::Engine()
42    : mManagerInterface(this),
43      mPhoneState(AUDIO_MODE_NORMAL),
44      mApmObserver(NULL)
45{
46    for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) {
47        mForceUse[i] = AUDIO_POLICY_FORCE_NONE;
48    }
49}
50
51Engine::~Engine()
52{
53}
54
55void Engine::setObserver(AudioPolicyManagerObserver *observer)
56{
57    ALOG_ASSERT(observer != NULL, "Invalid Audio Policy Manager observer");
58    mApmObserver = observer;
59}
60
61status_t Engine::initCheck()
62{
63    return (mApmObserver != NULL) ?  NO_ERROR : NO_INIT;
64}
65
66float Engine::volIndexToAmpl(Volume::device_category category, audio_stream_type_t streamType,
67                             int indexInUi)
68{
69    const StreamDescriptor &streamDesc = mApmObserver->getStreamDescriptors().valueAt(streamType);
70    return Gains::volIndexToAmpl(category, streamDesc, indexInUi);
71}
72
73status_t Engine::initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax)
74{
75    ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax);
76    if (indexMin < 0 || indexMin >= indexMax) {
77        ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d",
78              stream , indexMin, indexMax);
79        return BAD_VALUE;
80    }
81    mApmObserver->getStreamDescriptors().setVolumeIndexMin(stream, indexMin);
82    mApmObserver->getStreamDescriptors().setVolumeIndexMax(stream, indexMax);
83    return NO_ERROR;
84}
85
86void Engine::initializeVolumeCurves(bool isSpeakerDrcEnabled)
87{
88    StreamDescriptorCollection &streams = mApmObserver->getStreamDescriptors();
89
90    for (int i = 0; i < AUDIO_STREAM_CNT; i++) {
91        for (int j = 0; j < Volume::DEVICE_CATEGORY_CNT; j++) {
92            streams.setVolumeCurvePoint(static_cast<audio_stream_type_t>(i),
93                                         static_cast<Volume::device_category>(j),
94                                         Gains::sVolumeProfiles[i][j]);
95        }
96    }
97
98    // Check availability of DRC on speaker path: if available, override some of the speaker curves
99    if (isSpeakerDrcEnabled) {
100        streams.setVolumeCurvePoint(AUDIO_STREAM_SYSTEM, Volume::DEVICE_CATEGORY_SPEAKER,
101                Gains::sDefaultSystemVolumeCurveDrc);
102        streams.setVolumeCurvePoint(AUDIO_STREAM_RING, Volume::DEVICE_CATEGORY_SPEAKER,
103                Gains::sSpeakerSonificationVolumeCurveDrc);
104        streams.setVolumeCurvePoint(AUDIO_STREAM_ALARM, Volume::DEVICE_CATEGORY_SPEAKER,
105                Gains::sSpeakerSonificationVolumeCurveDrc);
106        streams.setVolumeCurvePoint(AUDIO_STREAM_NOTIFICATION, Volume::DEVICE_CATEGORY_SPEAKER,
107                Gains::sSpeakerSonificationVolumeCurveDrc);
108        streams.setVolumeCurvePoint(AUDIO_STREAM_MUSIC, Volume::DEVICE_CATEGORY_SPEAKER,
109                Gains::sSpeakerMediaVolumeCurveDrc);
110        streams.setVolumeCurvePoint(AUDIO_STREAM_ACCESSIBILITY, Volume::DEVICE_CATEGORY_SPEAKER,
111                Gains::sSpeakerMediaVolumeCurveDrc);
112    }
113}
114
115
116status_t Engine::setPhoneState(audio_mode_t state)
117{
118    ALOGV("setPhoneState() state %d", state);
119
120    if (state < 0 || state >= AUDIO_MODE_CNT) {
121        ALOGW("setPhoneState() invalid state %d", state);
122        return BAD_VALUE;
123    }
124
125    if (state == mPhoneState ) {
126        ALOGW("setPhoneState() setting same state %d", state);
127        return BAD_VALUE;
128    }
129
130    // store previous phone state for management of sonification strategy below
131    int oldState = mPhoneState;
132    mPhoneState = state;
133    StreamDescriptorCollection &streams = mApmObserver->getStreamDescriptors();
134    // are we entering or starting a call
135    if (!is_state_in_call(oldState) && is_state_in_call(state)) {
136        ALOGV("  Entering call in setPhoneState()");
137        for (int j = 0; j < Volume::DEVICE_CATEGORY_CNT; j++) {
138            streams.setVolumeCurvePoint(AUDIO_STREAM_DTMF, static_cast<Volume::device_category>(j),
139                                         Gains::sVolumeProfiles[AUDIO_STREAM_VOICE_CALL][j]);
140        }
141    } else if (is_state_in_call(oldState) && !is_state_in_call(state)) {
142        ALOGV("  Exiting call in setPhoneState()");
143        for (int j = 0; j < Volume::DEVICE_CATEGORY_CNT; j++) {
144            streams.setVolumeCurvePoint(AUDIO_STREAM_DTMF, static_cast<Volume::device_category>(j),
145                                         Gains::sVolumeProfiles[AUDIO_STREAM_DTMF][j]);
146        }
147    }
148    return NO_ERROR;
149}
150
151status_t Engine::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config)
152{
153    switch(usage) {
154    case AUDIO_POLICY_FORCE_FOR_COMMUNICATION:
155        if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO &&
156            config != AUDIO_POLICY_FORCE_NONE) {
157            ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config);
158            return BAD_VALUE;
159        }
160        mForceUse[usage] = config;
161        break;
162    case AUDIO_POLICY_FORCE_FOR_MEDIA:
163        if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP &&
164            config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
165            config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
166            config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE &&
167            config != AUDIO_POLICY_FORCE_NO_BT_A2DP && config != AUDIO_POLICY_FORCE_SPEAKER ) {
168            ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config);
169            return BAD_VALUE;
170        }
171        mForceUse[usage] = config;
172        break;
173    case AUDIO_POLICY_FORCE_FOR_RECORD:
174        if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
175            config != AUDIO_POLICY_FORCE_NONE) {
176            ALOGW("setForceUse() invalid config %d for FOR_RECORD", config);
177            return BAD_VALUE;
178        }
179        mForceUse[usage] = config;
180        break;
181    case AUDIO_POLICY_FORCE_FOR_DOCK:
182        if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK &&
183            config != AUDIO_POLICY_FORCE_BT_DESK_DOCK &&
184            config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY &&
185            config != AUDIO_POLICY_FORCE_ANALOG_DOCK &&
186            config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) {
187            ALOGW("setForceUse() invalid config %d for FOR_DOCK", config);
188        }
189        mForceUse[usage] = config;
190        break;
191    case AUDIO_POLICY_FORCE_FOR_SYSTEM:
192        if (config != AUDIO_POLICY_FORCE_NONE &&
193            config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
194            ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config);
195        }
196        mForceUse[usage] = config;
197        break;
198    case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO:
199        if (config != AUDIO_POLICY_FORCE_NONE &&
200            config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) {
201            ALOGW("setForceUse() invalid config %d forHDMI_SYSTEM_AUDIO", config);
202        }
203        mForceUse[usage] = config;
204        break;
205    default:
206        ALOGW("setForceUse() invalid usage %d", usage);
207        break;
208    }
209    return NO_ERROR;
210}
211
212routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream)
213{
214    // stream to strategy mapping
215    switch (stream) {
216    case AUDIO_STREAM_VOICE_CALL:
217    case AUDIO_STREAM_BLUETOOTH_SCO:
218        return STRATEGY_PHONE;
219    case AUDIO_STREAM_RING:
220    case AUDIO_STREAM_ALARM:
221        return STRATEGY_SONIFICATION;
222    case AUDIO_STREAM_NOTIFICATION:
223        return STRATEGY_SONIFICATION_RESPECTFUL;
224    case AUDIO_STREAM_DTMF:
225        return STRATEGY_DTMF;
226    default:
227        ALOGE("unknown stream type %d", stream);
228    case AUDIO_STREAM_SYSTEM:
229        // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs
230        // while key clicks are played produces a poor result
231    case AUDIO_STREAM_MUSIC:
232        return STRATEGY_MEDIA;
233    case AUDIO_STREAM_ENFORCED_AUDIBLE:
234        return STRATEGY_ENFORCED_AUDIBLE;
235    case AUDIO_STREAM_TTS:
236        return STRATEGY_TRANSMITTED_THROUGH_SPEAKER;
237    case AUDIO_STREAM_ACCESSIBILITY:
238        return STRATEGY_ACCESSIBILITY;
239    case AUDIO_STREAM_REROUTING:
240        return STRATEGY_REROUTING;
241    }
242}
243
244routing_strategy Engine::getStrategyForUsage(audio_usage_t usage)
245{
246    const AudioOutputCollection &outputs = mApmObserver->getOutputs();
247
248    // usage to strategy mapping
249    switch (usage) {
250    case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY:
251        if (outputs.isStreamActive(AUDIO_STREAM_RING) ||
252                outputs.isStreamActive(AUDIO_STREAM_ALARM)) {
253            return STRATEGY_SONIFICATION;
254        }
255        if (isInCall()) {
256            return STRATEGY_PHONE;
257        }
258        return STRATEGY_ACCESSIBILITY;
259
260    case AUDIO_USAGE_MEDIA:
261    case AUDIO_USAGE_GAME:
262    case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE:
263    case AUDIO_USAGE_ASSISTANCE_SONIFICATION:
264        return STRATEGY_MEDIA;
265
266    case AUDIO_USAGE_VOICE_COMMUNICATION:
267        return STRATEGY_PHONE;
268
269    case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING:
270        return STRATEGY_DTMF;
271
272    case AUDIO_USAGE_ALARM:
273    case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE:
274        return STRATEGY_SONIFICATION;
275
276    case AUDIO_USAGE_NOTIFICATION:
277    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST:
278    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT:
279    case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED:
280    case AUDIO_USAGE_NOTIFICATION_EVENT:
281        return STRATEGY_SONIFICATION_RESPECTFUL;
282
283    case AUDIO_USAGE_UNKNOWN:
284    default:
285        return STRATEGY_MEDIA;
286    }
287}
288
289audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const
290{
291    const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
292    const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
293
294    const AudioOutputCollection &outputs = mApmObserver->getOutputs();
295
296    uint32_t device = AUDIO_DEVICE_NONE;
297    uint32_t availableOutputDevicesType = availableOutputDevices.types();
298
299    switch (strategy) {
300
301    case STRATEGY_TRANSMITTED_THROUGH_SPEAKER:
302        device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
303        if (!device) {
304            ALOGE("getDeviceForStrategy() no device found for "\
305                    "STRATEGY_TRANSMITTED_THROUGH_SPEAKER");
306        }
307        break;
308
309    case STRATEGY_SONIFICATION_RESPECTFUL:
310        if (isInCall()) {
311            device = getDeviceForStrategy(STRATEGY_SONIFICATION);
312        } else if (outputs.isStreamActiveRemotely(AUDIO_STREAM_MUSIC,
313                SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
314            // while media is playing on a remote device, use the the sonification behavior.
315            // Note that we test this usecase before testing if media is playing because
316            //   the isStreamActive() method only informs about the activity of a stream, not
317            //   if it's for local playback. Note also that we use the same delay between both tests
318            device = getDeviceForStrategy(STRATEGY_SONIFICATION);
319            //user "safe" speaker if available instead of normal speaker to avoid triggering
320            //other acoustic safety mechanisms for notification
321            if (device == AUDIO_DEVICE_OUT_SPEAKER && (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE))
322                device = AUDIO_DEVICE_OUT_SPEAKER_SAFE;
323        } else if (outputs.isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) {
324            // while media is playing (or has recently played), use the same device
325            device = getDeviceForStrategy(STRATEGY_MEDIA);
326        } else {
327            // when media is not playing anymore, fall back on the sonification behavior
328            device = getDeviceForStrategy(STRATEGY_SONIFICATION);
329            //user "safe" speaker if available instead of normal speaker to avoid triggering
330            //other acoustic safety mechanisms for notification
331            if (device == AUDIO_DEVICE_OUT_SPEAKER && (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE))
332                device = AUDIO_DEVICE_OUT_SPEAKER_SAFE;
333        }
334        break;
335
336    case STRATEGY_DTMF:
337        if (!isInCall()) {
338            // when off call, DTMF strategy follows the same rules as MEDIA strategy
339            device = getDeviceForStrategy(STRATEGY_MEDIA);
340            break;
341        }
342        // when in call, DTMF and PHONE strategies follow the same rules
343        // FALL THROUGH
344
345    case STRATEGY_PHONE:
346        // Force use of only devices on primary output if:
347        // - in call AND
348        //   - cannot route from voice call RX OR
349        //   - audio HAL version is < 3.0 and TX device is on the primary HW module
350        if (getPhoneState() == AUDIO_MODE_IN_CALL) {
351            audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION);
352            sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
353            audio_devices_t availPrimaryInputDevices =
354                 availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle());
355            audio_devices_t availPrimaryOutputDevices =
356                    primaryOutput->supportedDevices() & availableOutputDevices.types();
357
358            if (((availableInputDevices.types() &
359                    AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) ||
360                    (((txDevice & availPrimaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) &&
361                         (primaryOutput->getAudioPort()->mModule->mHalVersion <
362                             AUDIO_DEVICE_API_VERSION_3_0))) {
363                availableOutputDevicesType = availPrimaryOutputDevices;
364            }
365        }
366        // for phone strategy, we first consider the forced use and then the available devices by order
367        // of priority
368        switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
369        case AUDIO_POLICY_FORCE_BT_SCO:
370            if (!isInCall() || strategy != STRATEGY_DTMF) {
371                device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT;
372                if (device) break;
373            }
374            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET;
375            if (device) break;
376            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO;
377            if (device) break;
378            // if SCO device is requested but no SCO device is available, fall back to default case
379            // FALL THROUGH
380
381        default:    // FORCE_NONE
382            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP
383            if (!isInCall() &&
384                    (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
385                    (outputs.getA2dpOutput() != 0)) {
386                device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
387                if (device) break;
388                device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
389                if (device) break;
390            }
391            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
392            if (device) break;
393            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
394            if (device) break;
395            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
396            if (device) break;
397            if (!isInCall()) {
398                device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
399                if (device) break;
400                device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
401                if (device) break;
402                device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
403                if (device) break;
404                device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
405                if (device) break;
406            }
407            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE;
408            if (device) break;
409            device = mApmObserver->getDefaultOutputDevice()->type();
410            if (device == AUDIO_DEVICE_NONE) {
411                ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE");
412            }
413            break;
414
415        case AUDIO_POLICY_FORCE_SPEAKER:
416            // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to
417            // A2DP speaker when forcing to speaker output
418            if (!isInCall() &&
419                    (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
420                    (outputs.getA2dpOutput() != 0)) {
421                device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
422                if (device) break;
423            }
424            if (!isInCall()) {
425                device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
426                if (device) break;
427                device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
428                if (device) break;
429                device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
430                if (device) break;
431                device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
432                if (device) break;
433                device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
434                if (device) break;
435            }
436            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
437            if (device) break;
438            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
439            if (device) break;
440            device = mApmObserver->getDefaultOutputDevice()->type();
441            if (device == AUDIO_DEVICE_NONE) {
442                ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER");
443            }
444            break;
445        }
446    break;
447
448    case STRATEGY_SONIFICATION:
449
450        // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by
451        // handleIncallSonification().
452        if (isInCall()) {
453            device = getDeviceForStrategy(STRATEGY_PHONE);
454            break;
455        }
456        // FALL THROUGH
457
458    case STRATEGY_ENFORCED_AUDIBLE:
459        // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION
460        // except:
461        //   - when in call where it doesn't default to STRATEGY_PHONE behavior
462        //   - in countries where not enforced in which case it follows STRATEGY_MEDIA
463
464        if ((strategy == STRATEGY_SONIFICATION) ||
465                (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) {
466            device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
467            if (device == AUDIO_DEVICE_NONE) {
468                ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION");
469            }
470        }
471        // The second device used for sonification is the same as the device used by media strategy
472        // FALL THROUGH
473
474    // FIXME: STRATEGY_ACCESSIBILITY and STRATEGY_REROUTING follow STRATEGY_MEDIA for now
475    case STRATEGY_ACCESSIBILITY:
476        if (strategy == STRATEGY_ACCESSIBILITY) {
477            // do not route accessibility prompts to a digital output currently configured with a
478            // compressed format as they would likely not be mixed and dropped.
479            for (size_t i = 0; i < outputs.size(); i++) {
480                sp<AudioOutputDescriptor> desc = outputs.valueAt(i);
481                audio_devices_t devices = desc->device() &
482                    (AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_HDMI_ARC);
483                if (desc->isActive() && !audio_is_linear_pcm(desc->mFormat) &&
484                        devices != AUDIO_DEVICE_NONE) {
485                    availableOutputDevicesType = availableOutputDevices.types() & ~devices;
486                }
487            }
488        }
489        // FALL THROUGH
490
491    case STRATEGY_REROUTING:
492    case STRATEGY_MEDIA: {
493        uint32_t device2 = AUDIO_DEVICE_NONE;
494        if (strategy != STRATEGY_SONIFICATION) {
495            // no sonification on remote submix (e.g. WFD)
496            if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) {
497                device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX;
498            }
499        }
500        if ((device2 == AUDIO_DEVICE_NONE) &&
501                (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) &&
502                (outputs.getA2dpOutput() != 0)) {
503            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP;
504            if (device2 == AUDIO_DEVICE_NONE) {
505                device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES;
506            }
507            if (device2 == AUDIO_DEVICE_NONE) {
508                device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER;
509            }
510        }
511        if ((device2 == AUDIO_DEVICE_NONE) &&
512            (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER)) {
513            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
514        }
515        if (device2 == AUDIO_DEVICE_NONE) {
516            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE;
517        }
518        if (device2 == AUDIO_DEVICE_NONE) {
519            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE;
520        }
521        if (device2 == AUDIO_DEVICE_NONE) {
522            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET;
523        }
524        if (device2 == AUDIO_DEVICE_NONE) {
525            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY;
526        }
527        if (device2 == AUDIO_DEVICE_NONE) {
528            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE;
529        }
530        if (device2 == AUDIO_DEVICE_NONE) {
531            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET;
532        }
533        if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) {
534            // no sonification on aux digital (e.g. HDMI)
535            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL;
536        }
537        if ((device2 == AUDIO_DEVICE_NONE) &&
538                (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) {
539            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET;
540        }
541        if (device2 == AUDIO_DEVICE_NONE) {
542            device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER;
543        }
544        int device3 = AUDIO_DEVICE_NONE;
545        if (strategy == STRATEGY_MEDIA) {
546            // ARC, SPDIF and AUX_LINE can co-exist with others.
547            device3 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI_ARC;
548            device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPDIF);
549            device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_LINE);
550        }
551
552        device2 |= device3;
553        // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or
554        // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise
555        device |= device2;
556
557        // If hdmi system audio mode is on, remove speaker out of output list.
558        if ((strategy == STRATEGY_MEDIA) &&
559            (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] ==
560                AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) {
561            device &= ~AUDIO_DEVICE_OUT_SPEAKER;
562        }
563
564        if (device) break;
565        device = mApmObserver->getDefaultOutputDevice()->type();
566        if (device == AUDIO_DEVICE_NONE) {
567            ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA");
568        }
569        } break;
570
571    default:
572        ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy);
573        break;
574    }
575
576    ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device);
577    return device;
578}
579
580
581audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const
582{
583    const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices();
584    const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices();
585    const AudioOutputCollection &outputs = mApmObserver->getOutputs();
586    audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN;
587
588    uint32_t device = AUDIO_DEVICE_NONE;
589
590    switch (inputSource) {
591    case AUDIO_SOURCE_VOICE_UPLINK:
592      if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
593          device = AUDIO_DEVICE_IN_VOICE_CALL;
594          break;
595      }
596      break;
597
598    case AUDIO_SOURCE_DEFAULT:
599    case AUDIO_SOURCE_MIC:
600    if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) {
601        device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP;
602    } else if ((mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO) &&
603        (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) {
604        device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
605    } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
606        device = AUDIO_DEVICE_IN_WIRED_HEADSET;
607    } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
608        device = AUDIO_DEVICE_IN_USB_DEVICE;
609    } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
610        device = AUDIO_DEVICE_IN_BUILTIN_MIC;
611    }
612    break;
613
614    case AUDIO_SOURCE_VOICE_COMMUNICATION:
615        // Allow only use of devices on primary input if in call and HAL does not support routing
616        // to voice call path.
617        if ((getPhoneState() == AUDIO_MODE_IN_CALL) &&
618                (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) {
619            sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput();
620            availableDeviceTypes =
621                    availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle())
622                    & ~AUDIO_DEVICE_BIT_IN;
623        }
624
625        switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) {
626        case AUDIO_POLICY_FORCE_BT_SCO:
627            // if SCO device is requested but no SCO device is available, fall back to default case
628            if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
629                device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
630                break;
631            }
632            // FALL THROUGH
633
634        default:    // FORCE_NONE
635            if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
636                device = AUDIO_DEVICE_IN_WIRED_HEADSET;
637            } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
638                device = AUDIO_DEVICE_IN_USB_DEVICE;
639            } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
640                device = AUDIO_DEVICE_IN_BUILTIN_MIC;
641            }
642            break;
643
644        case AUDIO_POLICY_FORCE_SPEAKER:
645            if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
646                device = AUDIO_DEVICE_IN_BACK_MIC;
647            } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
648                device = AUDIO_DEVICE_IN_BUILTIN_MIC;
649            }
650            break;
651        }
652        break;
653
654    case AUDIO_SOURCE_VOICE_RECOGNITION:
655    case AUDIO_SOURCE_HOTWORD:
656        if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO &&
657                availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) {
658            device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET;
659        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) {
660            device = AUDIO_DEVICE_IN_WIRED_HEADSET;
661        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) {
662            device = AUDIO_DEVICE_IN_USB_DEVICE;
663        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
664            device = AUDIO_DEVICE_IN_BUILTIN_MIC;
665        }
666        break;
667    case AUDIO_SOURCE_CAMCORDER:
668        if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) {
669            device = AUDIO_DEVICE_IN_BACK_MIC;
670        } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) {
671            device = AUDIO_DEVICE_IN_BUILTIN_MIC;
672        }
673        break;
674    case AUDIO_SOURCE_VOICE_DOWNLINK:
675    case AUDIO_SOURCE_VOICE_CALL:
676        if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) {
677            device = AUDIO_DEVICE_IN_VOICE_CALL;
678        }
679        break;
680    case AUDIO_SOURCE_REMOTE_SUBMIX:
681        if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) {
682            device = AUDIO_DEVICE_IN_REMOTE_SUBMIX;
683        }
684        break;
685     case AUDIO_SOURCE_FM_TUNER:
686        if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) {
687            device = AUDIO_DEVICE_IN_FM_TUNER;
688        }
689        break;
690    default:
691        ALOGW("getDeviceForInputSource() invalid input source %d", inputSource);
692        break;
693    }
694    ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device);
695    return device;
696}
697
698template <>
699AudioPolicyManagerInterface *Engine::queryInterface()
700{
701    return &mManagerInterface;
702}
703
704} // namespace audio_policy
705} // namespace android
706
707
708