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 
isActive(VolumeSource vs,uint32_t inPastMs,nsecs_t sysTime) const126 bool AudioOutputDescriptor::isActive(VolumeSource vs, uint32_t inPastMs, nsecs_t sysTime) const
127 {
128     return (vs == VOLUME_SOURCE_NONE) ?
129                 isActive(inPastMs) : (mVolumeActivities.find(vs) != std::end(mVolumeActivities)?
130                 mVolumeActivities.at(vs).isActive(inPastMs, sysTime) : false);
131 }
132 
isActive(uint32_t inPastMs) const133 bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
134 {
135     nsecs_t sysTime = 0;
136     if (inPastMs != 0) {
137         sysTime = systemTime();
138     }
139     for (const auto &iter : mVolumeActivities) {
140         if (iter.second.isActive(inPastMs, sysTime)) {
141             return true;
142         }
143     }
144     return false;
145 }
146 
isFixedVolume(const DeviceTypeSet & deviceTypes __unused)147 bool AudioOutputDescriptor::isFixedVolume(const DeviceTypeSet& deviceTypes __unused)
148 {
149     return false;
150 }
151 
setVolume(float volumeDb,VolumeSource volumeSource,const StreamTypeVector &,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force)152 bool AudioOutputDescriptor::setVolume(float volumeDb,
153                                       VolumeSource volumeSource,
154                                       const StreamTypeVector &/*streams*/,
155                                       const DeviceTypeSet& deviceTypes,
156                                       uint32_t delayMs,
157                                       bool force)
158 {
159 
160     if (!supportedDevices().containsDeviceAmongTypes(deviceTypes)) {
161         ALOGV("%s output ID %d unsupported device %s",
162                 __func__, getId(), toString(deviceTypes).c_str());
163         return false;
164     }
165     // We actually change the volume if:
166     // - the float value returned by computeVolume() changed
167     // - the force flag is set
168     if (volumeDb != getCurVolume(volumeSource) || force) {
169         ALOGV("%s for volumeSrc %d, volume %f, delay %d", __func__, volumeSource, volumeDb, delayMs);
170         setCurVolume(volumeSource, volumeDb);
171         return true;
172     }
173     return false;
174 }
175 
applyAudioPortConfig(const struct audio_port_config * config,audio_port_config * backupConfig)176 status_t AudioOutputDescriptor::applyAudioPortConfig(const struct audio_port_config *config,
177                                                      audio_port_config *backupConfig)
178 {
179     struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
180     status_t status = NO_ERROR;
181 
182     toAudioPortConfig(&localBackupConfig);
183     if ((status = validationBeforeApplyConfig(config)) == NO_ERROR) {
184         AudioPortConfig::applyAudioPortConfig(config, backupConfig);
185         applyPolicyAudioPortConfig(config);
186     }
187 
188     if (backupConfig != NULL) {
189         *backupConfig = localBackupConfig;
190     }
191     return status;
192 }
193 
194 
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const195 void AudioOutputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
196                                               const struct audio_port_config *srcConfig) const
197 {
198     dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
199                             AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
200     if (srcConfig != NULL) {
201         dstConfig->config_mask |= srcConfig->config_mask;
202     }
203     AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
204     toPolicyAudioPortConfig(dstConfig, srcConfig);
205 
206     dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
207     dstConfig->type = AUDIO_PORT_TYPE_MIX;
208     dstConfig->ext.mix.hw_module = getModuleHandle();
209     dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
210 }
211 
toAudioPort(struct audio_port * port) const212 void AudioOutputDescriptor::toAudioPort(struct audio_port *port) const
213 {
214     // Should not be called for duplicated ports, see SwAudioOutputDescriptor::toAudioPortConfig.
215     mPolicyAudioPort->asAudioPort()->toAudioPort(port);
216     port->id = mId;
217     port->ext.mix.hw_module = getModuleHandle();
218 }
219 
clientsList(bool activeOnly,product_strategy_t strategy,bool preferredDeviceOnly) const220 TrackClientVector AudioOutputDescriptor::clientsList(bool activeOnly, product_strategy_t strategy,
221                                                      bool preferredDeviceOnly) const
222 {
223     TrackClientVector clients;
224     for (const auto &client : getClientIterable()) {
225         if ((!activeOnly || client->active())
226             && (strategy == PRODUCT_STRATEGY_NONE || strategy == client->strategy())
227             && (!preferredDeviceOnly ||
228                 (client->hasPreferredDevice() && !client->isPreferredDeviceForExclusiveUse()))) {
229             clients.push_back(client);
230         }
231     }
232     return clients;
233 }
234 
isAnyActive(VolumeSource volumeSourceToIgnore) const235 bool AudioOutputDescriptor::isAnyActive(VolumeSource volumeSourceToIgnore) const
236 {
237     return std::find_if(begin(mActiveClients), end(mActiveClients),
238                         [&volumeSourceToIgnore](const auto &client) {
239         return client->volumeSource() != volumeSourceToIgnore; }) != end(mActiveClients);
240 }
241 
dump(String8 * dst) const242 void AudioOutputDescriptor::dump(String8 *dst) const
243 {
244     dst->appendFormat(" ID: %d\n", mId);
245     dst->appendFormat(" Sampling rate: %d\n", mSamplingRate);
246     dst->appendFormat(" Format: %08x\n", mFormat);
247     dst->appendFormat(" Channels: %08x\n", mChannelMask);
248     dst->appendFormat(" Devices: %s\n", devices().toString().c_str());
249     dst->appendFormat(" Global active count: %u\n", mGlobalActiveCount);
250     for (const auto &iter : mRoutingActivities) {
251         dst->appendFormat(" Product Strategy id: %d", iter.first);
252         iter.second.dump(dst, 4);
253     }
254     for (const auto &iter : mVolumeActivities) {
255         dst->appendFormat(" Volume Activities id: %d", iter.first);
256         iter.second.dump(dst, 4);
257     }
258     dst->append(" AudioTrack Clients:\n");
259     ClientMapHandler<TrackClientDescriptor>::dump(dst);
260     dst->append("\n");
261     if (!mActiveClients.empty()) {
262         dst->append(" AudioTrack active (stream) clients:\n");
263         size_t index = 0;
264         for (const auto& client : mActiveClients) {
265             client->dump(dst, 2, index++);
266         }
267         dst->append(" \n");
268     }
269 }
270 
log(const char * indent)271 void AudioOutputDescriptor::log(const char* indent)
272 {
273     ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]",
274           indent, mId, mId, mSamplingRate, mFormat, mChannelMask);
275 }
276 
277 // SwAudioOutputDescriptor implementation
SwAudioOutputDescriptor(const sp<IOProfile> & profile,AudioPolicyClientInterface * clientInterface)278 SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
279                                                  AudioPolicyClientInterface *clientInterface)
280     : AudioOutputDescriptor(profile, clientInterface),
281     mProfile(profile), mIoHandle(AUDIO_IO_HANDLE_NONE), mLatency(0),
282     mFlags((audio_output_flags_t)0),
283     mOutput1(0), mOutput2(0), mDirectOpenCount(0),
284     mDirectClientSession(AUDIO_SESSION_NONE)
285 {
286     if (profile != NULL) {
287         mFlags = (audio_output_flags_t)profile->getFlags();
288     }
289 }
290 
dump(String8 * dst) const291 void SwAudioOutputDescriptor::dump(String8 *dst) const
292 {
293     dst->appendFormat(" Latency: %d\n", mLatency);
294     dst->appendFormat(" Flags %08x\n", mFlags);
295     AudioOutputDescriptor::dump(dst);
296 }
297 
devices() const298 DeviceVector SwAudioOutputDescriptor::devices() const
299 {
300     if (isDuplicated()) {
301         DeviceVector devices = mOutput1->devices();
302         devices.merge(mOutput2->devices());
303         return devices;
304     }
305     return mDevices;
306 }
307 
sharesHwModuleWith(const sp<SwAudioOutputDescriptor> & outputDesc)308 bool SwAudioOutputDescriptor::sharesHwModuleWith(
309         const sp<SwAudioOutputDescriptor>& outputDesc)
310 {
311     if (isDuplicated()) {
312         return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
313     } else if (outputDesc->isDuplicated()){
314         return sharesHwModuleWith(outputDesc->subOutput1()) ||
315                     sharesHwModuleWith(outputDesc->subOutput2());
316     } else {
317         return AudioOutputDescriptor::sharesHwModuleWith(outputDesc);
318     }
319 }
320 
supportedDevices() const321 DeviceVector SwAudioOutputDescriptor::supportedDevices() const
322 {
323     if (isDuplicated()) {
324         DeviceVector supportedDevices = mOutput1->supportedDevices();
325         supportedDevices.merge(mOutput2->supportedDevices());
326         return supportedDevices;
327     }
328     return mProfile->getSupportedDevices();
329 }
330 
supportsDevice(const sp<DeviceDescriptor> & device) const331 bool SwAudioOutputDescriptor::supportsDevice(const sp<DeviceDescriptor> &device) const
332 {
333     return supportedDevices().contains(device);
334 }
335 
supportsAllDevices(const DeviceVector & devices) const336 bool SwAudioOutputDescriptor::supportsAllDevices(const DeviceVector &devices) const
337 {
338     return supportedDevices().containsAllDevices(devices);
339 }
340 
filterSupportedDevices(const DeviceVector & devices) const341 DeviceVector SwAudioOutputDescriptor::filterSupportedDevices(const DeviceVector &devices) const
342 {
343     DeviceVector filteredDevices = supportedDevices();
344     return filteredDevices.filter(devices);
345 }
346 
devicesSupportEncodedFormats(const DeviceTypeSet & deviceTypes)347 bool SwAudioOutputDescriptor::devicesSupportEncodedFormats(const DeviceTypeSet& deviceTypes)
348 {
349     if (isDuplicated()) {
350         return (mOutput1->devicesSupportEncodedFormats(deviceTypes)
351                     || mOutput2->devicesSupportEncodedFormats(deviceTypes));
352     } else {
353        return mProfile->devicesSupportEncodedFormats(deviceTypes);
354     }
355 }
356 
latency()357 uint32_t SwAudioOutputDescriptor::latency()
358 {
359     if (isDuplicated()) {
360         return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
361     } else {
362         return mLatency;
363     }
364 }
365 
setClientActive(const sp<TrackClientDescriptor> & client,bool active)366 void SwAudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active)
367 {
368     // forward usage count change to attached outputs
369     if (isDuplicated()) {
370         mOutput1->setClientActive(client, active);
371         mOutput2->setClientActive(client, active);
372     }
373     AudioOutputDescriptor::setClientActive(client, active);
374 }
375 
isFixedVolume(const DeviceTypeSet & deviceTypes)376 bool SwAudioOutputDescriptor::isFixedVolume(const DeviceTypeSet& deviceTypes)
377 {
378     // unit gain if rerouting to external policy
379     if (isSingleDeviceType(deviceTypes, AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) {
380         if (mPolicyMix != NULL) {
381             ALOGV("max gain when rerouting for output=%d", mIoHandle);
382             return true;
383         }
384     }
385     if (isSingleDeviceType(deviceTypes, AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
386         ALOGV("max gain when output device is telephony tx");
387         return true;
388     }
389     return false;
390 }
391 
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const392 void SwAudioOutputDescriptor::toAudioPortConfig(
393                                                  struct audio_port_config *dstConfig,
394                                                  const struct audio_port_config *srcConfig) const
395 {
396 
397     ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
398     AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig);
399 
400     dstConfig->ext.mix.handle = mIoHandle;
401 }
402 
toAudioPort(struct audio_port * port) const403 void SwAudioOutputDescriptor::toAudioPort(
404                                                     struct audio_port *port) const
405 {
406     ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
407 
408     AudioOutputDescriptor::toAudioPort(port);
409 
410     toAudioPortConfig(&port->active_config);
411     port->ext.mix.handle = mIoHandle;
412     port->ext.mix.latency_class =
413             mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
414 }
415 
setVolume(float volumeDb,VolumeSource vs,const StreamTypeVector & streamTypes,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force)416 bool SwAudioOutputDescriptor::setVolume(float volumeDb,
417                                         VolumeSource vs, const StreamTypeVector &streamTypes,
418                                         const DeviceTypeSet& deviceTypes,
419                                         uint32_t delayMs,
420                                         bool force)
421 {
422     StreamTypeVector streams = streamTypes;
423     if (!AudioOutputDescriptor::setVolume(volumeDb, vs, streamTypes, deviceTypes, delayMs, force)) {
424         return false;
425     }
426     if (streams.empty()) {
427         streams.push_back(AUDIO_STREAM_MUSIC);
428     }
429     for (const auto& devicePort : devices()) {
430         // APM loops on all group, so filter on active group to set the port gain,
431         // let the other groups set the stream volume as per legacy
432         // TODO: Pass in the device address and check against it.
433         if (isSingleDeviceType(deviceTypes, devicePort->type()) &&
434                 devicePort->hasGainController(true) && isActive(vs)) {
435             ALOGV("%s: device %s has gain controller", __func__, devicePort->toString().c_str());
436             // @todo: here we might be in trouble if the SwOutput has several active clients with
437             // different Volume Source (or if we allow several curves within same volume group)
438             //
439             // @todo: default stream volume to max (0) when using HW Port gain?
440             float volumeAmpl = Volume::DbToAmpl(0);
441             for (const auto &stream : streams) {
442                 mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
443             }
444 
445             AudioGains gains = devicePort->getGains();
446             int gainMinValueInMb = gains[0]->getMinValueInMb();
447             int gainMaxValueInMb = gains[0]->getMaxValueInMb();
448             int gainStepValueInMb = gains[0]->getStepValueInMb();
449             int gainValueMb = ((volumeDb * 100)/ gainStepValueInMb) * gainStepValueInMb;
450             gainValueMb = std::max(gainMinValueInMb, std::min(gainValueMb, gainMaxValueInMb));
451 
452             audio_port_config config = {};
453             devicePort->toAudioPortConfig(&config);
454             config.config_mask = AUDIO_PORT_CONFIG_GAIN;
455             config.gain.values[0] = gainValueMb;
456             return mClientInterface->setAudioPortConfig(&config, 0) == NO_ERROR;
457         }
458     }
459     // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is enabled
460     float volumeAmpl = Volume::DbToAmpl(getCurVolume(vs));
461     if (hasStream(streams, AUDIO_STREAM_BLUETOOTH_SCO)) {
462         mClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volumeAmpl, mIoHandle, delayMs);
463     }
464     for (const auto &stream : streams) {
465         ALOGV("%s output %d for volumeSource %d, volume %f, delay %d stream=%s", __func__,
466               mIoHandle, vs, volumeDb, delayMs, toString(stream).c_str());
467         mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
468     }
469     return true;
470 }
471 
open(const audio_config_t * config,const DeviceVector & devices,audio_stream_type_t stream,audio_output_flags_t flags,audio_io_handle_t * output)472 status_t SwAudioOutputDescriptor::open(const audio_config_t *config,
473                                        const DeviceVector &devices,
474                                        audio_stream_type_t stream,
475                                        audio_output_flags_t flags,
476                                        audio_io_handle_t *output)
477 {
478     mDevices = devices;
479     sp<DeviceDescriptor> device = devices.getDeviceForOpening();
480     LOG_ALWAYS_FATAL_IF(device == nullptr,
481                         "%s failed to get device descriptor for opening "
482                         "with the requested devices, all device types: %s",
483                         __func__, dumpDeviceTypes(devices.types()).c_str());
484 
485     audio_config_t lConfig;
486     if (config == nullptr) {
487         lConfig = AUDIO_CONFIG_INITIALIZER;
488         lConfig.sample_rate = mSamplingRate;
489         lConfig.channel_mask = mChannelMask;
490         lConfig.format = mFormat;
491     } else {
492         lConfig = *config;
493     }
494 
495     // if the selected profile is offloaded and no offload info was specified,
496     // create a default one
497     if ((mProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
498             lConfig.offload_info.format == AUDIO_FORMAT_DEFAULT) {
499         flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
500         lConfig.offload_info = AUDIO_INFO_INITIALIZER;
501         lConfig.offload_info.sample_rate = lConfig.sample_rate;
502         lConfig.offload_info.channel_mask = lConfig.channel_mask;
503         lConfig.offload_info.format = lConfig.format;
504         lConfig.offload_info.stream_type = stream;
505         lConfig.offload_info.duration_us = -1;
506         lConfig.offload_info.has_video = true; // conservative
507         lConfig.offload_info.is_streaming = true; // likely
508     }
509 
510     mFlags = (audio_output_flags_t)(mFlags | flags);
511 
512     ALOGV("opening output for device %s profile %p name %s",
513           mDevices.toString().c_str(), mProfile.get(), mProfile->getName().c_str());
514 
515     status_t status = mClientInterface->openOutput(mProfile->getModuleHandle(),
516                                                    output,
517                                                    &lConfig,
518                                                    device,
519                                                    &mLatency,
520                                                    mFlags);
521 
522     if (status == NO_ERROR) {
523         LOG_ALWAYS_FATAL_IF(*output == AUDIO_IO_HANDLE_NONE,
524                             "%s openOutput returned output handle %d for device %s, "
525                             "selected device %s for opening",
526                             __FUNCTION__, *output, devices.toString().c_str(),
527                             device->toString().c_str());
528         mSamplingRate = lConfig.sample_rate;
529         mChannelMask = lConfig.channel_mask;
530         mFormat = lConfig.format;
531         mId = PolicyAudioPort::getNextUniqueId();
532         mIoHandle = *output;
533         mProfile->curOpenCount++;
534     }
535 
536     return status;
537 }
538 
start()539 status_t SwAudioOutputDescriptor::start()
540 {
541     if (isDuplicated()) {
542         status_t status = mOutput1->start();
543         if (status != NO_ERROR) {
544             return status;
545         }
546         status = mOutput2->start();
547         if (status != NO_ERROR) {
548             mOutput1->stop();
549             return status;
550         }
551         return NO_ERROR;
552     }
553     if (!isActive()) {
554         if (!mProfile->canStartNewIo()) {
555             return INVALID_OPERATION;
556         }
557         mProfile->curActiveCount++;
558     }
559     return NO_ERROR;
560 }
561 
stop()562 void SwAudioOutputDescriptor::stop()
563 {
564     if (isDuplicated()) {
565         mOutput1->stop();
566         mOutput2->stop();
567         return;
568     }
569 
570     if (!isActive()) {
571         LOG_ALWAYS_FATAL_IF(mProfile->curActiveCount < 1,
572                             "%s invalid profile active count %u",
573                             __func__, mProfile->curActiveCount);
574         mProfile->curActiveCount--;
575     }
576 }
577 
close()578 void SwAudioOutputDescriptor::close()
579 {
580     if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
581         // clean up active clients if any (can happen if close() is called to force
582         // clients to reconnect
583         for (const auto &client : getClientIterable()) {
584             if (client->active()) {
585                 ALOGW("%s client with port ID %d still active on output %d",
586                       __func__, client->portId(), mId);
587                 setClientActive(client, false);
588                 stop();
589             }
590         }
591 
592         AudioParameter param;
593         param.add(String8("closing"), String8("true"));
594         mClientInterface->setParameters(mIoHandle, param.toString());
595 
596         mClientInterface->closeOutput(mIoHandle);
597 
598         LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
599                             __FUNCTION__, mProfile->curOpenCount);
600         mProfile->curOpenCount--;
601         mIoHandle = AUDIO_IO_HANDLE_NONE;
602     }
603 }
604 
openDuplicating(const sp<SwAudioOutputDescriptor> & output1,const sp<SwAudioOutputDescriptor> & output2,audio_io_handle_t * ioHandle)605 status_t SwAudioOutputDescriptor::openDuplicating(const sp<SwAudioOutputDescriptor>& output1,
606                                                   const sp<SwAudioOutputDescriptor>& output2,
607                                                   audio_io_handle_t *ioHandle)
608 {
609     // open a duplicating output thread for the new output and the primary output
610     // Note: openDuplicateOutput() API expects the output handles in the reverse order from the
611     // numbering in SwAudioOutputDescriptor mOutput1 and mOutput2
612     *ioHandle = mClientInterface->openDuplicateOutput(output2->mIoHandle, output1->mIoHandle);
613     if (*ioHandle == AUDIO_IO_HANDLE_NONE) {
614         return INVALID_OPERATION;
615     }
616 
617     mId = PolicyAudioPort::getNextUniqueId();
618     mIoHandle = *ioHandle;
619     mOutput1 = output1;
620     mOutput2 = output2;
621     mSamplingRate = output2->mSamplingRate;
622     mFormat = output2->mFormat;
623     mChannelMask = output2->mChannelMask;
624     mLatency = output2->mLatency;
625 
626     return NO_ERROR;
627 }
628 
629 // HwAudioOutputDescriptor implementation
HwAudioOutputDescriptor(const sp<SourceClientDescriptor> & source,AudioPolicyClientInterface * clientInterface)630 HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<SourceClientDescriptor>& source,
631                                                  AudioPolicyClientInterface *clientInterface)
632     : AudioOutputDescriptor(source->srcDevice(), clientInterface),
633       mSource(source)
634 {
635 }
636 
dump(String8 * dst) const637 void HwAudioOutputDescriptor::dump(String8 *dst) const
638 {
639     AudioOutputDescriptor::dump(dst);
640     dst->append("Source:\n");
641     mSource->dump(dst, 0, 0);
642 }
643 
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const644 void HwAudioOutputDescriptor::toAudioPortConfig(
645                                                  struct audio_port_config *dstConfig,
646                                                  const struct audio_port_config *srcConfig) const
647 {
648     mSource->srcDevice()->toAudioPortConfig(dstConfig, srcConfig);
649 }
650 
toAudioPort(struct audio_port * port) const651 void HwAudioOutputDescriptor::toAudioPort(
652                                                     struct audio_port *port) const
653 {
654     mSource->srcDevice()->toAudioPort(port);
655 }
656 
657 
setVolume(float volumeDb,VolumeSource volumeSource,const StreamTypeVector & streams,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force)658 bool HwAudioOutputDescriptor::setVolume(float volumeDb,
659                                         VolumeSource volumeSource, const StreamTypeVector &streams,
660                                         const DeviceTypeSet& deviceTypes,
661                                         uint32_t delayMs,
662                                         bool force)
663 {
664     bool changed = AudioOutputDescriptor::setVolume(
665             volumeDb, volumeSource, streams, deviceTypes, delayMs, force);
666 
667     if (changed) {
668       // TODO: use gain controller on source device if any to adjust volume
669     }
670     return changed;
671 }
672 
673 // SwAudioOutputCollection implementation
isActive(VolumeSource volumeSource,uint32_t inPastMs) const674 bool SwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const
675 {
676     nsecs_t sysTime = systemTime();
677     for (size_t i = 0; i < this->size(); i++) {
678         const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
679         if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
680             return true;
681         }
682     }
683     return false;
684 }
685 
isActiveLocally(VolumeSource volumeSource,uint32_t inPastMs) const686 bool SwAudioOutputCollection::isActiveLocally(VolumeSource volumeSource, uint32_t inPastMs) const
687 {
688     nsecs_t sysTime = systemTime();
689     for (size_t i = 0; i < this->size(); i++) {
690         const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
691         if (outputDesc->isActive(volumeSource, inPastMs, sysTime)
692                 && (!(outputDesc->devices()
693                         .containsDeviceAmongTypes(getAllOutRemoteDevices())
694                         || outputDesc->devices()
695                             .onlyContainsDevicesWithType(AUDIO_DEVICE_OUT_TELEPHONY_TX)))) {
696             return true;
697         }
698     }
699     return false;
700 }
701 
isActiveRemotely(VolumeSource volumeSource,uint32_t inPastMs) const702 bool SwAudioOutputCollection::isActiveRemotely(VolumeSource volumeSource, uint32_t inPastMs) const
703 {
704     nsecs_t sysTime = systemTime();
705     for (size_t i = 0; i < size(); i++) {
706         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
707         if (outputDesc->devices().containsDeviceAmongTypes(getAllOutRemoteDevices()) &&
708                 outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
709             // do not consider re routing (when the output is going to a dynamic policy)
710             // as "remote playback"
711             if (outputDesc->mPolicyMix == NULL) {
712                 return true;
713             }
714         }
715     }
716     return false;
717 }
718 
isStrategyActiveOnSameModule(product_strategy_t ps,const sp<SwAudioOutputDescriptor> & desc,uint32_t inPastMs,nsecs_t sysTime) const719 bool SwAudioOutputCollection::isStrategyActiveOnSameModule(product_strategy_t ps,
720                                                            const sp<SwAudioOutputDescriptor>& desc,
721                                                            uint32_t inPastMs, nsecs_t sysTime) const
722 {
723     for (size_t i = 0; i < size(); i++) {
724         const sp<SwAudioOutputDescriptor> otherDesc = valueAt(i);
725         if (desc->sharesHwModuleWith(otherDesc) &&
726                 otherDesc->isStrategyActive(ps, inPastMs, sysTime)) {
727             if (desc == otherDesc
728                     || !otherDesc->devices()
729                             .onlyContainsDevicesWithType(AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
730                 return true;
731             }
732         }
733     }
734     return false;
735 }
736 
getA2dpOutput() const737 audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
738 {
739     for (size_t i = 0; i < size(); i++) {
740         sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
741         if (!outputDesc->isDuplicated() &&
742              outputDesc->devices().containsDeviceAmongTypes(getAudioDeviceOutAllA2dpSet()) &&
743              outputDesc->devicesSupportEncodedFormats(getAudioDeviceOutAllA2dpSet())) {
744             return this->keyAt(i);
745         }
746     }
747     return 0;
748 }
749 
isA2dpOffloadedOnPrimary() const750 bool SwAudioOutputCollection::isA2dpOffloadedOnPrimary() const
751 {
752     sp<SwAudioOutputDescriptor> primaryOutput = getPrimaryOutput();
753 
754     if ((primaryOutput != NULL) && (primaryOutput->mProfile != NULL)
755         && (primaryOutput->mProfile->getModule() != NULL)) {
756         sp<HwModule> primaryHwModule = primaryOutput->mProfile->getModule();
757 
758         for (const auto &outputProfile : primaryHwModule->getOutputProfiles()) {
759             if (outputProfile->supportsDeviceTypes(getAudioDeviceOutAllA2dpSet())) {
760                 return true;
761             }
762         }
763     }
764     return false;
765 }
766 
isA2dpSupported() const767 bool SwAudioOutputCollection::isA2dpSupported() const
768 {
769     return (isA2dpOffloadedOnPrimary() || (getA2dpOutput() != 0));
770 }
771 
getPrimaryOutput() const772 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
773 {
774     for (size_t i = 0; i < size(); i++) {
775         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
776         if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
777             return outputDesc;
778         }
779     }
780     return NULL;
781 }
782 
getOutputFromId(audio_port_handle_t id) const783 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
784 {
785     for (size_t i = 0; i < size(); i++) {
786         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
787         if (outputDesc->getId() == id) {
788             return outputDesc;
789         }
790     }
791     return NULL;
792 }
793 
getOutputForClient(audio_port_handle_t portId)794 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputForClient(audio_port_handle_t portId)
795 {
796     for (size_t i = 0; i < size(); i++) {
797         sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
798         if (outputDesc->getClient(portId) != nullptr) {
799             return outputDesc;
800         }
801     }
802     return 0;
803 }
804 
clearSessionRoutesForDevice(const sp<DeviceDescriptor> & disconnectedDevice)805 void SwAudioOutputCollection::clearSessionRoutesForDevice(
806         const sp<DeviceDescriptor> &disconnectedDevice)
807 {
808     for (size_t i = 0; i < size(); i++) {
809         sp<AudioOutputDescriptor> outputDesc = valueAt(i);
810         for (const auto& client : outputDesc->getClientIterable()) {
811             if (client->preferredDeviceId() == disconnectedDevice->getId()) {
812                 client->setPreferredDeviceId(AUDIO_PORT_HANDLE_NONE);
813             }
814         }
815     }
816 }
817 
dump(String8 * dst) const818 void SwAudioOutputCollection::dump(String8 *dst) const
819 {
820     dst->append("\nOutputs dump:\n");
821     for (size_t i = 0; i < size(); i++) {
822         dst->appendFormat("- Output %d dump:\n", keyAt(i));
823         valueAt(i)->dump(dst);
824     }
825 }
826 
827 // HwAudioOutputCollection implementation
isActive(VolumeSource volumeSource,uint32_t inPastMs) const828 bool HwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const
829 {
830     nsecs_t sysTime = systemTime();
831     for (size_t i = 0; i < this->size(); i++) {
832         const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i);
833         if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
834             return true;
835         }
836     }
837     return false;
838 }
839 
dump(String8 * dst) const840 void HwAudioOutputCollection::dump(String8 *dst) const
841 {
842     dst->append("\nOutputs dump:\n");
843     for (size_t i = 0; i < size(); i++) {
844         dst->appendFormat("- Output %d dump:\n", keyAt(i));
845         valueAt(i)->dump(dst);
846     }
847 }
848 
849 }; //namespace android
850