1 /*
2  * Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
3  * Not a contribution.
4  *
5  * Copyright (C) 2009 The Android Open Source Project
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  * This file was modified by Dolby Laboratories, Inc. The portions of the
20  * code that are surrounded by "DOLBY..." are copyrighted and
21  * licensed separately, as follows:
22  *
23  *  (C) 2015 Dolby Laboratories, Inc.
24  *
25  * Licensed under the Apache License, Version 2.0 (the "License");
26  * you may not use this file except in compliance with the License.
27  * You may obtain a copy of the License at
28  *
29  *    http://www.apache.org/licenses/LICENSE-2.0
30  *
31  * Unless required by applicable law or agreed to in writing, software
32  * distributed under the License is distributed on an "AS IS" BASIS,
33  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34  * See the License for the specific language governing permissions and
35  * limitations under the License.
36  */
37 
38 #define LOG_TAG "AudioPolicyManagerCustom"
39 //#define LOG_NDEBUG 0
40 
41 //#define VERY_VERBOSE_LOGGING
42 #ifdef VERY_VERBOSE_LOGGING
43 #define ALOGVV ALOGV
44 #else
45 #define ALOGVV(a...) do { } while(0)
46 #endif
47 
48 #define MIN(a, b) ((a) < (b) ? (a) : (b))
49 
50 // A device mask for all audio output devices that are considered "remote" when evaluating
51 // active output devices in isStreamActiveRemotely()
52 #define APM_AUDIO_OUT_DEVICE_REMOTE_ALL  AUDIO_DEVICE_OUT_REMOTE_SUBMIX
53 // A device mask for all audio input and output devices where matching inputs/outputs on device
54 // type alone is not enough: the address must match too
55 #define APM_AUDIO_DEVICE_MATCH_ADDRESS_ALL (AUDIO_DEVICE_IN_REMOTE_SUBMIX | \
56                                             AUDIO_DEVICE_OUT_REMOTE_SUBMIX)
57 // Following delay should be used if the calculated routing delay from all active
58 // input streams is higher than this value
59 #define MAX_VOICE_CALL_START_DELAY_MS 100
60 
61 #include <inttypes.h>
62 #include <math.h>
63 
64 #include <cutils/properties.h>
65 #include <utils/Log.h>
66 #include <hardware/audio.h>
67 #include <hardware/audio_effect.h>
68 #include <media/AudioParameter.h>
69 #include <soundtrigger/SoundTrigger.h>
70 #include "AudioPolicyManager.h"
71 #include <policy.h>
72 #ifdef DOLBY_ENABLE
73 #include "DolbyAudioPolicy_impl.h"
74 #endif // DOLBY_END
75 
76 namespace android {
77 #ifdef VOICE_CONCURRENCY
getFallBackPath()78 audio_output_flags_t AudioPolicyManagerCustom::getFallBackPath()
79 {
80     audio_output_flags_t flag = AUDIO_OUTPUT_FLAG_FAST;
81     char propValue[PROPERTY_VALUE_MAX];
82 
83     if (property_get("voice.conc.fallbackpath", propValue, NULL)) {
84         if (!strncmp(propValue, "deep-buffer", 11)) {
85             flag = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
86         }
87         else if (!strncmp(propValue, "fast", 4)) {
88             flag = AUDIO_OUTPUT_FLAG_FAST;
89         }
90         else {
91             ALOGD("voice_conc:not a recognised path(%s) in prop voice.conc.fallbackpath",
92                 propValue);
93         }
94     }
95     else {
96         ALOGD("voice_conc:prop voice.conc.fallbackpath not set");
97     }
98 
99     ALOGD("voice_conc:picked up flag(0x%x) from prop voice.conc.fallbackpath",
100         flag);
101 
102     return flag;
103 }
104 #endif /*VOICE_CONCURRENCY*/
105 // ----------------------------------------------------------------------------
106 // AudioPolicyInterface implementation
107 // ----------------------------------------------------------------------------
createAudioPolicyManager(AudioPolicyClientInterface * clientInterface)108 extern "C" AudioPolicyInterface* createAudioPolicyManager(
109          AudioPolicyClientInterface *clientInterface)
110 {
111      return new AudioPolicyManagerCustom(clientInterface);
112 }
113 
destroyAudioPolicyManager(AudioPolicyInterface * interface)114 extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
115 {
116      delete interface;
117 }
118 
setDeviceConnectionStateInt(audio_devices_t device,audio_policy_dev_state_t state,const char * device_address,const char * device_name)119 status_t AudioPolicyManagerCustom::setDeviceConnectionStateInt(audio_devices_t device,
120                                                          audio_policy_dev_state_t state,
121                                                          const char *device_address,
122                                                          const char *device_name)
123 {
124     ALOGV("setDeviceConnectionStateInt() device: 0x%X, state %d, address %s name %s",
125             device, state, device_address, device_name);
126 
127     // connect/disconnect only 1 device at a time
128     if (!audio_is_output_device(device) && !audio_is_input_device(device)) return BAD_VALUE;
129 
130     sp<DeviceDescriptor> devDesc =
131             mHwModules.getDeviceDescriptor(device, device_address, device_name);
132 
133     // handle output devices
134     if (audio_is_output_device(device)) {
135         SortedVector <audio_io_handle_t> outputs;
136 
137         ssize_t index = mAvailableOutputDevices.indexOf(devDesc);
138 
139         // save a copy of the opened output descriptors before any output is opened or closed
140         // by checkOutputsForDevice(). This will be needed by checkOutputForAllStrategies()
141         mPreviousOutputs = mOutputs;
142         switch (state)
143         {
144         // handle output device connection
145         case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
146             if (index >= 0) {
147 #ifdef AUDIO_EXTN_HDMI_SPK_ENABLED
148                 if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
149                    if (!strncmp(device_address, "hdmi_spkr", 9)) {
150                         mHdmiAudioDisabled = false;
151                     } else {
152                         mHdmiAudioEvent = true;
153                     }
154                 }
155 #endif
156                 ALOGW("setDeviceConnectionState() device already connected: %x", device);
157                 return INVALID_OPERATION;
158             }
159             ALOGV("setDeviceConnectionState() connecting device %x", device);
160 
161             // register new device as available
162             index = mAvailableOutputDevices.add(devDesc);
163 #ifdef AUDIO_EXTN_HDMI_SPK_ENABLED
164             if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
165                 if (!strncmp(device_address, "hdmi_spkr", 9)) {
166                     mHdmiAudioDisabled = false;
167                 } else {
168                     mHdmiAudioEvent = true;
169                 }
170                 if (mHdmiAudioDisabled || !mHdmiAudioEvent) {
171                     mAvailableOutputDevices.remove(devDesc);
172                     ALOGW("HDMI sink not connected, do not route audio to HDMI out");
173                     return INVALID_OPERATION;
174                 }
175             }
176 #endif
177             if (index >= 0) {
178                 sp<HwModule> module = mHwModules.getModuleForDevice(device);
179                 if (module == 0) {
180                     ALOGD("setDeviceConnectionState() could not find HW module for device %08x",
181                           device);
182                     mAvailableOutputDevices.remove(devDesc);
183                     return INVALID_OPERATION;
184                 }
185                 mAvailableOutputDevices[index]->attach(module);
186             } else {
187                 return NO_MEMORY;
188             }
189 
190             if (checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress) != NO_ERROR) {
191                 mAvailableOutputDevices.remove(devDesc);
192                 return INVALID_OPERATION;
193             }
194             // Propagate device availability to Engine
195             mEngine->setDeviceConnectionState(devDesc, state);
196 
197             // outputs should never be empty here
198             ALOG_ASSERT(outputs.size() != 0, "setDeviceConnectionState():"
199                     "checkOutputsForDevice() returned no outputs but status OK");
200             ALOGV("setDeviceConnectionState() checkOutputsForDevice() returned %zu outputs",
201                   outputs.size());
202 
203             // Send connect to HALs
204             AudioParameter param = AudioParameter(devDesc->mAddress);
205             param.addInt(String8(AUDIO_PARAMETER_DEVICE_CONNECT), device);
206             mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
207 
208             } break;
209         // handle output device disconnection
210         case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
211             if (index < 0) {
212 #ifdef AUDIO_EXTN_HDMI_SPK_ENABLED
213                 if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
214                     if (!strncmp(device_address, "hdmi_spkr", 9)) {
215                         mHdmiAudioDisabled = true;
216                     } else {
217                         mHdmiAudioEvent = false;
218                     }
219                 }
220 #endif
221                 ALOGW("setDeviceConnectionState() device not connected: %x", device);
222                 return INVALID_OPERATION;
223             }
224 
225             ALOGV("setDeviceConnectionState() disconnecting output device %x", device);
226 
227             // Send Disconnect to HALs
228             AudioParameter param = AudioParameter(devDesc->mAddress);
229             param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device);
230             mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
231 
232             // remove device from available output devices
233             mAvailableOutputDevices.remove(devDesc);
234 #ifdef AUDIO_EXTN_HDMI_SPK_ENABLED
235             if ((popcount(device) == 1) && (device & AUDIO_DEVICE_OUT_AUX_DIGITAL)) {
236                 if (!strncmp(device_address, "hdmi_spkr", 9)) {
237                     mHdmiAudioDisabled = true;
238                 } else {
239                     mHdmiAudioEvent = false;
240                 }
241             }
242 #endif
243 
244             checkOutputsForDevice(devDesc, state, outputs, devDesc->mAddress);
245 
246             // Propagate device availability to Engine
247             mEngine->setDeviceConnectionState(devDesc, state);
248             } break;
249 
250         default:
251             ALOGE("setDeviceConnectionState() invalid state: %x", state);
252             return BAD_VALUE;
253         }
254 
255         // checkA2dpSuspend must run before checkOutputForAllStrategies so that A2DP
256         // output is suspended before any tracks are moved to it
257         checkA2dpSuspend();
258         checkOutputForAllStrategies();
259         // outputs must be closed after checkOutputForAllStrategies() is executed
260         if (!outputs.isEmpty()) {
261             for (size_t i = 0; i < outputs.size(); i++) {
262                 sp<SwAudioOutputDescriptor> desc = mOutputs.valueFor(outputs[i]);
263                 // close unused outputs after device disconnection or direct outputs that have been
264                 // opened by checkOutputsForDevice() to query dynamic parameters
265                 if ((state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE) ||
266                         (((desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT) != 0) &&
267                          (desc->mDirectOpenCount == 0))) {
268                     closeOutput(outputs[i]);
269                 }
270             }
271             // check again after closing A2DP output to reset mA2dpSuspended if needed
272             checkA2dpSuspend();
273         }
274 
275         updateDevicesAndOutputs();
276 #ifdef DOLBY_ENABLE
277         // Before closing the opened outputs, update endpoint property with device capabilities
278         audio_devices_t audioOutputDevice = getDeviceForStrategy(getStrategy(AUDIO_STREAM_MUSIC), true);
279         mDolbyAudioPolicy.setEndpointSystemProperty(audioOutputDevice, mHwModules);
280 #endif // DOLBY_END
281         if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
282             audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
283             updateCallRouting(newDevice);
284         }
285 
286 #ifdef FM_POWER_OPT
287         // handle FM device connection state to trigger FM AFE loopback
288         if(device == AUDIO_DEVICE_OUT_FM && hasPrimaryOutput()) {
289            audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
290            if (state == AUDIO_POLICY_DEVICE_STATE_AVAILABLE) {
291                mPrimaryOutput->changeRefCount(AUDIO_STREAM_MUSIC, 1);
292                newDevice = newDevice | AUDIO_DEVICE_OUT_FM;
293            } else {
294                mPrimaryOutput->changeRefCount(AUDIO_STREAM_MUSIC, -1);
295            }
296            AudioParameter param = AudioParameter();
297            param.addInt(String8("handle_fm"), (int)newDevice);
298            mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, param.toString());
299         }
300 #endif /* FM_POWER_OPT end */
301 
302         for (size_t i = 0; i < mOutputs.size(); i++) {
303             sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
304             if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || (desc != mPrimaryOutput)) {
305                 audio_devices_t newDevice = getNewOutputDevice(desc, true /*fromCache*/);
306                 // do not force device change on duplicated output because if device is 0, it will
307                 // also force a device 0 for the two outputs it is duplicated to which may override
308                 // a valid device selection on those outputs.
309                 bool force = !desc->isDuplicated()
310                         && (!device_distinguishes_on_address(device)
311                                 // always force when disconnecting (a non-duplicated device)
312                                 || (state == AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE));
313                 setOutputDevice(desc, newDevice, force, 0);
314             }
315         }
316 
317         mpClientInterface->onAudioPortListUpdate();
318         return NO_ERROR;
319     }  // end if is output device
320 
321     // handle input devices
322     if (audio_is_input_device(device)) {
323         SortedVector <audio_io_handle_t> inputs;
324 
325         ssize_t index = mAvailableInputDevices.indexOf(devDesc);
326         switch (state)
327         {
328         // handle input device connection
329         case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: {
330             if (index >= 0) {
331                 ALOGW("setDeviceConnectionState() device already connected: %d", device);
332                 return INVALID_OPERATION;
333             }
334             sp<HwModule> module = mHwModules.getModuleForDevice(device);
335             if (module == NULL) {
336                 ALOGW("setDeviceConnectionState(): could not find HW module for device %08x",
337                       device);
338                 return INVALID_OPERATION;
339             }
340             if (checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress) != NO_ERROR) {
341                 return INVALID_OPERATION;
342             }
343 
344             index = mAvailableInputDevices.add(devDesc);
345             if (index >= 0) {
346                 mAvailableInputDevices[index]->attach(module);
347             } else {
348                 return NO_MEMORY;
349             }
350 
351             // Set connect to HALs
352             AudioParameter param = AudioParameter(devDesc->mAddress);
353             param.addInt(String8(AUDIO_PARAMETER_DEVICE_CONNECT), device);
354             mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
355 
356             // Propagate device availability to Engine
357             mEngine->setDeviceConnectionState(devDesc, state);
358         } break;
359 
360         // handle input device disconnection
361         case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: {
362             if (index < 0) {
363                 ALOGW("setDeviceConnectionState() device not connected: %d", device);
364                 return INVALID_OPERATION;
365             }
366 
367             ALOGV("setDeviceConnectionState() disconnecting input device %x", device);
368 
369             // Set Disconnect to HALs
370             AudioParameter param = AudioParameter(devDesc->mAddress);
371             param.addInt(String8(AUDIO_PARAMETER_DEVICE_DISCONNECT), device);
372             mpClientInterface->setParameters(AUDIO_IO_HANDLE_NONE, param.toString());
373 
374             checkInputsForDevice(devDesc, state, inputs, devDesc->mAddress);
375             mAvailableInputDevices.remove(devDesc);
376 
377             // Propagate device availability to Engine
378             mEngine->setDeviceConnectionState(devDesc, state);
379         } break;
380 
381         default:
382             ALOGE("setDeviceConnectionState() invalid state: %x", state);
383             return BAD_VALUE;
384         }
385 
386         closeAllInputs();
387 
388         if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
389             audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
390             updateCallRouting(newDevice);
391         }
392 
393         mpClientInterface->onAudioPortListUpdate();
394         return NO_ERROR;
395     } // end if is input device
396 
397     ALOGW("setDeviceConnectionState() invalid device: %x", device);
398     return BAD_VALUE;
399 }
400 // This function checks for the parameters which can be offloaded.
401 // This can be enhanced depending on the capability of the DSP and policy
402 // of the system.
isOffloadSupported(const audio_offload_info_t & offloadInfo)403 bool AudioPolicyManagerCustom::isOffloadSupported(const audio_offload_info_t& offloadInfo)
404 {
405     ALOGV("isOffloadSupported: SR=%u, CM=0x%x, Format=0x%x, StreamType=%d,"
406      " BitRate=%u, duration=%" PRId64 " us, has_video=%d",
407      offloadInfo.sample_rate, offloadInfo.channel_mask,
408      offloadInfo.format,
409      offloadInfo.stream_type, offloadInfo.bit_rate, offloadInfo.duration_us,
410      offloadInfo.has_video);
411 #ifdef VOICE_CONCURRENCY
412     char concpropValue[PROPERTY_VALUE_MAX];
413     if (property_get("voice.playback.conc.disabled", concpropValue, NULL)) {
414          bool propenabled = atoi(concpropValue) || !strncmp("true", concpropValue, 4);
415          if (propenabled) {
416             if (isInCall())
417             {
418                 ALOGD("\n copl: blocking  compress offload on call mode\n");
419                 return false;
420             }
421          }
422     }
423 #endif
424 #ifdef RECORD_PLAY_CONCURRENCY
425     char recConcPropValue[PROPERTY_VALUE_MAX];
426     bool prop_rec_play_enabled = false;
427 
428     if (property_get("rec.playback.conc.disabled", recConcPropValue, NULL)) {
429         prop_rec_play_enabled = atoi(recConcPropValue) || !strncmp("true", recConcPropValue, 4);
430     }
431 
432     if ((prop_rec_play_enabled) &&
433          ((true == mIsInputRequestOnProgress) || (mInputs.activeInputsCount() > 0))) {
434         ALOGD("copl: blocking  compress offload for record concurrency");
435         return false;
436     }
437 #endif
438     // Check if offload has been disabled
439     char propValue[PROPERTY_VALUE_MAX];
440     if (property_get("audio.offload.disable", propValue, "0")) {
441         if (atoi(propValue) != 0) {
442             ALOGV("offload disabled by audio.offload.disable=%s", propValue );
443             return false;
444         }
445     }
446 
447     // Check if stream type is music, then only allow offload as of now.
448     if (offloadInfo.stream_type != AUDIO_STREAM_MUSIC)
449     {
450         ALOGV("isOffloadSupported: stream_type != MUSIC, returning false");
451         return false;
452     }
453     //check if it's multi-channel AAC (includes sub formats) and FLAC and VORBIS format
454     if ((popcount(offloadInfo.channel_mask) > 2) &&
455        (((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC) ||
456         ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_FLAC) ||
457         ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_VORBIS))) {
458            ALOGD("offload disabled for multi-channel AAC,FLAC and VORBIS format");
459            return false;
460     }
461 #ifdef AUDIO_EXTN_FORMATS_ENABLED
462         //check if it's multi-channel FLAC/ALAC/WMA format with sample rate > 48k
463     if ((popcount(offloadInfo.channel_mask) > 2) &&
464         (((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_FLAC) ||
465         (((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_ALAC) && offloadInfo.sample_rate > 48000) ||
466         (((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_WMA) && offloadInfo.sample_rate > 48000) ||
467         (((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_WMA_PRO) && offloadInfo.sample_rate > 48000))) {
468             ALOGD("offload disabled for multi-channel FLAC/ALAC/WMA clips with sample rate > 48kHz");
469         return false;
470         }
471 #endif
472     //TODO: enable audio offloading with video when ready
473     const bool allowOffloadWithVideo =
474             property_get_bool("audio.offload.video", false /* default_value */);
475     if (offloadInfo.has_video && !allowOffloadWithVideo) {
476         ALOGV("isOffloadSupported: has_video == true, returning false");
477         return false;
478     }
479 
480     //If duration is less than minimum value defined in property, return false
481     if (property_get("audio.offload.min.duration.secs", propValue, NULL)) {
482         if (offloadInfo.duration_us < (atoi(propValue) * 1000000 )) {
483             ALOGV("Offload denied by duration < audio.offload.min.duration.secs(=%s)", propValue);
484             return false;
485         }
486     } else if (offloadInfo.duration_us < OFFLOAD_DEFAULT_MIN_DURATION_SECS * 1000000) {
487         ALOGV("Offload denied by duration < default min(=%u)", OFFLOAD_DEFAULT_MIN_DURATION_SECS);
488         //duration checks only valid for MP3/AAC/VORBIS/WMA/ALAC/APE  formats,
489         //do not check duration for other audio formats, e.g. dolby AAC/AC3 and amrwb+ formats
490         if ((offloadInfo.format == AUDIO_FORMAT_MP3) ||
491             ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_AAC) ||
492             ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_VORBIS)
493 #ifdef AUDIO_EXTN_FORMATS_ENABLED
494             || ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_FLAC) ||
495             ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_WMA) ||
496             ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_WMA_PRO) ||
497             ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_ALAC) ||
498             ((offloadInfo.format & AUDIO_FORMAT_MAIN_MASK) == AUDIO_FORMAT_APE)
499 #endif
500               )
501             return false;
502 
503     }
504 
505     // Do not allow offloading if one non offloadable effect is enabled. This prevents from
506     // creating an offloaded track and tearing it down immediately after start when audioflinger
507     // detects there is an active non offloadable effect.
508     // FIXME: We should check the audio session here but we do not have it in this context.
509     // This may prevent offloading in rare situations where effects are left active by apps
510     // in the background.
511     if (mEffects.isNonOffloadableEffectEnabled()) {
512         return false;
513     }
514     // Check for soundcard status
515     String8 valueStr = mpClientInterface->getParameters((audio_io_handle_t)0,
516     String8("SND_CARD_STATUS"));
517     AudioParameter result = AudioParameter(valueStr);
518     int isonline = 0;
519     if ((result.getInt(String8("SND_CARD_STATUS"), isonline) == NO_ERROR)
520            && !isonline) {
521          ALOGD("copl: soundcard is offline rejecting offload request");
522          return false;
523     }
524     // See if there is a profile to support this.
525     // AUDIO_DEVICE_NONE
526     sp<IOProfile> profile = getProfileForDirectOutput(AUDIO_DEVICE_NONE /*ignore device */,
527                                             offloadInfo.sample_rate,
528                                             offloadInfo.format,
529                                             offloadInfo.channel_mask,
530                                             AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
531     ALOGV("isOffloadSupported() profile %sfound", profile != 0 ? "" : "NOT ");
532     return (profile != 0);
533 }
getNewOutputDevice(const sp<AudioOutputDescriptor> & outputDesc,bool fromCache)534 audio_devices_t AudioPolicyManagerCustom::getNewOutputDevice(const sp<AudioOutputDescriptor>& outputDesc,
535                                                        bool fromCache)
536 {
537     audio_devices_t device = AUDIO_DEVICE_NONE;
538 
539     ssize_t index = mAudioPatches.indexOfKey(outputDesc->mPatchHandle);
540     if (index >= 0) {
541         sp<AudioPatch> patchDesc = mAudioPatches.valueAt(index);
542         if (patchDesc->mUid != mUidCached) {
543             ALOGV("getNewOutputDevice() device %08x forced by patch %d",
544                   outputDesc->device(), outputDesc->mPatchHandle);
545             return outputDesc->device();
546         }
547     }
548 
549     // check the following by order of priority to request a routing change if necessary:
550     // 1: the strategy enforced audible is active and enforced on the output:
551     //      use device for strategy enforced audible
552     // 2: we are in call or the strategy phone is active on the output:
553     //      use device for strategy phone
554     // 3: the strategy for enforced audible is active but not enforced on the output:
555     //      use the device for strategy enforced audible
556     // 4: the strategy sonification is active on the output:
557     //      use device for strategy sonification
558     // 5: the strategy "respectful" sonification is active on the output:
559     //      use device for strategy "respectful" sonification
560     // 6: the strategy accessibility is active on the output:
561     //      use device for strategy accessibility
562     // 7: the strategy media is active on the output:
563     //      use device for strategy media
564     // 8: the strategy DTMF is active on the output:
565     //      use device for strategy DTMF
566     // 9: the strategy for beacon, a.k.a. "transmitted through speaker" is active on the output:
567     //      use device for strategy t-t-s
568     if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE) &&
569         mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_SYSTEM) == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) {
570         device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
571     } else if (isInCall() ||
572                     isStrategyActive(outputDesc, STRATEGY_PHONE)||
573                     isStrategyActive(mPrimaryOutput, STRATEGY_PHONE)) {
574         device = getDeviceForStrategy(STRATEGY_PHONE, fromCache);
575     } else if (isStrategyActive(outputDesc, STRATEGY_ENFORCED_AUDIBLE)) {
576         device = getDeviceForStrategy(STRATEGY_ENFORCED_AUDIBLE, fromCache);
577     } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION)||
578                 (isStrategyActive(mPrimaryOutput,STRATEGY_SONIFICATION)
579                 && (!isStrategyActive(mPrimaryOutput,STRATEGY_MEDIA)))) {
580         device = getDeviceForStrategy(STRATEGY_SONIFICATION, fromCache);
581     } else if (isStrategyActive(outputDesc, STRATEGY_SONIFICATION_RESPECTFUL)||
582                 (isStrategyActive(mPrimaryOutput,STRATEGY_SONIFICATION_RESPECTFUL)
583                 && (!isStrategyActive(mPrimaryOutput, STRATEGY_MEDIA)))) {
584         device = getDeviceForStrategy(STRATEGY_SONIFICATION_RESPECTFUL, fromCache);
585     } else if (isStrategyActive(outputDesc, STRATEGY_ACCESSIBILITY)) {
586         device = getDeviceForStrategy(STRATEGY_ACCESSIBILITY, fromCache);
587     } else if (isStrategyActive(outputDesc, STRATEGY_MEDIA)) {
588         device = getDeviceForStrategy(STRATEGY_MEDIA, fromCache);
589     } else if (isStrategyActive(outputDesc, STRATEGY_DTMF)) {
590         device = getDeviceForStrategy(STRATEGY_DTMF, fromCache);
591     } else if (isStrategyActive(outputDesc, STRATEGY_TRANSMITTED_THROUGH_SPEAKER)) {
592         device = getDeviceForStrategy(STRATEGY_TRANSMITTED_THROUGH_SPEAKER, fromCache);
593     } else if (isStrategyActive(outputDesc, STRATEGY_REROUTING)) {
594         device = getDeviceForStrategy(STRATEGY_REROUTING, fromCache);
595     }
596 
597     ALOGV("getNewOutputDevice() selected device %x", device);
598     return device;
599 }
setPhoneState(audio_mode_t state)600 void AudioPolicyManagerCustom::setPhoneState(audio_mode_t state)
601 {
602     ALOGV("setPhoneState() state %d", state);
603     // store previous phone state for management of sonification strategy below
604     audio_devices_t newDevice = AUDIO_DEVICE_NONE;
605     int oldState = mEngine->getPhoneState();
606 
607     if (mEngine->setPhoneState(state) != NO_ERROR) {
608         ALOGW("setPhoneState() invalid or same state %d", state);
609         return;
610     }
611     /// Opens: can these line be executed after the switch of volume curves???
612     // if leaving call state, handle special case of active streams
613     // pertaining to sonification strategy see handleIncallSonification()
614     if (isStateInCall(oldState)) {
615         ALOGV("setPhoneState() in call state management: new state is %d", state);
616         for (size_t j = 0; j < mOutputs.size(); j++) {
617             audio_io_handle_t curOutput = mOutputs.keyAt(j);
618             for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
619                 if (stream == AUDIO_STREAM_PATCH) {
620                     continue;
621                 }
622 
623             handleIncallSonification((audio_stream_type_t)stream, false, true, curOutput);
624             }
625         }
626 
627         // force reevaluating accessibility routing when call starts
628         mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
629     }
630 
631     /**
632      * Switching to or from incall state or switching between telephony and VoIP lead to force
633      * routing command.
634      */
635     bool force = ((is_state_in_call(oldState) != is_state_in_call(state))
636                   || (is_state_in_call(state) && (state != oldState)));
637 
638     // check for device and output changes triggered by new phone state
639     checkA2dpSuspend();
640     checkOutputForAllStrategies();
641     updateDevicesAndOutputs();
642 
643     sp<SwAudioOutputDescriptor> hwOutputDesc = mPrimaryOutput;
644 #ifdef VOICE_CONCURRENCY
645     int voice_call_state = 0;
646     char propValue[PROPERTY_VALUE_MAX];
647     bool prop_playback_enabled = false, prop_rec_enabled=false, prop_voip_enabled = false;
648 
649     if(property_get("voice.playback.conc.disabled", propValue, NULL)) {
650         prop_playback_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
651     }
652 
653     if(property_get("voice.record.conc.disabled", propValue, NULL)) {
654         prop_rec_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
655     }
656 
657     if(property_get("voice.voip.conc.disabled", propValue, NULL)) {
658         prop_voip_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
659     }
660 
661     bool mode_in_call = (AUDIO_MODE_IN_CALL != oldState) && (AUDIO_MODE_IN_CALL == state);
662     //query if it is a actual voice call initiated by telephony
663     if (mode_in_call) {
664         String8 valueStr = mpClientInterface->getParameters((audio_io_handle_t)0, String8("in_call"));
665         AudioParameter result = AudioParameter(valueStr);
666         if (result.getInt(String8("in_call"), voice_call_state) == NO_ERROR)
667             ALOGD("voice_conc:SetPhoneState: Voice call state = %d", voice_call_state);
668     }
669 
670     if (mode_in_call && voice_call_state && !mvoice_call_state) {
671         ALOGD("voice_conc:Entering to call mode oldState :: %d state::%d ",
672             oldState, state);
673         mvoice_call_state = voice_call_state;
674         if (prop_rec_enabled) {
675             //Close all active inputs
676             audio_io_handle_t activeInput = mInputs.getActiveInput();
677             if (activeInput != 0) {
678                sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
679                switch(activeDesc->mInputSource) {
680                    case AUDIO_SOURCE_VOICE_UPLINK:
681                    case AUDIO_SOURCE_VOICE_DOWNLINK:
682                    case AUDIO_SOURCE_VOICE_CALL:
683                        ALOGD("voice_conc:FOUND active input during call active: %d",activeDesc->mInputSource);
684                    break;
685 
686                    case  AUDIO_SOURCE_VOICE_COMMUNICATION:
687                         if(prop_voip_enabled) {
688                             ALOGD("voice_conc:CLOSING VoIP input source on call setup :%d ",activeDesc->mInputSource);
689                             stopInput(activeInput, activeDesc->mSessions.itemAt(0));
690                             releaseInput(activeInput, activeDesc->mSessions.itemAt(0));
691                         }
692                    break;
693 
694                    default:
695                        ALOGD("voice_conc:CLOSING input on call setup  for inputSource: %d",activeDesc->mInputSource);
696                        stopInput(activeInput, activeDesc->mSessions.itemAt(0));
697                        releaseInput(activeInput, activeDesc->mSessions.itemAt(0));
698                    break;
699                }
700            }
701         } else if (prop_voip_enabled) {
702             audio_io_handle_t activeInput = mInputs.getActiveInput();
703             if (activeInput != 0) {
704                 sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
705                 if (AUDIO_SOURCE_VOICE_COMMUNICATION == activeDesc->mInputSource) {
706                     ALOGD("voice_conc:CLOSING VoIP on call setup : %d",activeDesc->mInputSource);
707                     stopInput(activeInput, activeDesc->mSessions.itemAt(0));
708                     releaseInput(activeInput, activeDesc->mSessions.itemAt(0));
709                 }
710             }
711         }
712         if (prop_playback_enabled) {
713             // Move tracks associated to this strategy from previous output to new output
714             for (int i = AUDIO_STREAM_SYSTEM; i < (int)AUDIO_STREAM_CNT; i++) {
715                 ALOGV("voice_conc:Invalidate on call mode for stream :: %d ", i);
716                 if (i == AUDIO_STREAM_PATCH) {
717                     ALOGV("voice_conc:not calling invalidate for AUDIO_STREAM_PATCH");
718                     continue;
719                 }
720                 if (AUDIO_OUTPUT_FLAG_DEEP_BUFFER == mFallBackflag) {
721                     if ((AUDIO_STREAM_MUSIC == i) ||
722                         (AUDIO_STREAM_VOICE_CALL == i) ) {
723                         ALOGD("voice_conc:Invalidate stream type %d", i);
724                         mpClientInterface->invalidateStream((audio_stream_type_t)i);
725                     }
726                 } else if (AUDIO_OUTPUT_FLAG_FAST == mFallBackflag) {
727                     ALOGD("voice_conc:Invalidate stream type %d", i);
728                     mpClientInterface->invalidateStream((audio_stream_type_t)i);
729                 }
730             }
731         }
732 
733         for (size_t i = 0; i < mOutputs.size(); i++) {
734             sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
735             if ( (outputDesc == NULL) || (outputDesc->mProfile == NULL)) {
736                ALOGD("voice_conc:ouput desc / profile is NULL");
737                continue;
738             }
739 
740             if (AUDIO_OUTPUT_FLAG_FAST == mFallBackflag) {
741                 if (((!outputDesc->isDuplicated() &&outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY))
742                             && prop_playback_enabled) {
743                     ALOGD("voice_conc:calling suspendOutput on call mode for primary output");
744                     mpClientInterface->suspendOutput(mOutputs.keyAt(i));
745                 } //Close compress all sessions
746                 else if ((outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD)
747                                 &&  prop_playback_enabled) {
748                     ALOGD("voice_conc:calling closeOutput on call mode for COMPRESS output");
749                     closeOutput(mOutputs.keyAt(i));
750                 }
751                 else if ((outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_VOIP_RX)
752                                 && prop_voip_enabled) {
753                     ALOGD("voice_conc:calling closeOutput on call mode for DIRECT  output");
754                     closeOutput(mOutputs.keyAt(i));
755                 }
756             } else if (AUDIO_OUTPUT_FLAG_DEEP_BUFFER == mFallBackflag) {
757                 if ((outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)
758                                 &&  prop_playback_enabled) {
759                     ALOGD("voice_conc:calling closeOutput on call mode for COMPRESS output");
760                     closeOutput(mOutputs.keyAt(i));
761                 }
762             }
763         }
764     }
765 
766     if ((AUDIO_MODE_IN_CALL == oldState || AUDIO_MODE_IN_COMMUNICATION == oldState) &&
767        (AUDIO_MODE_NORMAL == state) && prop_playback_enabled && mvoice_call_state) {
768         ALOGD("voice_conc:EXITING from call mode oldState :: %d state::%d \n",oldState, state);
769         mvoice_call_state = 0;
770         if (AUDIO_OUTPUT_FLAG_FAST == mFallBackflag) {
771             //restore PCM (deep-buffer) output after call termination
772             for (size_t i = 0; i < mOutputs.size(); i++) {
773                 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
774                 if ( (outputDesc == NULL) || (outputDesc->mProfile == NULL)) {
775                    ALOGD("voice_conc:ouput desc / profile is NULL");
776                    continue;
777                 }
778                 if (!outputDesc->isDuplicated() && outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
779                     ALOGD("voice_conc:calling restoreOutput after call mode for primary output");
780                     mpClientInterface->restoreOutput(mOutputs.keyAt(i));
781                 }
782            }
783         }
784        //call invalidate tracks so that any open streams can fall back to deep buffer/compress path from ULL
785         for (int i = AUDIO_STREAM_SYSTEM; i < (int)AUDIO_STREAM_CNT; i++) {
786             ALOGV("voice_conc:Invalidate on call mode for stream :: %d ", i);
787             if (i == AUDIO_STREAM_PATCH) {
788                 ALOGV("voice_conc:not calling invalidate for AUDIO_STREAM_PATCH");
789                 continue;
790             }
791             if (AUDIO_OUTPUT_FLAG_DEEP_BUFFER == mFallBackflag) {
792                 if ((AUDIO_STREAM_MUSIC == i) ||
793                     (AUDIO_STREAM_VOICE_CALL == i) ) {
794                     mpClientInterface->invalidateStream((audio_stream_type_t)i);
795                 }
796             } else if (AUDIO_OUTPUT_FLAG_FAST == mFallBackflag) {
797                 mpClientInterface->invalidateStream((audio_stream_type_t)i);
798             }
799         }
800     }
801 
802 #endif
803 #ifdef RECORD_PLAY_CONCURRENCY
804     char recConcPropValue[PROPERTY_VALUE_MAX];
805     bool prop_rec_play_enabled = false;
806 
807     if (property_get("rec.playback.conc.disabled", recConcPropValue, NULL)) {
808         prop_rec_play_enabled = atoi(recConcPropValue) || !strncmp("true", recConcPropValue, 4);
809     }
810     if (prop_rec_play_enabled) {
811         if (AUDIO_MODE_IN_COMMUNICATION == mEngine->getPhoneState()) {
812             ALOGD("phone state changed to MODE_IN_COMM invlaidating music and voice streams");
813             // call invalidate for voice streams, so that it can use deepbuffer with VoIP out device from HAL
814             mpClientInterface->invalidateStream(AUDIO_STREAM_VOICE_CALL);
815             // call invalidate for music, so that compress will fallback to deep-buffer with VoIP out device
816             mpClientInterface->invalidateStream(AUDIO_STREAM_MUSIC);
817 
818             // close compress output to make sure session will be closed before timeout(60sec)
819             for (size_t i = 0; i < mOutputs.size(); i++) {
820 
821                 sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
822                 if ((outputDesc == NULL) || (outputDesc->mProfile == NULL)) {
823                    ALOGD("ouput desc / profile is NULL");
824                    continue;
825                 }
826 
827                 if (outputDesc->mProfile->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
828                     ALOGD("calling closeOutput on call mode for COMPRESS output");
829                     closeOutput(mOutputs.keyAt(i));
830                 }
831             }
832         } else if ((oldState == AUDIO_MODE_IN_COMMUNICATION) &&
833                     (mEngine->getPhoneState() == AUDIO_MODE_NORMAL)) {
834             // call invalidate for music so that music can fallback to compress
835             mpClientInterface->invalidateStream(AUDIO_STREAM_MUSIC);
836         }
837     }
838 #endif
839     mPrevPhoneState = oldState;
840     int delayMs = 0;
841     if (isStateInCall(state)) {
842         nsecs_t sysTime = systemTime();
843         for (size_t i = 0; i < mOutputs.size(); i++) {
844             sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
845             // mute media and sonification strategies and delay device switch by the largest
846             // latency of any output where either strategy is active.
847             // This avoid sending the ring tone or music tail into the earpiece or headset.
848             if ((isStrategyActive(desc, STRATEGY_MEDIA,
849                                   SONIFICATION_HEADSET_MUSIC_DELAY,
850                                   sysTime) ||
851                  isStrategyActive(desc, STRATEGY_SONIFICATION,
852                                   SONIFICATION_HEADSET_MUSIC_DELAY,
853                                   sysTime)) &&
854                     (delayMs < (int)desc->latency()*2)) {
855                 delayMs = desc->latency()*2;
856             }
857             setStrategyMute(STRATEGY_MEDIA, true, desc);
858             setStrategyMute(STRATEGY_MEDIA, false, desc, MUTE_TIME_MS,
859                 getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
860             setStrategyMute(STRATEGY_SONIFICATION, true, desc);
861             setStrategyMute(STRATEGY_SONIFICATION, false, desc, MUTE_TIME_MS,
862                 getDeviceForStrategy(STRATEGY_SONIFICATION, true /*fromCache*/));
863         }
864         ALOGV("Setting the delay from %dms to %dms", delayMs,
865                 MIN(delayMs, MAX_VOICE_CALL_START_DELAY_MS));
866          delayMs = MIN(delayMs, MAX_VOICE_CALL_START_DELAY_MS);
867     }
868 
869     if (hasPrimaryOutput()) {
870         // Note that despite the fact that getNewOutputDevice() is called on the primary output,
871         // the device returned is not necessarily reachable via this output
872         audio_devices_t rxDevice = getNewOutputDevice(mPrimaryOutput, false /*fromCache*/);
873         // force routing command to audio hardware when ending call
874         // even if no device change is needed
875         if (isStateInCall(oldState) && rxDevice == AUDIO_DEVICE_NONE) {
876             rxDevice = mPrimaryOutput->device();
877         }
878 
879         if (state == AUDIO_MODE_IN_CALL) {
880             updateCallRouting(rxDevice, delayMs);
881         } else if (oldState == AUDIO_MODE_IN_CALL) {
882             if (mCallRxPatch != 0) {
883                 mpClientInterface->releaseAudioPatch(mCallRxPatch->mAfPatchHandle, 0);
884                 mCallRxPatch.clear();
885             }
886             if (mCallTxPatch != 0) {
887                 mpClientInterface->releaseAudioPatch(mCallTxPatch->mAfPatchHandle, 0);
888                 mCallTxPatch.clear();
889             }
890             setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
891         } else {
892             setOutputDevice(mPrimaryOutput, rxDevice, force, 0);
893         }
894     }
895     //update device for all non-primary outputs
896     for (size_t i = 0; i < mOutputs.size(); i++) {
897         audio_io_handle_t output = mOutputs.keyAt(i);
898         if (output != mPrimaryOutput->mIoHandle) {
899             newDevice = getNewOutputDevice(mOutputs.valueFor(output), false /*fromCache*/);
900             setOutputDevice(mOutputs.valueFor(output), newDevice, (newDevice != AUDIO_DEVICE_NONE));
901         }
902     }
903     // if entering in call state, handle special case of active streams
904     // pertaining to sonification strategy see handleIncallSonification()
905     if (isStateInCall(state)) {
906         ALOGV("setPhoneState() in call state management: new state is %d", state);
907         for (size_t j = 0; j < mOutputs.size(); j++) {
908             audio_io_handle_t curOutput = mOutputs.keyAt(j);
909             for (int stream = 0; stream < AUDIO_STREAM_CNT; stream++) {
910                if (stream == AUDIO_STREAM_PATCH) {
911                     continue;
912                 }
913             handleIncallSonification((audio_stream_type_t)stream, true, true, curOutput);
914            }
915         }
916     }
917 
918     // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
919     if (state == AUDIO_MODE_RINGTONE &&
920         isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
921         mLimitRingtoneVolume = true;
922     } else {
923         mLimitRingtoneVolume = false;
924     }
925 }
926 
setForceUse(audio_policy_force_use_t usage,audio_policy_forced_cfg_t config)927 void AudioPolicyManagerCustom::setForceUse(audio_policy_force_use_t usage,
928                                          audio_policy_forced_cfg_t config)
929 {
930     ALOGV("setForceUse() usage %d, config %d, mPhoneState %d", usage, config, mEngine->getPhoneState());
931 
932     if (mEngine->setForceUse(usage, config) != NO_ERROR) {
933         ALOGW("setForceUse() could not set force cfg %d for usage %d", config, usage);
934         return;
935     }
936     bool forceVolumeReeval = (usage == AUDIO_POLICY_FORCE_FOR_COMMUNICATION) ||
937             (usage == AUDIO_POLICY_FORCE_FOR_DOCK) ||
938             (usage == AUDIO_POLICY_FORCE_FOR_SYSTEM);
939 
940     // check for device and output changes triggered by new force usage
941     checkA2dpSuspend();
942     checkOutputForAllStrategies();
943     updateDevicesAndOutputs();
944     if (mEngine->getPhoneState() == AUDIO_MODE_IN_CALL && hasPrimaryOutput()) {
945         audio_devices_t newDevice = getNewOutputDevice(mPrimaryOutput, true /*fromCache*/);
946         updateCallRouting(newDevice);
947     }
948     // Use reverse loop to make sure any low latency usecases (generally tones)
949     // are not routed before non LL usecases (generally music).
950     // We can safely assume that LL output would always have lower index,
951     // and use this work-around to avoid routing of output with music stream
952     // from the context of short lived LL output.
953     // Note: in case output's share backend(HAL sharing is implicit) all outputs
954     //       gets routing update while processing first output itself.
955     for (size_t i = mOutputs.size(); i > 0; i--) {
956         sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i-1);
957         audio_devices_t newDevice = getNewOutputDevice(outputDesc, true /*fromCache*/);
958         if ((mEngine->getPhoneState() != AUDIO_MODE_IN_CALL) || outputDesc != mPrimaryOutput) {
959             setOutputDevice(outputDesc, newDevice, (newDevice != AUDIO_DEVICE_NONE));
960         }
961         if (forceVolumeReeval && (newDevice != AUDIO_DEVICE_NONE)) {
962             applyStreamVolumes(outputDesc, newDevice, 0, true);
963         }
964     }
965 
966     audio_io_handle_t activeInput = mInputs.getActiveInput();
967     if (activeInput != 0) {
968         setInputDevice(activeInput, getNewInputDevice(activeInput));
969     }
970 
971 }
972 
stopSource(sp<AudioOutputDescriptor> outputDesc1,audio_stream_type_t stream,bool forceDeviceUpdate)973 status_t AudioPolicyManagerCustom::stopSource(sp<AudioOutputDescriptor> outputDesc1,
974                                             audio_stream_type_t stream,
975                                             bool forceDeviceUpdate)
976 {
977     if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
978         ALOGW("stopSource() invalid stream %d", stream);
979         return INVALID_OPERATION;
980     }
981 
982     // always handle stream stop, check which stream type is stopping
983 #ifdef NON_WEARABLE_TARGET
984     sp<AudioOutputDescriptor> outputDesc = outputDesc1;
985 #else
986     sp<SwAudioOutputDescriptor> outputDesc = (sp<SwAudioOutputDescriptor>) outputDesc1;
987 #endif
988     handleEventForBeacon(stream == AUDIO_STREAM_TTS ? STOPPING_BEACON : STOPPING_OUTPUT);
989 
990     // handle special case for sonification while in call
991     if (isInCall() && (outputDesc->mRefCount[stream] == 1)) {
992         if (outputDesc->isDuplicated()) {
993 #ifdef NON_WEARABLE_TARGET
994             handleIncallSonification(stream, false, false, outputDesc->subOutput1()->mIoHandle);
995             handleIncallSonification(stream, false, false, outputDesc->subOutput2()->mIoHandle);
996 #else
997             handleIncallSonification(stream, false, false, outputDesc->mOutput1->mIoHandle);
998             handleIncallSonification(stream, false, false, outputDesc->mOutput2->mIoHandle);
999 #endif
1000         }
1001         handleIncallSonification(stream, false, false, outputDesc->mIoHandle);
1002     }
1003 
1004     if (outputDesc->mRefCount[stream] > 0) {
1005         // decrement usage count of this stream on the output
1006         outputDesc->changeRefCount(stream, -1);
1007 
1008         // store time at which the stream was stopped - see isStreamActive()
1009         if (outputDesc->mRefCount[stream] == 0 || forceDeviceUpdate) {
1010             outputDesc->mStopTime[stream] = systemTime();
1011             audio_devices_t newDevice = getNewOutputDevice(outputDesc, false /*fromCache*/);
1012             // delay the device switch by twice the latency because stopOutput() is executed when
1013             // the track stop() command is received and at that time the audio track buffer can
1014             // still contain data that needs to be drained. The latency only covers the audio HAL
1015             // and kernel buffers. Also the latency does not always include additional delay in the
1016             // audio path (audio DSP, CODEC ...)
1017             setOutputDevice(outputDesc, newDevice, false, outputDesc->latency()*2);
1018 
1019             // force restoring the device selection on other active outputs if it differs from the
1020             // one being selected for this output
1021             for (size_t i = 0; i < mOutputs.size(); i++) {
1022                 audio_io_handle_t curOutput = mOutputs.keyAt(i);
1023                 sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
1024                 if (desc != outputDesc &&
1025                         desc->isActive() &&
1026                         outputDesc->sharesHwModuleWith(desc) &&
1027                         (newDevice != desc->device())) {
1028                     audio_devices_t dev = getNewOutputDevice(mOutputs.valueFor(curOutput), false /*fromCache*/);
1029                     setOutputDevice(desc,
1030                                     dev,
1031                                     true,
1032                                     outputDesc->latency()*2);
1033                 }
1034             }
1035             // update the outputs if stopping one with a stream that can affect notification routing
1036             handleNotificationRoutingForStream(stream);
1037         }
1038         return NO_ERROR;
1039     } else {
1040         ALOGW("stopOutput() refcount is already 0");
1041         return INVALID_OPERATION;
1042     }
1043 }
startSource(sp<AudioOutputDescriptor> outputDesc1,audio_stream_type_t stream,audio_devices_t device,uint32_t * delayMs)1044 status_t AudioPolicyManagerCustom::startSource(sp<AudioOutputDescriptor> outputDesc1,
1045                                              audio_stream_type_t stream,
1046                                              audio_devices_t device,
1047                                              uint32_t *delayMs)
1048 {
1049     // cannot start playback of STREAM_TTS if any other output is being used
1050     uint32_t beaconMuteLatency = 0;
1051     if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
1052         ALOGW("startSource() invalid stream %d", stream);
1053         return INVALID_OPERATION;
1054     }
1055 
1056 #ifdef NON_WEARABLE_TARGET
1057     sp<AudioOutputDescriptor> outputDesc = outputDesc1;
1058 #else
1059     sp<SwAudioOutputDescriptor> outputDesc = (sp<SwAudioOutputDescriptor>) outputDesc1;
1060 #endif
1061 
1062     *delayMs = 0;
1063     if (stream == AUDIO_STREAM_TTS) {
1064         ALOGV("\t found BEACON stream");
1065         if (mOutputs.isAnyOutputActive(AUDIO_STREAM_TTS /*streamToIgnore*/)) {
1066             return INVALID_OPERATION;
1067         } else {
1068             beaconMuteLatency = handleEventForBeacon(STARTING_BEACON);
1069         }
1070     } else {
1071         // some playback other than beacon starts
1072         beaconMuteLatency = handleEventForBeacon(STARTING_OUTPUT);
1073     }
1074 
1075     // increment usage count for this stream on the requested output:
1076     // NOTE that the usage count is the same for duplicated output and hardware output which is
1077     // necessary for a correct control of hardware output routing by startOutput() and stopOutput()
1078     outputDesc->changeRefCount(stream, 1);
1079 
1080     if (outputDesc->mRefCount[stream] == 1 || device != AUDIO_DEVICE_NONE) {
1081         // starting an output being rerouted?
1082         if (device == AUDIO_DEVICE_NONE) {
1083             device = getNewOutputDevice(outputDesc, false /*fromCache*/);
1084         }
1085         routing_strategy strategy = getStrategy(stream);
1086         bool shouldWait = (strategy == STRATEGY_SONIFICATION) ||
1087                             (strategy == STRATEGY_SONIFICATION_RESPECTFUL) ||
1088                             (beaconMuteLatency > 0);
1089         uint32_t waitMs = beaconMuteLatency;
1090         bool force = false;
1091         for (size_t i = 0; i < mOutputs.size(); i++) {
1092             sp<AudioOutputDescriptor> desc = mOutputs.valueAt(i);
1093             if (desc != outputDesc) {
1094                 // force a device change if any other output is managed by the same hw
1095                 // module and has a current device selection that differs from selected device.
1096                 // In this case, the audio HAL must receive the new device selection so that it can
1097                 // change the device currently selected by the other active output.
1098                 if (outputDesc->sharesHwModuleWith(desc) &&
1099                     desc->device() != device) {
1100                     force = true;
1101                 }
1102                 // wait for audio on other active outputs to be presented when starting
1103                 // a notification so that audio focus effect can propagate, or that a mute/unmute
1104                 // event occurred for beacon
1105                 uint32_t latency = desc->latency();
1106                 if (shouldWait && desc->isActive(latency * 2) && (waitMs < latency)) {
1107                     waitMs = latency;
1108                 }
1109             }
1110         }
1111         uint32_t muteWaitMs = setOutputDevice(outputDesc, device, force);
1112 
1113         // handle special case for sonification while in call
1114         if (isInCall()) {
1115             handleIncallSonification(stream, true, false, outputDesc->mIoHandle);
1116         }
1117 
1118         // apply volume rules for current stream and device if necessary
1119         checkAndSetVolume(stream,
1120                           mStreams.valueFor(stream).getVolumeIndex(device),
1121                           outputDesc,
1122                           device);
1123 
1124         // update the outputs if starting an output with a stream that can affect notification
1125         // routing
1126         handleNotificationRoutingForStream(stream);
1127 
1128         // force reevaluating accessibility routing when ringtone or alarm starts
1129         if (strategy == STRATEGY_SONIFICATION) {
1130             mpClientInterface->invalidateStream(AUDIO_STREAM_ACCESSIBILITY);
1131         }
1132     }
1133     else {
1134             // handle special case for sonification while in call
1135             if (isInCall()) {
1136                 handleIncallSonification(stream, true, false, outputDesc->mIoHandle);
1137               }
1138         }
1139     return NO_ERROR;
1140 }
handleIncallSonification(audio_stream_type_t stream,bool starting,bool stateChange,audio_io_handle_t output)1141 void AudioPolicyManagerCustom::handleIncallSonification(audio_stream_type_t stream,
1142                                                       bool starting, bool stateChange,
1143                                                       audio_io_handle_t output)
1144 {
1145     if(!hasPrimaryOutput()) {
1146         return;
1147     }
1148     // no action needed for AUDIO_STREAM_PATCH stream type, it's for internal flinger tracks
1149     if (stream == AUDIO_STREAM_PATCH) {
1150         return;
1151     }
1152     // if the stream pertains to sonification strategy and we are in call we must
1153     // mute the stream if it is low visibility. If it is high visibility, we must play a tone
1154     // in the device used for phone strategy and play the tone if the selected device does not
1155     // interfere with the device used for phone strategy
1156     // if stateChange is true, we are called from setPhoneState() and we must mute or unmute as
1157     // many times as there are active tracks on the output
1158     const routing_strategy stream_strategy = getStrategy(stream);
1159     if ((stream_strategy == STRATEGY_SONIFICATION) ||
1160             ((stream_strategy == STRATEGY_SONIFICATION_RESPECTFUL))) {
1161         sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueFor(output);
1162         ALOGV("handleIncallSonification() stream %d starting %d device %x stateChange %d",
1163                 stream, starting, outputDesc->mDevice, stateChange);
1164         if (outputDesc->mRefCount[stream]) {
1165             int muteCount = 1;
1166             if (stateChange) {
1167                 muteCount = outputDesc->mRefCount[stream];
1168             }
1169             if (audio_is_low_visibility(stream)) {
1170                 ALOGV("handleIncallSonification() low visibility, muteCount %d", muteCount);
1171                 for (int i = 0; i < muteCount; i++) {
1172                     setStreamMute(stream, starting, outputDesc);
1173                 }
1174             } else {
1175                 ALOGV("handleIncallSonification() high visibility");
1176                 if (outputDesc->device() &
1177                         getDeviceForStrategy(STRATEGY_PHONE, true /*fromCache*/)) {
1178                     ALOGV("handleIncallSonification() high visibility muted, muteCount %d", muteCount);
1179                     for (int i = 0; i < muteCount; i++) {
1180                         setStreamMute(stream, starting, outputDesc);
1181                     }
1182                 }
1183                 if (starting) {
1184                     mpClientInterface->startTone(AUDIO_POLICY_TONE_IN_CALL_NOTIFICATION,
1185                                                  AUDIO_STREAM_VOICE_CALL);
1186                 } else {
1187                     mpClientInterface->stopTone();
1188                 }
1189             }
1190         }
1191     }
1192 }
handleNotificationRoutingForStream(audio_stream_type_t stream)1193 void AudioPolicyManagerCustom::handleNotificationRoutingForStream(audio_stream_type_t stream) {
1194     switch(stream) {
1195     case AUDIO_STREAM_MUSIC:
1196         checkOutputForStrategy(STRATEGY_SONIFICATION_RESPECTFUL);
1197         updateDevicesAndOutputs();
1198         break;
1199     default:
1200         break;
1201     }
1202 }
1203 #ifdef NON_WEARABLE_TARGET
checkAndSetVolume(audio_stream_type_t stream,int index,const sp<AudioOutputDescriptor> & outputDesc,audio_devices_t device,int delayMs,bool force)1204 status_t AudioPolicyManagerCustom::checkAndSetVolume(audio_stream_type_t stream,
1205                                                    int index,
1206                                                    const sp<AudioOutputDescriptor>& outputDesc,
1207                                                    audio_devices_t device,
1208                                                    int delayMs, bool force)
1209 #else
1210 status_t AudioPolicyManagerCustom::checkAndSetVolume(audio_stream_type_t stream,
1211                                                     int index,
1212                                                     const sp<SwAudioOutputDescriptor>& outputDesc,
1213                                                     audio_devices_t device,
1214                                                     int delayMs, bool force)
1215 
1216 #endif
1217 {
1218     if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
1219         ALOGW("checkAndSetVolume() invalid stream %d", stream);
1220         return INVALID_OPERATION;
1221     }
1222 
1223     // do not change actual stream volume if the stream is muted
1224     if (outputDesc->mMuteCount[stream] != 0) {
1225         ALOGVV("checkAndSetVolume() stream %d muted count %d",
1226               stream, outputDesc->mMuteCount[stream]);
1227         return NO_ERROR;
1228     }
1229     audio_policy_forced_cfg_t forceUseForComm =
1230             mEngine->getForceUse(AUDIO_POLICY_FORCE_FOR_COMMUNICATION);
1231     // do not change in call volume if bluetooth is connected and vice versa
1232     if ((stream == AUDIO_STREAM_VOICE_CALL && forceUseForComm == AUDIO_POLICY_FORCE_BT_SCO) ||
1233         (stream == AUDIO_STREAM_BLUETOOTH_SCO && forceUseForComm != AUDIO_POLICY_FORCE_BT_SCO)) {
1234         ALOGV("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",
1235              stream, forceUseForComm);
1236         return INVALID_OPERATION;
1237     }
1238 
1239     if (device == AUDIO_DEVICE_NONE) {
1240         device = outputDesc->device();
1241     }
1242 
1243     float volumeDb = computeVolume(stream, index, device);
1244     if (outputDesc->isFixedVolume(device)) {
1245         volumeDb = 0.0f;
1246     }
1247 
1248     outputDesc->setVolume(volumeDb, stream, device, delayMs, force);
1249 
1250     if (stream == AUDIO_STREAM_VOICE_CALL ||
1251         stream == AUDIO_STREAM_BLUETOOTH_SCO) {
1252         float voiceVolume;
1253         // Force voice volume to max for bluetooth SCO as volume is managed by the headset
1254         if (stream == AUDIO_STREAM_VOICE_CALL) {
1255             voiceVolume = (float)index/(float)mStreams.valueFor(stream).getVolumeIndexMax();
1256         } else {
1257             voiceVolume = 1.0;
1258         }
1259 
1260         if (voiceVolume != mLastVoiceVolume && ((outputDesc == mPrimaryOutput) ||
1261             isDirectOutput(outputDesc->mIoHandle) || device & AUDIO_DEVICE_OUT_ALL_USB)) {
1262             mpClientInterface->setVoiceVolume(voiceVolume, delayMs);
1263             mLastVoiceVolume = voiceVolume;
1264         }
1265 #ifdef FM_POWER_OPT
1266     } else if (stream == AUDIO_STREAM_MUSIC && hasPrimaryOutput() &&
1267                outputDesc == mPrimaryOutput) {
1268         AudioParameter param = AudioParameter();
1269         param.addFloat(String8("fm_volume"), Volume::DbToAmpl(volumeDb));
1270         mpClientInterface->setParameters(mPrimaryOutput->mIoHandle, param.toString(), delayMs);
1271 #endif /* FM_POWER_OPT end */
1272     }
1273 
1274     return NO_ERROR;
1275 }
isDirectOutput(audio_io_handle_t output)1276 bool AudioPolicyManagerCustom::isDirectOutput(audio_io_handle_t output) {
1277     for (size_t i = 0; i < mOutputs.size(); i++) {
1278         audio_io_handle_t curOutput = mOutputs.keyAt(i);
1279         sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
1280         if ((curOutput == output) && (desc->mFlags & AUDIO_OUTPUT_FLAG_DIRECT)) {
1281             return true;
1282         }
1283     }
1284     return false;
1285 }
getOutputForDevice(audio_devices_t device,audio_session_t session __unused,audio_stream_type_t stream,uint32_t samplingRate,audio_format_t format,audio_channel_mask_t channelMask,audio_output_flags_t flags,const audio_offload_info_t * offloadInfo)1286 audio_io_handle_t AudioPolicyManagerCustom::getOutputForDevice(
1287         audio_devices_t device,
1288         audio_session_t session __unused,
1289         audio_stream_type_t stream,
1290         uint32_t samplingRate,
1291         audio_format_t format,
1292         audio_channel_mask_t channelMask,
1293         audio_output_flags_t flags,
1294         const audio_offload_info_t *offloadInfo)
1295 {
1296     audio_io_handle_t output = AUDIO_IO_HANDLE_NONE;
1297     uint32_t latency = 0;
1298     status_t status;
1299 
1300 #ifdef AUDIO_POLICY_TEST
1301     if (mCurOutput != 0) {
1302         ALOGV("getOutput() test output mCurOutput %d, samplingRate %d, format %d, channelMask %x, mDirectOutput %d",
1303                 mCurOutput, mTestSamplingRate, mTestFormat, mTestChannels, mDirectOutput);
1304 
1305         if (mTestOutputs[mCurOutput] == 0) {
1306             ALOGV("getOutput() opening test output");
1307             sp<AudioOutputDescriptor> outputDesc = new SwAudioOutputDescriptor(NULL,
1308                                                                                mpClientInterface);
1309             outputDesc->mDevice = mTestDevice;
1310             outputDesc->mLatency = mTestLatencyMs;
1311             outputDesc->mFlags =
1312                     (audio_output_flags_t)(mDirectOutput ? AUDIO_OUTPUT_FLAG_DIRECT : 0);
1313             outputDesc->mRefCount[stream] = 0;
1314             audio_config_t config = AUDIO_CONFIG_INITIALIZER;
1315             config.sample_rate = mTestSamplingRate;
1316             config.channel_mask = mTestChannels;
1317             config.format = mTestFormat;
1318             if (offloadInfo != NULL) {
1319                 config.offload_info = *offloadInfo;
1320             }
1321             status = mpClientInterface->openOutput(0,
1322                                                   &mTestOutputs[mCurOutput],
1323                                                   &config,
1324                                                   &outputDesc->mDevice,
1325                                                   String8(""),
1326                                                   &outputDesc->mLatency,
1327                                                   outputDesc->mFlags);
1328             if (status == NO_ERROR) {
1329                 outputDesc->mSamplingRate = config.sample_rate;
1330                 outputDesc->mFormat = config.format;
1331                 outputDesc->mChannelMask = config.channel_mask;
1332                 AudioParameter outputCmd = AudioParameter();
1333                 outputCmd.addInt(String8("set_id"),mCurOutput);
1334                 mpClientInterface->setParameters(mTestOutputs[mCurOutput],outputCmd.toString());
1335                 addOutput(mTestOutputs[mCurOutput], outputDesc);
1336             }
1337         }
1338         return mTestOutputs[mCurOutput];
1339     }
1340 #endif //AUDIO_POLICY_TEST
1341     if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) &&
1342             (stream != AUDIO_STREAM_MUSIC)) {
1343         // compress should not be used for non-music streams
1344         ALOGE("Offloading only allowed with music stream");
1345         return 0;
1346        }
1347 
1348 #ifdef COMPRESS_VOIP_ENABLED
1349     if ((stream == AUDIO_STREAM_VOICE_CALL) &&
1350         (channelMask == 1) &&
1351         (samplingRate == 8000 || samplingRate == 16000)) {
1352         // Allow Voip direct output only if:
1353         // audio mode is MODE_IN_COMMUNCATION; AND
1354         // voip output is not opened already; AND
1355         // requested sample rate matches with that of voip input stream (if opened already)
1356         int value = 0;
1357         uint32_t mode = 0, voipOutCount = 1, voipSampleRate = 1;
1358         String8 valueStr = mpClientInterface->getParameters((audio_io_handle_t)0,
1359                                                            String8("audio_mode"));
1360         AudioParameter result = AudioParameter(valueStr);
1361         if (result.getInt(String8("audio_mode"), value) == NO_ERROR) {
1362             mode = value;
1363         }
1364 
1365         valueStr =  mpClientInterface->getParameters((audio_io_handle_t)0,
1366                                               String8("voip_out_stream_count"));
1367         result = AudioParameter(valueStr);
1368         if (result.getInt(String8("voip_out_stream_count"), value) == NO_ERROR) {
1369             voipOutCount = value;
1370         }
1371 
1372         valueStr = mpClientInterface->getParameters((audio_io_handle_t)0,
1373                                               String8("voip_sample_rate"));
1374         result = AudioParameter(valueStr);
1375         if (result.getInt(String8("voip_sample_rate"), value) == NO_ERROR) {
1376             voipSampleRate = value;
1377         }
1378 
1379         if ((mode == AUDIO_MODE_IN_COMMUNICATION) && (voipOutCount == 0) &&
1380             ((voipSampleRate == 0) || (voipSampleRate == samplingRate))) {
1381             if (audio_is_linear_pcm(format)) {
1382                 char propValue[PROPERTY_VALUE_MAX] = {0};
1383                 property_get("use.voice.path.for.pcm.voip", propValue, "0");
1384                 bool voipPcmSysPropEnabled = !strncmp("true", propValue, sizeof("true"));
1385                 if (voipPcmSysPropEnabled && (format == AUDIO_FORMAT_PCM_16_BIT)) {
1386                     flags = (audio_output_flags_t)((flags &~AUDIO_OUTPUT_FLAG_FAST) |
1387                                 AUDIO_OUTPUT_FLAG_VOIP_RX | AUDIO_OUTPUT_FLAG_DIRECT);
1388                     ALOGD("Set VoIP and Direct output flags for PCM format");
1389                 }
1390             }
1391         }
1392     }
1393 #endif
1394 
1395 #ifdef VOICE_CONCURRENCY
1396     char propValue[PROPERTY_VALUE_MAX];
1397     bool prop_play_enabled=false, prop_voip_enabled = false;
1398 
1399     if(property_get("voice.playback.conc.disabled", propValue, NULL)) {
1400        prop_play_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
1401     }
1402 
1403     if(property_get("voice.voip.conc.disabled", propValue, NULL)) {
1404        prop_voip_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
1405     }
1406 
1407     if (prop_play_enabled && mvoice_call_state) {
1408         //check if voice call is active  / running in background
1409         if((AUDIO_MODE_IN_CALL == mEngine->getPhoneState()) ||
1410              ((AUDIO_MODE_IN_CALL == mPrevPhoneState)
1411                 && (AUDIO_MODE_IN_COMMUNICATION == mEngine->getPhoneState())))
1412         {
1413             if(AUDIO_OUTPUT_FLAG_VOIP_RX  & flags) {
1414                 if(prop_voip_enabled) {
1415                    ALOGD("voice_conc:getoutput:IN call mode return no o/p for VoIP %x",
1416                         flags );
1417                    return 0;
1418                 }
1419             }
1420             else {
1421                 if (AUDIO_OUTPUT_FLAG_FAST == mFallBackflag) {
1422                     ALOGD("voice_conc:IN call mode adding ULL flags .. flags: %x ", flags );
1423                     flags = AUDIO_OUTPUT_FLAG_FAST;
1424                 } else if (AUDIO_OUTPUT_FLAG_DEEP_BUFFER == mFallBackflag) {
1425                     if (AUDIO_STREAM_MUSIC == stream) {
1426                         flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
1427                         ALOGD("voice_conc:IN call mode adding deep-buffer flags %x ", flags );
1428                     }
1429                     else {
1430                         flags = AUDIO_OUTPUT_FLAG_FAST;
1431                         ALOGD("voice_conc:IN call mode adding fast flags %x ", flags );
1432                     }
1433                 }
1434             }
1435         }
1436     } else if (prop_voip_enabled && mvoice_call_state) {
1437         //check if voice call is active  / running in background
1438         //some of VoIP apps(like SIP2SIP call) supports resume of VoIP call when call in progress
1439         //return only ULL ouput
1440         if((AUDIO_MODE_IN_CALL == mEngine->getPhoneState()) ||
1441              ((AUDIO_MODE_IN_CALL == mPrevPhoneState)
1442                 && (AUDIO_MODE_IN_COMMUNICATION == mEngine->getPhoneState())))
1443         {
1444             if(AUDIO_OUTPUT_FLAG_VOIP_RX  & flags) {
1445                     ALOGD("voice_conc:getoutput:IN call mode return no o/p for VoIP %x",
1446                         flags );
1447                return 0;
1448             }
1449         }
1450      }
1451 #endif
1452 #ifdef RECORD_PLAY_CONCURRENCY
1453     char recConcPropValue[PROPERTY_VALUE_MAX];
1454     bool prop_rec_play_enabled = false;
1455 
1456     if (property_get("rec.playback.conc.disabled", recConcPropValue, NULL)) {
1457         prop_rec_play_enabled = atoi(recConcPropValue) || !strncmp("true", recConcPropValue, 4);
1458     }
1459     if ((prop_rec_play_enabled) &&
1460             ((true == mIsInputRequestOnProgress) || (mInputs.activeInputsCount() > 0))) {
1461         if (AUDIO_MODE_IN_COMMUNICATION == mEngine->getPhoneState()) {
1462             if (AUDIO_OUTPUT_FLAG_VOIP_RX & flags) {
1463                 // allow VoIP using voice path
1464                 // Do nothing
1465             } else if((flags & AUDIO_OUTPUT_FLAG_FAST) == 0) {
1466                 ALOGD("voice_conc:MODE_IN_COMM is setforcing deep buffer output for non ULL... flags: %x", flags);
1467                 // use deep buffer path for all non ULL outputs
1468                 flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
1469             }
1470         } else if ((flags & AUDIO_OUTPUT_FLAG_FAST) == 0) {
1471             ALOGD("voice_conc:Record mode is on forcing deep buffer output for non ULL... flags: %x ", flags);
1472             // use deep buffer path for all non ULL outputs
1473             flags = AUDIO_OUTPUT_FLAG_DEEP_BUFFER;
1474         }
1475     }
1476     if (prop_rec_play_enabled &&
1477             (stream == AUDIO_STREAM_ENFORCED_AUDIBLE)) {
1478            ALOGD("Record conc is on forcing ULL output for ENFORCED_AUDIBLE");
1479            flags = AUDIO_OUTPUT_FLAG_FAST;
1480     }
1481 #endif
1482 #ifdef AUDIO_EXTN_AFE_PROXY_ENABLED
1483     /*
1484     * WFD audio routes back to target speaker when starting a ringtone playback.
1485     * This is because primary output is reused for ringtone, so output device is
1486     * updated based on SONIFICATION strategy for both ringtone and music playback.
1487     * The same issue is not seen on remoted_submix HAL based WFD audio because
1488     * primary output is not reused and a new output is created for ringtone playback.
1489     * Issue is fixed by updating output flag to AUDIO_OUTPUT_FLAG_FAST when there is
1490     * a non-music stream playback on WFD, so primary output is not reused for ringtone.
1491     */
1492     audio_devices_t availableOutputDeviceTypes = mAvailableOutputDevices.types();
1493     if ((availableOutputDeviceTypes & AUDIO_DEVICE_OUT_PROXY)
1494           && (stream != AUDIO_STREAM_MUSIC)) {
1495         ALOGD("WFD audio: use OUTPUT_FLAG_FAST for non music stream. flags:%x", flags );
1496         //For voip paths
1497         if(flags & AUDIO_OUTPUT_FLAG_DIRECT)
1498             flags = AUDIO_OUTPUT_FLAG_DIRECT;
1499         else //route every thing else to ULL path
1500             flags = AUDIO_OUTPUT_FLAG_FAST;
1501     }
1502 #endif
1503     // open a direct output if required by specified parameters
1504     //force direct flag if offload flag is set: offloading implies a direct output stream
1505     // and all common behaviors are driven by checking only the direct flag
1506     // this should normally be set appropriately in the policy configuration file
1507     if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
1508         flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
1509     }
1510     if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
1511         flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
1512     }
1513     // only allow deep buffering for music stream type
1514     if (stream != AUDIO_STREAM_MUSIC) {
1515         flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
1516     }
1517     if (stream == AUDIO_STREAM_TTS) {
1518         flags = AUDIO_OUTPUT_FLAG_TTS;
1519     }
1520 
1521     // open a direct output if required by specified parameters
1522     //force direct flag if offload flag is set: offloading implies a direct output stream
1523     // and all common behaviors are driven by checking only the direct flag
1524     // this should normally be set appropriately in the policy configuration file
1525     if ((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) != 0) {
1526         flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
1527     }
1528     if ((flags & AUDIO_OUTPUT_FLAG_HW_AV_SYNC) != 0) {
1529         flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_DIRECT);
1530     }
1531     // only allow deep buffering for music stream type
1532     if (stream != AUDIO_STREAM_MUSIC) {
1533         flags = (audio_output_flags_t)(flags &~AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
1534     }
1535     if (stream == AUDIO_STREAM_TTS) {
1536         flags = AUDIO_OUTPUT_FLAG_TTS;
1537     }
1538 
1539     sp<IOProfile> profile;
1540 
1541     // skip direct output selection if the request can obviously be attached to a mixed output
1542     // and not explicitly requested
1543     if (((flags & AUDIO_OUTPUT_FLAG_DIRECT) == 0) &&
1544             audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE &&
1545             audio_channel_count_from_out_mask(channelMask) <= 2) {
1546         goto non_direct_output;
1547     }
1548 
1549     // Do not allow offloading if one non offloadable effect is enabled. This prevents from
1550     // creating an offloaded track and tearing it down immediately after start when audioflinger
1551     // detects there is an active non offloadable effect.
1552     // FIXME: We should check the audio session here but we do not have it in this context.
1553     // This may prevent offloading in rare situations where effects are left active by apps
1554     // in the background.
1555 
1556     if (((flags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) == 0) ||
1557             !mEffects.isNonOffloadableEffectEnabled()) {
1558         profile = getProfileForDirectOutput(device,
1559                                            samplingRate,
1560                                            format,
1561                                            channelMask,
1562                                            (audio_output_flags_t)flags);
1563     }
1564 
1565     if (profile != 0) {
1566         sp<SwAudioOutputDescriptor> outputDesc = NULL;
1567 
1568         for (size_t i = 0; i < mOutputs.size(); i++) {
1569             sp<SwAudioOutputDescriptor> desc = mOutputs.valueAt(i);
1570             if (!desc->isDuplicated() && (profile == desc->mProfile)) {
1571                 outputDesc = desc;
1572                 // reuse direct output if currently open and configured with same parameters
1573                 if ((samplingRate == outputDesc->mSamplingRate) &&
1574                         (format == outputDesc->mFormat) &&
1575                         (channelMask == outputDesc->mChannelMask)) {
1576                     outputDesc->mDirectOpenCount++;
1577                     ALOGV("getOutput() reusing direct output %d", mOutputs.keyAt(i));
1578                     return mOutputs.keyAt(i);
1579                 }
1580             }
1581         }
1582         // close direct output if currently open and configured with different parameters
1583         if (outputDesc != NULL) {
1584             closeOutput(outputDesc->mIoHandle);
1585         }
1586 
1587         // if the selected profile is offloaded and no offload info was specified,
1588         // create a default one
1589         audio_offload_info_t defaultOffloadInfo = AUDIO_INFO_INITIALIZER;
1590         if ((profile->mFlags & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) && !offloadInfo) {
1591             flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
1592             defaultOffloadInfo.sample_rate = samplingRate;
1593             defaultOffloadInfo.channel_mask = channelMask;
1594             defaultOffloadInfo.format = format;
1595             defaultOffloadInfo.stream_type = stream;
1596             defaultOffloadInfo.bit_rate = 0;
1597             defaultOffloadInfo.duration_us = -1;
1598             defaultOffloadInfo.has_video = true; // conservative
1599             defaultOffloadInfo.is_streaming = true; // likely
1600             offloadInfo = &defaultOffloadInfo;
1601         }
1602 
1603         outputDesc = new SwAudioOutputDescriptor(profile, mpClientInterface);
1604         outputDesc->mDevice = device;
1605         outputDesc->mLatency = 0;
1606         outputDesc->mFlags = (audio_output_flags_t)(outputDesc->mFlags | flags);
1607         audio_config_t config = AUDIO_CONFIG_INITIALIZER;
1608         config.sample_rate = samplingRate;
1609         config.channel_mask = channelMask;
1610         config.format = format;
1611         if (offloadInfo != NULL) {
1612             config.offload_info = *offloadInfo;
1613         }
1614         status = mpClientInterface->openOutput(profile->getModuleHandle(),
1615                                                &output,
1616                                                &config,
1617                                                &outputDesc->mDevice,
1618                                                String8(""),
1619                                                &outputDesc->mLatency,
1620                                                outputDesc->mFlags);
1621 
1622         // only accept an output with the requested parameters
1623         if (status != NO_ERROR ||
1624             (samplingRate != 0 && samplingRate != config.sample_rate) ||
1625             (format != AUDIO_FORMAT_DEFAULT && format != config.format) ||
1626             (channelMask != 0 && channelMask != config.channel_mask)) {
1627             ALOGV("getOutput() failed opening direct output: output %d samplingRate %d %d,"
1628                     "format %d %d, channelMask %04x %04x", output, samplingRate,
1629                     outputDesc->mSamplingRate, format, outputDesc->mFormat, channelMask,
1630                     outputDesc->mChannelMask);
1631             if (output != AUDIO_IO_HANDLE_NONE) {
1632                 mpClientInterface->closeOutput(output);
1633             }
1634             // fall back to mixer output if possible when the direct output could not be open
1635             if (audio_is_linear_pcm(format) && samplingRate <= MAX_MIXER_SAMPLING_RATE) {
1636                 goto non_direct_output;
1637             }
1638             return AUDIO_IO_HANDLE_NONE;
1639         }
1640         outputDesc->mSamplingRate = config.sample_rate;
1641         outputDesc->mChannelMask = config.channel_mask;
1642         outputDesc->mFormat = config.format;
1643         outputDesc->mRefCount[stream] = 0;
1644         outputDesc->mStopTime[stream] = 0;
1645         outputDesc->mDirectOpenCount = 1;
1646 
1647         audio_io_handle_t srcOutput = getOutputForEffect();
1648         addOutput(output, outputDesc);
1649         audio_io_handle_t dstOutput = getOutputForEffect();
1650         if (dstOutput == output) {
1651 #ifdef DOLBY_ENABLE
1652             status_t status = mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
1653             if (status == NO_ERROR) {
1654                 for (size_t i = 0; i < mEffects.size(); i++) {
1655                     sp<EffectDescriptor> desc = mEffects.valueAt(i);
1656                     if (desc->mSession == AUDIO_SESSION_OUTPUT_MIX) {
1657                         // update the mIo member of EffectDescriptor for the global effect
1658                         ALOGV("%s updating mIo", __FUNCTION__);
1659                         desc->mIo = dstOutput;
1660                     }
1661                 }
1662             } else {
1663                 ALOGW("%s moveEffects from %d to %d failed", __FUNCTION__, srcOutput, dstOutput);
1664             }
1665 #else // DOLBY_END
1666             mpClientInterface->moveEffects(AUDIO_SESSION_OUTPUT_MIX, srcOutput, dstOutput);
1667 #endif // LINE_ADDED_BY_DOLBY
1668         }
1669         mPreviousOutputs = mOutputs;
1670         ALOGV("getOutput() returns new direct output %d", output);
1671         mpClientInterface->onAudioPortListUpdate();
1672         return output;
1673     }
1674 
1675 non_direct_output:
1676     // ignoring channel mask due to downmix capability in mixer
1677 
1678     // open a non direct output
1679 
1680     // for non direct outputs, only PCM is supported
1681     if (audio_is_linear_pcm(format)) {
1682         // get which output is suitable for the specified stream. The actual
1683         // routing change will happen when startOutput() will be called
1684         SortedVector<audio_io_handle_t> outputs = getOutputsForDevice(device, mOutputs);
1685 
1686         // at this stage we should ignore the DIRECT flag as no direct output could be found earlier
1687         flags = (audio_output_flags_t)(flags & ~AUDIO_OUTPUT_FLAG_DIRECT);
1688         output = selectOutput(outputs, flags, format);
1689     }
1690     ALOGW_IF((output == 0), "getOutput() could not find output for stream %d, samplingRate %d,"
1691             "format %d, channels %x, flags %x", stream, samplingRate, format, channelMask, flags);
1692 
1693     ALOGV("  getOutputForDevice() returns output %d", output);
1694 
1695     return output;
1696 }
1697 
getInputForAttr(const audio_attributes_t * attr,audio_io_handle_t * input,audio_session_t session,uid_t uid,uint32_t samplingRate,audio_format_t format,audio_channel_mask_t channelMask,audio_input_flags_t flags,audio_port_handle_t selectedDeviceId,input_type_t * inputType)1698 status_t AudioPolicyManagerCustom::getInputForAttr(const audio_attributes_t *attr,
1699                                              audio_io_handle_t *input,
1700                                              audio_session_t session,
1701                                              uid_t uid,
1702                                              uint32_t samplingRate,
1703                                              audio_format_t format,
1704                                              audio_channel_mask_t channelMask,
1705                                              audio_input_flags_t flags,
1706                                              audio_port_handle_t selectedDeviceId,
1707                                              input_type_t *inputType)
1708 {
1709     audio_source_t inputSource = attr->source;
1710 #ifdef VOICE_CONCURRENCY
1711 
1712     char propValue[PROPERTY_VALUE_MAX];
1713     bool prop_rec_enabled=false, prop_voip_enabled = false;
1714 
1715     if(property_get("voice.record.conc.disabled", propValue, NULL)) {
1716         prop_rec_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
1717     }
1718 
1719     if(property_get("voice.voip.conc.disabled", propValue, NULL)) {
1720         prop_voip_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
1721      }
1722 
1723     if (prop_rec_enabled && mvoice_call_state) {
1724          //check if voice call is active  / running in background
1725          //some of VoIP apps(like SIP2SIP call) supports resume of VoIP call when call in progress
1726          //Need to block input request
1727         if((AUDIO_MODE_IN_CALL == mEngine->getPhoneState()) ||
1728            ((AUDIO_MODE_IN_CALL == mPrevPhoneState) &&
1729              (AUDIO_MODE_IN_COMMUNICATION == mEngine->getPhoneState())))
1730         {
1731             switch(inputSource) {
1732                 case AUDIO_SOURCE_VOICE_UPLINK:
1733                 case AUDIO_SOURCE_VOICE_DOWNLINK:
1734                 case AUDIO_SOURCE_VOICE_CALL:
1735                     ALOGD("voice_conc:Creating input during incall mode for inputSource: %d",
1736                         inputSource);
1737                 break;
1738 
1739                 case AUDIO_SOURCE_VOICE_COMMUNICATION:
1740                     if(prop_voip_enabled) {
1741                        ALOGD("voice_conc:BLOCK VoIP requst incall mode for inputSource: %d",
1742                         inputSource);
1743                        return NO_INIT;
1744                     }
1745                 break;
1746                 default:
1747                     ALOGD("voice_conc:BLOCK VoIP requst incall mode for inputSource: %d",
1748                         inputSource);
1749                 return NO_INIT;
1750             }
1751         }
1752     }//check for VoIP flag
1753     else if(prop_voip_enabled && mvoice_call_state) {
1754          //check if voice call is active  / running in background
1755          //some of VoIP apps(like SIP2SIP call) supports resume of VoIP call when call in progress
1756          //Need to block input request
1757         if((AUDIO_MODE_IN_CALL == mEngine->getPhoneState()) ||
1758            ((AUDIO_MODE_IN_CALL == mPrevPhoneState) &&
1759              (AUDIO_MODE_IN_COMMUNICATION == mEngine->getPhoneState())))
1760         {
1761             if(inputSource == AUDIO_SOURCE_VOICE_COMMUNICATION) {
1762                 ALOGD("BLOCKING VoIP request during incall mode for inputSource: %d ",inputSource);
1763                 return NO_INIT;
1764             }
1765         }
1766     }
1767 
1768 #endif
1769 
1770     return AudioPolicyManager::getInputForAttr(attr,
1771                                                input,
1772                                                session,
1773                                                uid,
1774                                                samplingRate,
1775                                                format,
1776                                                channelMask,
1777                                                flags,
1778                                                selectedDeviceId,
1779                                                inputType);
1780 }
startInput(audio_io_handle_t input,audio_session_t session)1781 status_t AudioPolicyManagerCustom::startInput(audio_io_handle_t input,
1782                                         audio_session_t session)
1783 {
1784     ALOGV("startInput() input %d", input);
1785     ssize_t index = mInputs.indexOfKey(input);
1786     if (index < 0) {
1787         ALOGW("startInput() unknown input %d", input);
1788         return BAD_VALUE;
1789     }
1790     sp<AudioInputDescriptor> inputDesc = mInputs.valueAt(index);
1791 
1792     index = inputDesc->mSessions.indexOf(session);
1793     if (index < 0) {
1794         ALOGW("startInput() unknown session %d on input %d", session, input);
1795         return BAD_VALUE;
1796     }
1797 
1798     // virtual input devices are compatible with other input devices
1799     if (!is_virtual_input_device(inputDesc->mDevice)) {
1800 
1801         // for a non-virtual input device, check if there is another (non-virtual) active input
1802         audio_io_handle_t activeInput = mInputs.getActiveInput();
1803         if (activeInput != 0 && activeInput != input) {
1804 
1805             // If the already active input uses AUDIO_SOURCE_HOTWORD then it is closed,
1806             // otherwise the active input continues and the new input cannot be started.
1807             sp<AudioInputDescriptor> activeDesc = mInputs.valueFor(activeInput);
1808             if (activeDesc->mInputSource == AUDIO_SOURCE_HOTWORD) {
1809                 ALOGW("startInput(%d) preempting low-priority input %d", input, activeInput);
1810                 stopInput(activeInput, activeDesc->mSessions.itemAt(0));
1811                 releaseInput(activeInput, activeDesc->mSessions.itemAt(0));
1812             } else {
1813                 ALOGE("startInput(%d) failed: other input %d already started", input, activeInput);
1814                 return INVALID_OPERATION;
1815             }
1816         }
1817     }
1818 
1819     // Routing?
1820     mInputRoutes.incRouteActivity(session);
1821 #ifdef RECORD_PLAY_CONCURRENCY
1822     mIsInputRequestOnProgress = true;
1823 
1824     char getPropValue[PROPERTY_VALUE_MAX];
1825     bool prop_rec_play_enabled = false;
1826 
1827     if (property_get("rec.playback.conc.disabled", getPropValue, NULL)) {
1828         prop_rec_play_enabled = atoi(getPropValue) || !strncmp("true", getPropValue, 4);
1829     }
1830 
1831     if ((prop_rec_play_enabled) &&(mInputs.activeInputsCount() == 0)){
1832         // send update to HAL on record playback concurrency
1833         AudioParameter param = AudioParameter();
1834         param.add(String8("rec_play_conc_on"), String8("true"));
1835         ALOGD("startInput() setParameters rec_play_conc is setting to ON ");
1836         mpClientInterface->setParameters(0, param.toString());
1837 
1838         // Call invalidate to reset all opened non ULL audio tracks
1839         // Move tracks associated to this strategy from previous output to new output
1840         for (int i = AUDIO_STREAM_SYSTEM; i < (int)AUDIO_STREAM_CNT; i++) {
1841             // Do not call invalidate for ENFORCED_AUDIBLE (otherwise pops are seen for camcorder)
1842             if ((i != AUDIO_STREAM_ENFORCED_AUDIBLE) && (i != AUDIO_STREAM_PATCH)) {
1843                ALOGD("Invalidate on releaseInput for stream :: %d ", i);
1844                //FIXME see fixme on name change
1845                mpClientInterface->invalidateStream((audio_stream_type_t)i);
1846             }
1847         }
1848         // close compress tracks
1849         for (size_t i = 0; i < mOutputs.size(); i++) {
1850             sp<SwAudioOutputDescriptor> outputDesc = mOutputs.valueAt(i);
1851             if ((outputDesc == NULL) || (outputDesc->mProfile == NULL)) {
1852                ALOGD("ouput desc / profile is NULL");
1853                continue;
1854             }
1855             if (outputDesc->mProfile->mFlags
1856                             & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) {
1857                 // close compress  sessions
1858                 ALOGD("calling closeOutput on record conc for COMPRESS output");
1859                 closeOutput(mOutputs.keyAt(i));
1860             }
1861         }
1862     }
1863 #endif
1864 
1865     if (inputDesc->mRefCount == 0 || mInputRoutes.hasRouteChanged(session)) {
1866         // if input maps to a dynamic policy with an activity listener, notify of state change
1867         if ((inputDesc->mPolicyMix != NULL)
1868                 && ((inputDesc->mPolicyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
1869             mpClientInterface->onDynamicPolicyMixStateUpdate(inputDesc->mPolicyMix->mRegistrationId,
1870                     MIX_STATE_MIXING);
1871         }
1872 
1873         if (mInputs.activeInputsCount() == 0) {
1874             SoundTrigger::setCaptureState(true);
1875         }
1876         setInputDevice(input, getNewInputDevice(input), true /* force */);
1877 
1878         // automatically enable the remote submix output when input is started if not
1879         // used by a policy mix of type MIX_TYPE_RECORDERS
1880         // For remote submix (a virtual device), we open only one input per capture request.
1881         if (audio_is_remote_submix_device(inputDesc->mDevice)) {
1882             String8 address = String8("");
1883             if (inputDesc->mPolicyMix == NULL) {
1884                 address = String8("0");
1885             } else if (inputDesc->mPolicyMix->mMixType == MIX_TYPE_PLAYERS) {
1886                 address = inputDesc->mPolicyMix->mRegistrationId;
1887             }
1888             if (address != "") {
1889                 setDeviceConnectionStateInt(AUDIO_DEVICE_OUT_REMOTE_SUBMIX,
1890                         AUDIO_POLICY_DEVICE_STATE_AVAILABLE,
1891                         address, "remote-submix");
1892             }
1893         }
1894     }
1895 
1896     ALOGV("AudioPolicyManager::startInput() input source = %d", inputDesc->mInputSource);
1897 
1898     inputDesc->mRefCount++;
1899 #ifdef RECORD_PLAY_CONCURRENCY
1900     mIsInputRequestOnProgress = false;
1901 #endif
1902     return NO_ERROR;
1903 }
stopInput(audio_io_handle_t input,audio_session_t session)1904 status_t AudioPolicyManagerCustom::stopInput(audio_io_handle_t input,
1905                                        audio_session_t session)
1906 {
1907     status_t status;
1908     status = AudioPolicyManager::stopInput(input, session);
1909 #ifdef RECORD_PLAY_CONCURRENCY
1910     char propValue[PROPERTY_VALUE_MAX];
1911     bool prop_rec_play_enabled = false;
1912 
1913     if (property_get("rec.playback.conc.disabled", propValue, NULL)) {
1914         prop_rec_play_enabled = atoi(propValue) || !strncmp("true", propValue, 4);
1915     }
1916 
1917     if ((prop_rec_play_enabled) && (mInputs.activeInputsCount() == 0)) {
1918 
1919         //send update to HAL on record playback concurrency
1920         AudioParameter param = AudioParameter();
1921         param.add(String8("rec_play_conc_on"), String8("false"));
1922         ALOGD("stopInput() setParameters rec_play_conc is setting to OFF ");
1923         mpClientInterface->setParameters(0, param.toString());
1924 
1925         //call invalidate tracks so that any open streams can fall back to deep buffer/compress path from ULL
1926         for (int i = AUDIO_STREAM_SYSTEM; i < (int)AUDIO_STREAM_CNT; i++) {
1927             //Do not call invalidate for ENFORCED_AUDIBLE (otherwise pops are seen for camcorder stop tone)
1928             if ((i != AUDIO_STREAM_ENFORCED_AUDIBLE) && (i != AUDIO_STREAM_PATCH)) {
1929                ALOGD(" Invalidate on stopInput for stream :: %d ", i);
1930                //FIXME see fixme on name change
1931                mpClientInterface->invalidateStream((audio_stream_type_t)i);
1932             }
1933         }
1934     }
1935 #endif
1936     return status;
1937 }
1938 
AudioPolicyManagerCustom(AudioPolicyClientInterface * clientInterface)1939 AudioPolicyManagerCustom::AudioPolicyManagerCustom(AudioPolicyClientInterface *clientInterface)
1940     : AudioPolicyManager(clientInterface)
1941 {
1942 #ifdef RECORD_PLAY_CONCURRENCY
1943     mIsInputRequestOnProgress = false;
1944 #endif
1945 
1946 
1947 #ifdef VOICE_CONCURRENCY
1948     mFallBackflag = getFallBackPath();
1949 #endif
1950 }
1951 }
1952