1 /*
2  * Copyright (C) 2015 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #define LOG_TAG "APM::AudioOutputDescriptor"
18 //#define LOG_NDEBUG 0
19 
20 #include <AudioPolicyInterface.h>
21 #include "AudioOutputDescriptor.h"
22 #include "AudioPolicyMix.h"
23 #include "IOProfile.h"
24 #include "Volume.h"
25 #include "HwModule.h"
26 #include "TypeConverter.h"
27 #include <media/AudioGain.h>
28 #include <media/AudioParameter.h>
29 #include <media/AudioPolicy.h>
30 
31 // A device mask for all audio output devices that are considered "remote" when evaluating
32 // active output devices in isStreamActiveRemotely()
33 
34 namespace android {
35 
getAllOutRemoteDevices()36 static const DeviceTypeSet& getAllOutRemoteDevices() {
37     static const DeviceTypeSet allOutRemoteDevices = {AUDIO_DEVICE_OUT_REMOTE_SUBMIX};
38     return allOutRemoteDevices;
39 }
40 
AudioOutputDescriptor(const sp<PolicyAudioPort> & policyAudioPort,AudioPolicyClientInterface * clientInterface)41 AudioOutputDescriptor::AudioOutputDescriptor(const sp<PolicyAudioPort>& policyAudioPort,
42                                              AudioPolicyClientInterface *clientInterface)
43     : mPolicyAudioPort(policyAudioPort), mClientInterface(clientInterface)
44 {
45     if (mPolicyAudioPort.get() != nullptr) {
46         mPolicyAudioPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
47         if (mPolicyAudioPort->asAudioPort()->getGains().size() > 0) {
48             mPolicyAudioPort->asAudioPort()->getGains()[0]->getDefaultConfig(&mGain);
49         }
50     }
51 }
52 
getConfig() const53 audio_config_base_t AudioOutputDescriptor::getConfig() const
54 {
55     const audio_config_base_t config = { .sample_rate = mSamplingRate, .channel_mask = mChannelMask,
56             .format = mFormat };
57     return config;
58 }
59 
getModuleHandle() const60 audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
61 {
62     return mPolicyAudioPort.get() != nullptr ?
63             mPolicyAudioPort->getModuleHandle() : AUDIO_MODULE_HANDLE_NONE;
64 }
65 
getPatchHandle() const66 audio_patch_handle_t AudioOutputDescriptor::getPatchHandle() const
67 {
68     return mPatchHandle;
69 }
70 
setPatchHandle(audio_patch_handle_t handle)71 void AudioOutputDescriptor::setPatchHandle(audio_patch_handle_t handle)
72 {
73     mPatchHandle = handle;
74 }
75 
sharesHwModuleWith(const sp<AudioOutputDescriptor> & outputDesc)76 bool AudioOutputDescriptor::sharesHwModuleWith(
77         const sp<AudioOutputDescriptor>& outputDesc)
78 {
79     return hasSameHwModuleAs(outputDesc);
80 }
81 
setStopTime(const sp<TrackClientDescriptor> & client,nsecs_t sysTime)82 void AudioOutputDescriptor::setStopTime(const sp<TrackClientDescriptor>& client, nsecs_t sysTime)
83 {
84     mVolumeActivities[client->volumeSource()].setStopTime(sysTime);
85     mRoutingActivities[client->strategy()].setStopTime(sysTime);
86 }
87 
setClientActive(const sp<TrackClientDescriptor> & client,bool active)88 void AudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active)
89 {
90     auto clientIter = std::find(begin(mActiveClients), end(mActiveClients), client);
91     if (active == (clientIter != end(mActiveClients))) {
92         ALOGW("%s(%s): ignored active: %d, current stream count %d", __func__,
93               client->toShortString().c_str(), active,
94               mRoutingActivities.at(client->strategy()).getActivityCount());
95         return;
96     }
97     if (active) {
98         mActiveClients.push_back(client);
99     } else {
100         mActiveClients.erase(clientIter);
101     }
102     const int delta = active ? 1 : -1;
103     // If ps is unknown, it is time to track it!
104     mRoutingActivities[client->strategy()].changeActivityCount(delta);
105     mVolumeActivities[client->volumeSource()].changeActivityCount(delta);
106 
107     // Handle non-client-specific activity ref count
108     int32_t oldGlobalActiveCount = mGlobalActiveCount;
109     if (!active && mGlobalActiveCount < 1) {
110         ALOGW("%s(%s): invalid deactivation with globalRefCount %d",
111               __func__, client->toShortString().c_str(), mGlobalActiveCount);
112         mGlobalActiveCount = 1;
113     }
114     mGlobalActiveCount += delta;
115 
116     sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
117     if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
118         if ((oldGlobalActiveCount == 0) || (mGlobalActiveCount == 0)) {
119             mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
120                 mGlobalActiveCount > 0 ? MIX_STATE_MIXING : MIX_STATE_IDLE);
121         }
122     }
123     client->setActive(active);
124 }
125 
isClientActive(const sp<TrackClientDescriptor> & client)126 bool AudioOutputDescriptor::isClientActive(const sp<TrackClientDescriptor>& client)
127 {
128     return client != nullptr &&
129             std::find(begin(mActiveClients), end(mActiveClients), client) != end(mActiveClients);
130 }
131 
isActive(VolumeSource vs,uint32_t inPastMs,nsecs_t sysTime) const132 bool AudioOutputDescriptor::isActive(VolumeSource vs, uint32_t inPastMs, nsecs_t sysTime) const
133 {
134     return (vs == VOLUME_SOURCE_NONE) ?
135                 isActive(inPastMs) : (mVolumeActivities.find(vs) != std::end(mVolumeActivities)?
136                 mVolumeActivities.at(vs).isActive(inPastMs, sysTime) : false);
137 }
138 
isActive(uint32_t inPastMs) const139 bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
140 {
141     nsecs_t sysTime = 0;
142     if (inPastMs != 0) {
143         sysTime = systemTime();
144     }
145     for (const auto &iter : mVolumeActivities) {
146         if (iter.second.isActive(inPastMs, sysTime)) {
147             return true;
148         }
149     }
150     return false;
151 }
152 
isFixedVolume(const DeviceTypeSet & deviceTypes __unused)153 bool AudioOutputDescriptor::isFixedVolume(const DeviceTypeSet& deviceTypes __unused)
154 {
155     return false;
156 }
157 
setVolume(float volumeDb,VolumeSource volumeSource,const StreamTypeVector &,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force)158 bool AudioOutputDescriptor::setVolume(float volumeDb,
159                                       VolumeSource volumeSource,
160                                       const StreamTypeVector &/*streams*/,
161                                       const DeviceTypeSet& deviceTypes,
162                                       uint32_t delayMs,
163                                       bool force)
164 {
165 
166     if (!supportedDevices().containsDeviceAmongTypes(deviceTypes)) {
167         ALOGV("%s output ID %d unsupported device %s",
168                 __func__, getId(), toString(deviceTypes).c_str());
169         return false;
170     }
171     // We actually change the volume if:
172     // - the float value returned by computeVolume() changed
173     // - the force flag is set
174     if (volumeDb != getCurVolume(volumeSource) || force) {
175         ALOGV("%s for volumeSrc %d, volume %f, delay %d", __func__, volumeSource, volumeDb, delayMs);
176         setCurVolume(volumeSource, volumeDb);
177         return true;
178     }
179     return false;
180 }
181 
applyAudioPortConfig(const struct audio_port_config * config,audio_port_config * backupConfig)182 status_t AudioOutputDescriptor::applyAudioPortConfig(const struct audio_port_config *config,
183                                                      audio_port_config *backupConfig)
184 {
185     struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
186     status_t status = NO_ERROR;
187 
188     toAudioPortConfig(&localBackupConfig);
189     if ((status = validationBeforeApplyConfig(config)) == NO_ERROR) {
190         AudioPortConfig::applyAudioPortConfig(config, backupConfig);
191         applyPolicyAudioPortConfig(config);
192     }
193 
194     if (backupConfig != NULL) {
195         *backupConfig = localBackupConfig;
196     }
197     return status;
198 }
199 
200 
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const201 void AudioOutputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
202                                               const struct audio_port_config *srcConfig) const
203 {
204     dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
205                             AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
206     if (srcConfig != NULL) {
207         dstConfig->config_mask |= srcConfig->config_mask;
208     }
209     AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
210     toPolicyAudioPortConfig(dstConfig, srcConfig);
211 
212     dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
213     dstConfig->type = AUDIO_PORT_TYPE_MIX;
214     dstConfig->ext.mix.hw_module = getModuleHandle();
215     dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
216 }
217 
toAudioPort(struct audio_port_v7 * port) const218 void AudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
219 {
220     // Should not be called for duplicated ports, see SwAudioOutputDescriptor::toAudioPortConfig.
221     mPolicyAudioPort->asAudioPort()->toAudioPort(port);
222     port->id = mId;
223     port->ext.mix.hw_module = getModuleHandle();
224 }
225 
clientsList(bool activeOnly,product_strategy_t strategy,bool preferredDeviceOnly) const226 TrackClientVector AudioOutputDescriptor::clientsList(bool activeOnly, product_strategy_t strategy,
227                                                      bool preferredDeviceOnly) const
228 {
229     TrackClientVector clients;
230     for (const auto &client : getClientIterable()) {
231         if ((!activeOnly || client->active())
232             && (strategy == PRODUCT_STRATEGY_NONE || strategy == client->strategy())
233             && (!preferredDeviceOnly ||
234                 (client->hasPreferredDevice() && !client->isPreferredDeviceForExclusiveUse()))) {
235             clients.push_back(client);
236         }
237     }
238     return clients;
239 }
240 
isAnyActive(VolumeSource volumeSourceToIgnore) const241 bool AudioOutputDescriptor::isAnyActive(VolumeSource volumeSourceToIgnore) const
242 {
243     return std::find_if(begin(mActiveClients), end(mActiveClients),
244                         [&volumeSourceToIgnore](const auto &client) {
245         return client->volumeSource() != volumeSourceToIgnore; }) != end(mActiveClients);
246 }
247 
dump(String8 * dst) const248 void AudioOutputDescriptor::dump(String8 *dst) const
249 {
250     dst->appendFormat(" ID: %d\n", mId);
251     dst->appendFormat(" Sampling rate: %d\n", mSamplingRate);
252     dst->appendFormat(" Format: %08x\n", mFormat);
253     dst->appendFormat(" Channels: %08x\n", mChannelMask);
254     dst->appendFormat(" Devices: %s\n", devices().toString(true /*includeSensitiveInfo*/).c_str());
255     dst->appendFormat(" Global active count: %u\n", mGlobalActiveCount);
256     for (const auto &iter : mRoutingActivities) {
257         dst->appendFormat(" Product Strategy id: %d", iter.first);
258         iter.second.dump(dst, 4);
259     }
260     for (const auto &iter : mVolumeActivities) {
261         dst->appendFormat(" Volume Activities id: %d", iter.first);
262         iter.second.dump(dst, 4);
263     }
264     dst->append(" AudioTrack Clients:\n");
265     ClientMapHandler<TrackClientDescriptor>::dump(dst);
266     dst->append("\n");
267     if (!mActiveClients.empty()) {
268         dst->append(" AudioTrack active (stream) clients:\n");
269         size_t index = 0;
270         for (const auto& client : mActiveClients) {
271             client->dump(dst, 2, index++);
272         }
273         dst->append(" \n");
274     }
275 }
276 
log(const char * indent)277 void AudioOutputDescriptor::log(const char* indent)
278 {
279     ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]",
280           indent, mId, mId, mSamplingRate, mFormat, mChannelMask);
281 }
282 
283 // SwAudioOutputDescriptor implementation
SwAudioOutputDescriptor(const sp<IOProfile> & profile,AudioPolicyClientInterface * clientInterface)284 SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
285                                                  AudioPolicyClientInterface *clientInterface)
286     : AudioOutputDescriptor(profile, clientInterface),
287     mProfile(profile), mIoHandle(AUDIO_IO_HANDLE_NONE), mLatency(0),
288     mFlags((audio_output_flags_t)0),
289     mOutput1(0), mOutput2(0), mDirectOpenCount(0),
290     mDirectClientSession(AUDIO_SESSION_NONE)
291 {
292     if (profile != NULL) {
293         mFlags = (audio_output_flags_t)profile->getFlags();
294     }
295 }
296 
dump(String8 * dst) const297 void SwAudioOutputDescriptor::dump(String8 *dst) const
298 {
299     dst->appendFormat(" Latency: %d\n", mLatency);
300     dst->appendFormat(" Flags %08x\n", mFlags);
301     AudioOutputDescriptor::dump(dst);
302 }
303 
devices() const304 DeviceVector SwAudioOutputDescriptor::devices() const
305 {
306     if (isDuplicated()) {
307         DeviceVector devices = mOutput1->devices();
308         devices.merge(mOutput2->devices());
309         return devices;
310     }
311     return mDevices;
312 }
313 
sharesHwModuleWith(const sp<SwAudioOutputDescriptor> & outputDesc)314 bool SwAudioOutputDescriptor::sharesHwModuleWith(
315         const sp<SwAudioOutputDescriptor>& outputDesc)
316 {
317     if (isDuplicated()) {
318         return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
319     } else if (outputDesc->isDuplicated()){
320         return sharesHwModuleWith(outputDesc->subOutput1()) ||
321                     sharesHwModuleWith(outputDesc->subOutput2());
322     } else {
323         return AudioOutputDescriptor::sharesHwModuleWith(outputDesc);
324     }
325 }
326 
supportedDevices() const327 DeviceVector SwAudioOutputDescriptor::supportedDevices() const
328 {
329     if (isDuplicated()) {
330         DeviceVector supportedDevices = mOutput1->supportedDevices();
331         supportedDevices.merge(mOutput2->supportedDevices());
332         return supportedDevices;
333     }
334     return mProfile->getSupportedDevices();
335 }
336 
supportsDevice(const sp<DeviceDescriptor> & device) const337 bool SwAudioOutputDescriptor::supportsDevice(const sp<DeviceDescriptor> &device) const
338 {
339     return supportedDevices().contains(device);
340 }
341 
supportsAllDevices(const DeviceVector & devices) const342 bool SwAudioOutputDescriptor::supportsAllDevices(const DeviceVector &devices) const
343 {
344     return supportedDevices().containsAllDevices(devices);
345 }
346 
supportsDevicesForPlayback(const DeviceVector & devices) const347 bool SwAudioOutputDescriptor::supportsDevicesForPlayback(const DeviceVector &devices) const
348 {
349     // No considering duplicated output
350     // TODO: need to verify if the profile supports the devices combo for playback.
351     return !isDuplicated() && supportsAllDevices(devices);
352 }
353 
filterSupportedDevices(const DeviceVector & devices) const354 DeviceVector SwAudioOutputDescriptor::filterSupportedDevices(const DeviceVector &devices) const
355 {
356     DeviceVector filteredDevices = supportedDevices();
357     return filteredDevices.filter(devices);
358 }
359 
devicesSupportEncodedFormats(const DeviceTypeSet & deviceTypes)360 bool SwAudioOutputDescriptor::devicesSupportEncodedFormats(const DeviceTypeSet& deviceTypes)
361 {
362     if (isDuplicated()) {
363         return (mOutput1->devicesSupportEncodedFormats(deviceTypes)
364                     || mOutput2->devicesSupportEncodedFormats(deviceTypes));
365     } else {
366        return mProfile->devicesSupportEncodedFormats(deviceTypes);
367     }
368 }
369 
containsSingleDeviceSupportingEncodedFormats(const sp<DeviceDescriptor> & device) const370 bool SwAudioOutputDescriptor::containsSingleDeviceSupportingEncodedFormats(
371         const sp<DeviceDescriptor>& device) const
372 {
373     if (isDuplicated()) {
374         return (mOutput1->containsSingleDeviceSupportingEncodedFormats(device) &&
375                 mOutput2->containsSingleDeviceSupportingEncodedFormats(device));
376     }
377     return mProfile->containsSingleDeviceSupportingEncodedFormats(device);
378 }
379 
latency()380 uint32_t SwAudioOutputDescriptor::latency()
381 {
382     if (isDuplicated()) {
383         return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
384     } else {
385         return mLatency;
386     }
387 }
388 
setClientActive(const sp<TrackClientDescriptor> & client,bool active)389 void SwAudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active)
390 {
391     // forward usage count change to attached outputs
392     if (isDuplicated()) {
393         mOutput1->setClientActive(client, active);
394         mOutput2->setClientActive(client, active);
395     }
396     AudioOutputDescriptor::setClientActive(client, active);
397 }
398 
isFixedVolume(const DeviceTypeSet & deviceTypes)399 bool SwAudioOutputDescriptor::isFixedVolume(const DeviceTypeSet& deviceTypes)
400 {
401     // unit gain if rerouting to external policy
402     if (isSingleDeviceType(deviceTypes, AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) {
403         if (mPolicyMix != NULL) {
404             ALOGV("max gain when rerouting for output=%d", mIoHandle);
405             return true;
406         }
407     }
408     if (isSingleDeviceType(deviceTypes, AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
409         ALOGV("max gain when output device is telephony tx");
410         return true;
411     }
412     return false;
413 }
414 
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const415 void SwAudioOutputDescriptor::toAudioPortConfig(
416                                                  struct audio_port_config *dstConfig,
417                                                  const struct audio_port_config *srcConfig) const
418 {
419 
420     ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
421     AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig);
422 
423     dstConfig->ext.mix.handle = mIoHandle;
424 }
425 
toAudioPort(struct audio_port_v7 * port) const426 void SwAudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
427 {
428     ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
429 
430     AudioOutputDescriptor::toAudioPort(port);
431 
432     toAudioPortConfig(&port->active_config);
433     port->ext.mix.handle = mIoHandle;
434     port->ext.mix.latency_class =
435             mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
436 }
437 
setVolume(float volumeDb,VolumeSource vs,const StreamTypeVector & streamTypes,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force)438 bool SwAudioOutputDescriptor::setVolume(float volumeDb,
439                                         VolumeSource vs, const StreamTypeVector &streamTypes,
440                                         const DeviceTypeSet& deviceTypes,
441                                         uint32_t delayMs,
442                                         bool force)
443 {
444     StreamTypeVector streams = streamTypes;
445     if (!AudioOutputDescriptor::setVolume(volumeDb, vs, streamTypes, deviceTypes, delayMs, force)) {
446         return false;
447     }
448     if (streams.empty()) {
449         streams.push_back(AUDIO_STREAM_MUSIC);
450     }
451     for (const auto& devicePort : devices()) {
452         // APM loops on all group, so filter on active group to set the port gain,
453         // let the other groups set the stream volume as per legacy
454         // TODO: Pass in the device address and check against it.
455         if (isSingleDeviceType(deviceTypes, devicePort->type()) &&
456                 devicePort->hasGainController(true) && isActive(vs)) {
457             ALOGV("%s: device %s has gain controller", __func__, devicePort->toString().c_str());
458             // @todo: here we might be in trouble if the SwOutput has several active clients with
459             // different Volume Source (or if we allow several curves within same volume group)
460             //
461             // @todo: default stream volume to max (0) when using HW Port gain?
462             float volumeAmpl = Volume::DbToAmpl(0);
463             for (const auto &stream : streams) {
464                 mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
465             }
466 
467             AudioGains gains = devicePort->getGains();
468             int gainMinValueInMb = gains[0]->getMinValueInMb();
469             int gainMaxValueInMb = gains[0]->getMaxValueInMb();
470             int gainStepValueInMb = gains[0]->getStepValueInMb();
471             int gainValueMb = ((volumeDb * 100)/ gainStepValueInMb) * gainStepValueInMb;
472             gainValueMb = std::max(gainMinValueInMb, std::min(gainValueMb, gainMaxValueInMb));
473 
474             audio_port_config config = {};
475             devicePort->toAudioPortConfig(&config);
476             config.config_mask = AUDIO_PORT_CONFIG_GAIN;
477             config.gain.values[0] = gainValueMb;
478             return mClientInterface->setAudioPortConfig(&config, 0) == NO_ERROR;
479         }
480     }
481     // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is enabled
482     float volumeAmpl = Volume::DbToAmpl(getCurVolume(vs));
483     if (hasStream(streams, AUDIO_STREAM_BLUETOOTH_SCO)) {
484         mClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volumeAmpl, mIoHandle, delayMs);
485     }
486     for (const auto &stream : streams) {
487         ALOGV("%s output %d for volumeSource %d, volume %f, delay %d stream=%s", __func__,
488               mIoHandle, vs, volumeDb, delayMs, toString(stream).c_str());
489         mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
490     }
491     return true;
492 }
493 
open(const audio_config_t * halConfig,const audio_config_base_t * mixerConfig,const DeviceVector & devices,audio_stream_type_t stream,audio_output_flags_t flags,audio_io_handle_t * output)494 status_t SwAudioOutputDescriptor::open(const audio_config_t *halConfig,
495                                        const audio_config_base_t *mixerConfig,
496                                        const DeviceVector &devices,
497                                        audio_stream_type_t stream,
498                                        audio_output_flags_t flags,
499                                        audio_io_handle_t *output)
500 {
501     mDevices = devices;
502     sp<DeviceDescriptor> device = devices.getDeviceForOpening();
503     LOG_ALWAYS_FATAL_IF(device == nullptr,
504                         "%s failed to get device descriptor for opening "
505                         "with the requested devices, all device types: %s",
506                         __func__, dumpDeviceTypes(devices.types()).c_str());
507 
508     audio_config_t lHalConfig;
509     if (halConfig == nullptr) {
510         lHalConfig = AUDIO_CONFIG_INITIALIZER;
511         lHalConfig.sample_rate = mSamplingRate;
512         lHalConfig.channel_mask = mChannelMask;
513         lHalConfig.format = mFormat;
514     } else {
515         lHalConfig = *halConfig;
516     }
517 
518     // if the selected profile is offloaded and no offload info was specified,
519     // create a default one
520     if ((mProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
521             lHalConfig.offload_info.format == AUDIO_FORMAT_DEFAULT) {
522         flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
523         lHalConfig.offload_info = AUDIO_INFO_INITIALIZER;
524         lHalConfig.offload_info.sample_rate = lHalConfig.sample_rate;
525         lHalConfig.offload_info.channel_mask = lHalConfig.channel_mask;
526         lHalConfig.offload_info.format = lHalConfig.format;
527         lHalConfig.offload_info.stream_type = stream;
528         lHalConfig.offload_info.duration_us = -1;
529         lHalConfig.offload_info.has_video = true; // conservative
530         lHalConfig.offload_info.is_streaming = true; // likely
531         lHalConfig.offload_info.encapsulation_mode = lHalConfig.offload_info.encapsulation_mode;
532         lHalConfig.offload_info.content_id = lHalConfig.offload_info.content_id;
533         lHalConfig.offload_info.sync_id = lHalConfig.offload_info.sync_id;
534     }
535 
536     audio_config_base_t lMixerConfig;
537     if (mixerConfig == nullptr) {
538         lMixerConfig = AUDIO_CONFIG_BASE_INITIALIZER;
539         lMixerConfig.sample_rate = lHalConfig.sample_rate;
540         lMixerConfig.channel_mask = lHalConfig.channel_mask;
541         lMixerConfig.format = lHalConfig.format;
542     } else {
543         lMixerConfig = *mixerConfig;
544     }
545 
546     mFlags = (audio_output_flags_t)(mFlags | flags);
547 
548     //TODO: b/193496180 use spatializer flag at audio HAL when available
549     audio_output_flags_t halFlags = mFlags;
550     if ((mFlags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0) {
551         halFlags = (audio_output_flags_t)(AUDIO_OUTPUT_FLAG_FAST | AUDIO_OUTPUT_FLAG_DEEP_BUFFER);
552     }
553 
554     ALOGV("opening output for device %s profile %p name %s",
555           mDevices.toString().c_str(), mProfile.get(), mProfile->getName().c_str());
556 
557     status_t status = mClientInterface->openOutput(mProfile->getModuleHandle(),
558                                                    output,
559                                                    &lHalConfig,
560                                                    &lMixerConfig,
561                                                    device,
562                                                    &mLatency,
563                                                    halFlags);
564 
565     if (status == NO_ERROR) {
566         LOG_ALWAYS_FATAL_IF(*output == AUDIO_IO_HANDLE_NONE,
567                             "%s openOutput returned output handle %d for device %s, "
568                             "selected device %s for opening",
569                             __FUNCTION__, *output, devices.toString().c_str(),
570                             device->toString().c_str());
571         mSamplingRate = lHalConfig.sample_rate;
572         mChannelMask = lHalConfig.channel_mask;
573         mFormat = lHalConfig.format;
574         mMixerChannelMask = lMixerConfig.channel_mask;
575         mId = PolicyAudioPort::getNextUniqueId();
576         mIoHandle = *output;
577         mProfile->curOpenCount++;
578     }
579 
580     return status;
581 }
582 
start()583 status_t SwAudioOutputDescriptor::start()
584 {
585     if (isDuplicated()) {
586         status_t status = mOutput1->start();
587         if (status != NO_ERROR) {
588             return status;
589         }
590         status = mOutput2->start();
591         if (status != NO_ERROR) {
592             mOutput1->stop();
593             return status;
594         }
595         return NO_ERROR;
596     }
597     if (!isActive()) {
598         if (!mProfile->canStartNewIo()) {
599             return INVALID_OPERATION;
600         }
601         mProfile->curActiveCount++;
602     }
603     return NO_ERROR;
604 }
605 
stop()606 void SwAudioOutputDescriptor::stop()
607 {
608     if (isDuplicated()) {
609         mOutput1->stop();
610         mOutput2->stop();
611         return;
612     }
613 
614     if (!isActive()) {
615         LOG_ALWAYS_FATAL_IF(mProfile->curActiveCount < 1,
616                             "%s invalid profile active count %u",
617                             __func__, mProfile->curActiveCount);
618         mProfile->curActiveCount--;
619     }
620 }
621 
close()622 void SwAudioOutputDescriptor::close()
623 {
624     if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
625         // clean up active clients if any (can happen if close() is called to force
626         // clients to reconnect
627         for (const auto &client : getClientIterable()) {
628             if (client->active()) {
629                 ALOGW("%s client with port ID %d still active on output %d",
630                       __func__, client->portId(), mId);
631                 setClientActive(client, false);
632                 stop();
633             }
634         }
635 
636         AudioParameter param;
637         param.add(String8("closing"), String8("true"));
638         mClientInterface->setParameters(mIoHandle, param.toString());
639 
640         mClientInterface->closeOutput(mIoHandle);
641 
642         LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
643                             __FUNCTION__, mProfile->curOpenCount);
644         mProfile->curOpenCount--;
645         mIoHandle = AUDIO_IO_HANDLE_NONE;
646     }
647 }
648 
openDuplicating(const sp<SwAudioOutputDescriptor> & output1,const sp<SwAudioOutputDescriptor> & output2,audio_io_handle_t * ioHandle)649 status_t SwAudioOutputDescriptor::openDuplicating(const sp<SwAudioOutputDescriptor>& output1,
650                                                   const sp<SwAudioOutputDescriptor>& output2,
651                                                   audio_io_handle_t *ioHandle)
652 {
653     // open a duplicating output thread for the new output and the primary output
654     // Note: openDuplicateOutput() API expects the output handles in the reverse order from the
655     // numbering in SwAudioOutputDescriptor mOutput1 and mOutput2
656     *ioHandle = mClientInterface->openDuplicateOutput(output2->mIoHandle, output1->mIoHandle);
657     if (*ioHandle == AUDIO_IO_HANDLE_NONE) {
658         return INVALID_OPERATION;
659     }
660 
661     mId = PolicyAudioPort::getNextUniqueId();
662     mIoHandle = *ioHandle;
663     mOutput1 = output1;
664     mOutput2 = output2;
665     mSamplingRate = output2->mSamplingRate;
666     mFormat = output2->mFormat;
667     mChannelMask = output2->mChannelMask;
668     mLatency = output2->mLatency;
669 
670     return NO_ERROR;
671 }
672 
673 // HwAudioOutputDescriptor implementation
HwAudioOutputDescriptor(const sp<SourceClientDescriptor> & source,AudioPolicyClientInterface * clientInterface)674 HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<SourceClientDescriptor>& source,
675                                                  AudioPolicyClientInterface *clientInterface)
676     : AudioOutputDescriptor(source->srcDevice(), clientInterface),
677       mSource(source)
678 {
679 }
680 
dump(String8 * dst) const681 void HwAudioOutputDescriptor::dump(String8 *dst) const
682 {
683     AudioOutputDescriptor::dump(dst);
684     dst->append("Source:\n");
685     mSource->dump(dst, 0, 0);
686 }
687 
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const688 void HwAudioOutputDescriptor::toAudioPortConfig(
689                                                  struct audio_port_config *dstConfig,
690                                                  const struct audio_port_config *srcConfig) const
691 {
692     mSource->srcDevice()->toAudioPortConfig(dstConfig, srcConfig);
693 }
694 
toAudioPort(struct audio_port_v7 * port) const695 void HwAudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
696 {
697     mSource->srcDevice()->toAudioPort(port);
698 }
699 
700 
setVolume(float volumeDb,VolumeSource volumeSource,const StreamTypeVector & streams,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force)701 bool HwAudioOutputDescriptor::setVolume(float volumeDb,
702                                         VolumeSource volumeSource, const StreamTypeVector &streams,
703                                         const DeviceTypeSet& deviceTypes,
704                                         uint32_t delayMs,
705                                         bool force)
706 {
707     bool changed = AudioOutputDescriptor::setVolume(
708             volumeDb, volumeSource, streams, deviceTypes, delayMs, force);
709 
710     if (changed) {
711       // TODO: use gain controller on source device if any to adjust volume
712     }
713     return changed;
714 }
715 
716 // SwAudioOutputCollection implementation
isActive(VolumeSource volumeSource,uint32_t inPastMs) const717 bool SwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const
718 {
719     nsecs_t sysTime = systemTime();
720     for (size_t i = 0; i < this->size(); i++) {
721         const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
722         if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
723             return true;
724         }
725     }
726     return false;
727 }
728 
isActiveLocally(VolumeSource volumeSource,uint32_t inPastMs) const729 bool SwAudioOutputCollection::isActiveLocally(VolumeSource volumeSource, uint32_t inPastMs) const
730 {
731     nsecs_t sysTime = systemTime();
732     for (size_t i = 0; i < this->size(); i++) {
733         const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
734         if (outputDesc->isActive(volumeSource, inPastMs, sysTime)
735                 && (!(outputDesc->devices()
736                         .containsDeviceAmongTypes(getAllOutRemoteDevices())
737                         || outputDesc->devices()
738                             .onlyContainsDevicesWithType(AUDIO_DEVICE_OUT_TELEPHONY_TX)))) {
739             return true;
740         }
741     }
742     return false;
743 }
744 
isActiveRemotely(VolumeSource volumeSource,uint32_t inPastMs) const745 bool SwAudioOutputCollection::isActiveRemotely(VolumeSource volumeSource, uint32_t inPastMs) const
746 {
747     nsecs_t sysTime = systemTime();
748     for (size_t i = 0; i < size(); i++) {
749         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
750         if (outputDesc->devices().containsDeviceAmongTypes(getAllOutRemoteDevices()) &&
751                 outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
752             // do not consider re routing (when the output is going to a dynamic policy)
753             // as "remote playback"
754             if (outputDesc->mPolicyMix == NULL) {
755                 return true;
756             }
757         }
758     }
759     return false;
760 }
761 
isStrategyActiveOnSameModule(product_strategy_t ps,const sp<SwAudioOutputDescriptor> & desc,uint32_t inPastMs,nsecs_t sysTime) const762 bool SwAudioOutputCollection::isStrategyActiveOnSameModule(product_strategy_t ps,
763                                                            const sp<SwAudioOutputDescriptor>& desc,
764                                                            uint32_t inPastMs, nsecs_t sysTime) const
765 {
766     for (size_t i = 0; i < size(); i++) {
767         const sp<SwAudioOutputDescriptor> otherDesc = valueAt(i);
768         if (desc->sharesHwModuleWith(otherDesc) &&
769                 otherDesc->isStrategyActive(ps, inPastMs, sysTime)) {
770             if (desc == otherDesc
771                     || !otherDesc->devices()
772                             .onlyContainsDevicesWithType(AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
773                 return true;
774             }
775         }
776     }
777     return false;
778 }
779 
getA2dpOutput() const780 audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
781 {
782     for (size_t i = 0; i < size(); i++) {
783         sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
784         if (!outputDesc->isDuplicated() &&
785              outputDesc->devices().containsDeviceAmongTypes(getAudioDeviceOutAllA2dpSet()) &&
786              outputDesc->devicesSupportEncodedFormats(getAudioDeviceOutAllA2dpSet())) {
787             return this->keyAt(i);
788         }
789     }
790     return 0;
791 }
792 
isA2dpOffloadedOnPrimary() const793 bool SwAudioOutputCollection::isA2dpOffloadedOnPrimary() const
794 {
795     sp<SwAudioOutputDescriptor> primaryOutput = getPrimaryOutput();
796 
797     if ((primaryOutput != NULL) && (primaryOutput->mProfile != NULL)
798         && (primaryOutput->mProfile->getModule() != NULL)) {
799         sp<HwModule> primaryHwModule = primaryOutput->mProfile->getModule();
800 
801         for (const auto &outputProfile : primaryHwModule->getOutputProfiles()) {
802             if (outputProfile->supportsDeviceTypes(getAudioDeviceOutAllA2dpSet())) {
803                 return true;
804             }
805         }
806     }
807     return false;
808 }
809 
getPrimaryOutput() const810 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
811 {
812     for (size_t i = 0; i < size(); i++) {
813         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
814         if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
815             return outputDesc;
816         }
817     }
818     return NULL;
819 }
820 
getOutputFromId(audio_port_handle_t id) const821 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
822 {
823     for (size_t i = 0; i < size(); i++) {
824         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
825         if (outputDesc->getId() == id) {
826             return outputDesc;
827         }
828     }
829     return NULL;
830 }
831 
getOutputForClient(audio_port_handle_t portId)832 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputForClient(audio_port_handle_t portId)
833 {
834     for (size_t i = 0; i < size(); i++) {
835         sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
836         if (outputDesc->getClient(portId) != nullptr) {
837             return outputDesc;
838         }
839     }
840     return 0;
841 }
842 
clearSessionRoutesForDevice(const sp<DeviceDescriptor> & disconnectedDevice)843 void SwAudioOutputCollection::clearSessionRoutesForDevice(
844         const sp<DeviceDescriptor> &disconnectedDevice)
845 {
846     for (size_t i = 0; i < size(); i++) {
847         sp<AudioOutputDescriptor> outputDesc = valueAt(i);
848         for (const auto& client : outputDesc->getClientIterable()) {
849             if (client->preferredDeviceId() == disconnectedDevice->getId()) {
850                 client->setPreferredDeviceId(AUDIO_PORT_HANDLE_NONE);
851             }
852         }
853     }
854 }
855 
dump(String8 * dst) const856 void SwAudioOutputCollection::dump(String8 *dst) const
857 {
858     dst->append("\nOutputs dump:\n");
859     for (size_t i = 0; i < size(); i++) {
860         dst->appendFormat("- Output %d dump:\n", keyAt(i));
861         valueAt(i)->dump(dst);
862     }
863 }
864 
865 // HwAudioOutputCollection implementation
isActive(VolumeSource volumeSource,uint32_t inPastMs) const866 bool HwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const
867 {
868     nsecs_t sysTime = systemTime();
869     for (size_t i = 0; i < this->size(); i++) {
870         const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i);
871         if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
872             return true;
873         }
874     }
875     return false;
876 }
877 
dump(String8 * dst) const878 void HwAudioOutputCollection::dump(String8 *dst) const
879 {
880     dst->append("\nOutputs dump:\n");
881     for (size_t i = 0; i < size(); i++) {
882         dst->appendFormat("- Output %d dump:\n", keyAt(i));
883         valueAt(i)->dump(dst);
884     }
885 }
886 
887 }; //namespace android
888