• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <android-base/stringprintf.h>
21 
22 #include <AudioPolicyInterface.h>
23 #include "AudioOutputDescriptor.h"
24 #include "AudioPolicyMix.h"
25 #include "IOProfile.h"
26 #include "Volume.h"
27 #include "HwModule.h"
28 #include "TypeConverter.h"
29 #include <media/AudioGain.h>
30 #include <media/AudioParameter.h>
31 #include <media/AudioPolicy.h>
32 
33 // A device mask for all audio output devices that are considered "remote" when evaluating
34 // active output devices in isStreamActiveRemotely()
35 
36 namespace android {
37 
getAllOutRemoteDevices()38 static const DeviceTypeSet& getAllOutRemoteDevices() {
39     static const DeviceTypeSet allOutRemoteDevices = {AUDIO_DEVICE_OUT_REMOTE_SUBMIX};
40     return allOutRemoteDevices;
41 }
42 
AudioOutputDescriptor(const sp<PolicyAudioPort> & policyAudioPort,AudioPolicyClientInterface * clientInterface)43 AudioOutputDescriptor::AudioOutputDescriptor(const sp<PolicyAudioPort>& policyAudioPort,
44                                              AudioPolicyClientInterface *clientInterface)
45     : mPolicyAudioPort(policyAudioPort), mClientInterface(clientInterface)
46 {
47     if (mPolicyAudioPort.get() != nullptr) {
48         mPolicyAudioPort->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
49         if (mPolicyAudioPort->asAudioPort()->getGains().size() > 0) {
50             mPolicyAudioPort->asAudioPort()->getGains()[0]->getDefaultConfig(&mGain);
51         }
52     }
53 }
54 
getConfig() const55 audio_config_base_t AudioOutputDescriptor::getConfig() const
56 {
57     const audio_config_base_t config = { .sample_rate = mSamplingRate, .channel_mask = mChannelMask,
58             .format = mFormat };
59     return config;
60 }
61 
getModuleHandle() const62 audio_module_handle_t AudioOutputDescriptor::getModuleHandle() const
63 {
64     return mPolicyAudioPort.get() != nullptr ?
65             mPolicyAudioPort->getModuleHandle() : AUDIO_MODULE_HANDLE_NONE;
66 }
67 
getPatchHandle() const68 audio_patch_handle_t AudioOutputDescriptor::getPatchHandle() const
69 {
70     return mPatchHandle;
71 }
72 
setPatchHandle(audio_patch_handle_t handle)73 void AudioOutputDescriptor::setPatchHandle(audio_patch_handle_t handle)
74 {
75     mPatchHandle = handle;
76 }
77 
sharesHwModuleWith(const sp<AudioOutputDescriptor> & outputDesc)78 bool AudioOutputDescriptor::sharesHwModuleWith(
79         const sp<AudioOutputDescriptor>& outputDesc)
80 {
81     return hasSameHwModuleAs(outputDesc);
82 }
83 
setStopTime(const sp<TrackClientDescriptor> & client,nsecs_t sysTime)84 void AudioOutputDescriptor::setStopTime(const sp<TrackClientDescriptor>& client, nsecs_t sysTime)
85 {
86     mVolumeActivities[client->volumeSource()].setStopTime(sysTime);
87     mRoutingActivities[client->strategy()].setStopTime(sysTime);
88 }
89 
setClientActive(const sp<TrackClientDescriptor> & client,bool active)90 void AudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active)
91 {
92     auto clientIter = std::find(begin(mActiveClients), end(mActiveClients), client);
93     if (active == (clientIter != end(mActiveClients))) {
94         ALOGW("%s(%s): ignored active: %d, current stream count %d", __func__,
95               client->toShortString().c_str(), active,
96               mRoutingActivities.at(client->strategy()).getActivityCount());
97         return;
98     }
99     if (active) {
100         mActiveClients.push_back(client);
101     } else {
102         mActiveClients.erase(clientIter);
103     }
104     const int delta = active ? 1 : -1;
105     // If ps is unknown, it is time to track it!
106     mRoutingActivities[client->strategy()].changeActivityCount(delta);
107     mVolumeActivities[client->volumeSource()].changeActivityCount(delta);
108 
109     // Handle non-client-specific activity ref count
110     int32_t oldGlobalActiveCount = mGlobalActiveCount;
111     if (!active && mGlobalActiveCount < 1) {
112         ALOGW("%s(%s): invalid deactivation with globalRefCount %d",
113               __func__, client->toShortString().c_str(), mGlobalActiveCount);
114         mGlobalActiveCount = 1;
115     }
116     mGlobalActiveCount += delta;
117 
118     sp<AudioPolicyMix> policyMix = mPolicyMix.promote();
119     if ((policyMix != NULL) && ((policyMix->mCbFlags & AudioMix::kCbFlagNotifyActivity) != 0)) {
120         if ((oldGlobalActiveCount == 0) || (mGlobalActiveCount == 0)) {
121             mClientInterface->onDynamicPolicyMixStateUpdate(policyMix->mDeviceAddress,
122                 mGlobalActiveCount > 0 ? MIX_STATE_MIXING : MIX_STATE_IDLE);
123         }
124     }
125     client->setActive(active);
126 }
127 
isClientActive(const sp<TrackClientDescriptor> & client)128 bool AudioOutputDescriptor::isClientActive(const sp<TrackClientDescriptor>& client)
129 {
130     return client != nullptr &&
131             std::find(begin(mActiveClients), end(mActiveClients), client) != end(mActiveClients);
132 }
133 
isActive(VolumeSource vs,uint32_t inPastMs,nsecs_t sysTime) const134 bool AudioOutputDescriptor::isActive(VolumeSource vs, uint32_t inPastMs, nsecs_t sysTime) const
135 {
136     return (vs == VOLUME_SOURCE_NONE) ?
137                 isActive(inPastMs) : (mVolumeActivities.find(vs) != std::end(mVolumeActivities)?
138                 mVolumeActivities.at(vs).isActive(inPastMs, sysTime) : false);
139 }
140 
isActive(uint32_t inPastMs) const141 bool AudioOutputDescriptor::isActive(uint32_t inPastMs) const
142 {
143     nsecs_t sysTime = 0;
144     if (inPastMs != 0) {
145         sysTime = systemTime();
146     }
147     for (const auto &iter : mVolumeActivities) {
148         if (iter.second.isActive(inPastMs, sysTime)) {
149             return true;
150         }
151     }
152     return false;
153 }
154 
isFixedVolume(const DeviceTypeSet & deviceTypes __unused)155 bool AudioOutputDescriptor::isFixedVolume(const DeviceTypeSet& deviceTypes __unused)
156 {
157     return false;
158 }
159 
setVolume(float volumeDb,bool,VolumeSource volumeSource,const StreamTypeVector &,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force)160 bool AudioOutputDescriptor::setVolume(float volumeDb, bool /*muted*/,
161                                       VolumeSource volumeSource,
162                                       const StreamTypeVector &/*streams*/,
163                                       const DeviceTypeSet& deviceTypes,
164                                       uint32_t delayMs,
165                                       bool force)
166 {
167 
168     if (!supportedDevices().containsDeviceAmongTypes(deviceTypes)) {
169         ALOGV("%s output ID %d unsupported device %s",
170                 __func__, getId(), toString(deviceTypes).c_str());
171         return false;
172     }
173     // We actually change the volume if:
174     // - the float value returned by computeVolume() changed
175     // - the force flag is set
176     if (volumeDb != getCurVolume(volumeSource) || force) {
177         ALOGV("%s for volumeSrc %d, volume %f, delay %d", __func__, volumeSource, volumeDb, delayMs);
178         setCurVolume(volumeSource, volumeDb);
179         return true;
180     }
181     return false;
182 }
183 
applyAudioPortConfig(const struct audio_port_config * config,audio_port_config * backupConfig)184 status_t AudioOutputDescriptor::applyAudioPortConfig(const struct audio_port_config *config,
185                                                      audio_port_config *backupConfig)
186 {
187     struct audio_port_config localBackupConfig = { .config_mask = config->config_mask };
188     status_t status = NO_ERROR;
189 
190     toAudioPortConfig(&localBackupConfig);
191     if ((status = validationBeforeApplyConfig(config)) == NO_ERROR) {
192         AudioPortConfig::applyAudioPortConfig(config, backupConfig);
193     }
194 
195     if (backupConfig != NULL) {
196         *backupConfig = localBackupConfig;
197     }
198     return status;
199 }
200 
201 
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const202 void AudioOutputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
203                                               const struct audio_port_config *srcConfig) const
204 {
205     dstConfig->config_mask = AUDIO_PORT_CONFIG_ALL;
206     if (srcConfig != NULL) {
207         dstConfig->config_mask |= srcConfig->config_mask;
208     }
209     AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
210 
211     dstConfig->role = AUDIO_PORT_ROLE_SOURCE;
212     dstConfig->type = AUDIO_PORT_TYPE_MIX;
213     dstConfig->ext.mix.hw_module = getModuleHandle();
214     dstConfig->ext.mix.usecase.stream = AUDIO_STREAM_DEFAULT;
215 }
216 
toAudioPort(struct audio_port_v7 * port) const217 void AudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
218 {
219     // Should not be called for duplicated ports, see SwAudioOutputDescriptor::toAudioPortConfig.
220     mPolicyAudioPort->asAudioPort()->toAudioPort(port);
221     port->id = mId;
222     port->ext.mix.hw_module = getModuleHandle();
223 }
224 
clientsList(bool activeOnly,product_strategy_t strategy,bool preferredDeviceOnly) const225 TrackClientVector AudioOutputDescriptor::clientsList(bool activeOnly, product_strategy_t strategy,
226                                                      bool preferredDeviceOnly) const
227 {
228     TrackClientVector clients;
229     for (const auto &client : getClientIterable()) {
230         if ((!activeOnly || client->active())
231             && (strategy == PRODUCT_STRATEGY_NONE || strategy == client->strategy())
232             && (!preferredDeviceOnly ||
233                 (client->hasPreferredDevice() && !client->isPreferredDeviceForExclusiveUse()))) {
234             clients.push_back(client);
235         }
236     }
237     return clients;
238 }
239 
sameExclusivePreferredDevicesCount() const240 size_t AudioOutputDescriptor::sameExclusivePreferredDevicesCount() const
241 {
242     audio_port_handle_t deviceId = AUDIO_PORT_HANDLE_NONE;
243     size_t count = 0;
244     for (const auto &client : getClientIterable()) {
245         if (client->active()) {
246             if (!(client->hasPreferredDevice() &&
247                     client->isPreferredDeviceForExclusiveUse())) {
248                 return 0;
249             }
250             if (deviceId == AUDIO_PORT_HANDLE_NONE) {
251                 deviceId = client->preferredDeviceId();
252             } else if (deviceId != client->preferredDeviceId()) {
253                 return 0;
254             }
255             count++;
256         }
257     }
258     return count;
259 }
260 
isAnyActive(VolumeSource volumeSourceToIgnore) const261 bool AudioOutputDescriptor::isAnyActive(VolumeSource volumeSourceToIgnore) const
262 {
263     return std::find_if(begin(mActiveClients), end(mActiveClients),
264                         [&volumeSourceToIgnore](const auto &client) {
265         return client->volumeSource() != volumeSourceToIgnore; }) != end(mActiveClients);
266 }
267 
dump(String8 * dst,int spaces,const char * extraInfo) const268 void AudioOutputDescriptor::dump(String8 *dst, int spaces, const char* extraInfo) const
269 {
270     dst->appendFormat("Port ID: %d%s%s\n",
271             mId, extraInfo != nullptr ? "; " : "", extraInfo != nullptr ? extraInfo : "");
272     dst->appendFormat("%*s%s; %d; Channel mask: 0x%x\n", spaces, "",
273             audio_format_to_string(mFormat), mSamplingRate, mChannelMask);
274     dst->appendFormat("%*sDevices: %s\n", spaces, "",
275             devices().toString(true /*includeSensitiveInfo*/).c_str());
276     dst->appendFormat("%*sGlobal active count: %u\n", spaces, "", mGlobalActiveCount);
277     if (!mRoutingActivities.empty()) {
278         dst->appendFormat("%*s- Product Strategies (%zu):\n", spaces - 2, "",
279                 mRoutingActivities.size());
280         for (const auto &iter : mRoutingActivities) {
281             dst->appendFormat("%*sid %d: ", spaces + 1, "", iter.first);
282             iter.second.dump(dst, 0);
283         }
284     }
285     if (!mVolumeActivities.empty()) {
286         dst->appendFormat("%*s- Volume Activities (%zu):\n", spaces - 2, "",
287                 mVolumeActivities.size());
288         for (const auto &iter : mVolumeActivities) {
289             dst->appendFormat("%*sid %d: ", spaces + 1, "", iter.first);
290             iter.second.dump(dst, 0);
291         }
292     }
293     if (getClientCount() != 0) {
294         dst->appendFormat("%*s- AudioTrack clients (%zu):\n", spaces - 2, "", getClientCount());
295         ClientMapHandler<TrackClientDescriptor>::dump(dst, spaces);
296     }
297     if (!mActiveClients.empty()) {
298         dst->appendFormat("%*s- AudioTrack active (stream) clients (%zu):\n", spaces - 2, "",
299                 mActiveClients.size());
300         size_t index = 0;
301         for (const auto& client : mActiveClients) {
302             const std::string prefix = base::StringPrintf(
303                     "%*sid %zu: ", spaces + 1, "", index + 1);
304             dst->appendFormat("%s", prefix.c_str());
305             client->dump(dst, prefix.size());
306         }
307     }
308 }
309 
log(const char * indent)310 void AudioOutputDescriptor::log(const char* indent)
311 {
312     ALOGI("%sID: %d,0x%X, [rt:%d fmt:0x%X ch:0x%X]",
313           indent, mId, mId, mSamplingRate, mFormat, mChannelMask);
314 }
315 
316 // SwAudioOutputDescriptor implementation
SwAudioOutputDescriptor(const sp<IOProfile> & profile,AudioPolicyClientInterface * clientInterface)317 SwAudioOutputDescriptor::SwAudioOutputDescriptor(const sp<IOProfile>& profile,
318                                                  AudioPolicyClientInterface *clientInterface)
319     : AudioOutputDescriptor(profile, clientInterface),
320     mProfile(profile), mIoHandle(AUDIO_IO_HANDLE_NONE), mLatency(0),
321     mOutput1(0), mOutput2(0), mDirectOpenCount(0),
322     mDirectClientSession(AUDIO_SESSION_NONE)
323 {
324     if (profile != NULL) {
325         mFlags = (audio_output_flags_t)profile->getFlags();
326     }
327 }
328 
dump(String8 * dst,int spaces,const char * extraInfo) const329 void SwAudioOutputDescriptor::dump(String8 *dst, int spaces, const char* extraInfo) const
330 {
331     String8 allExtraInfo;
332     if (extraInfo != nullptr) {
333         allExtraInfo.appendFormat("%s; ", extraInfo);
334     }
335     std::string flagsLiteral = toString(mFlags);
336     allExtraInfo.appendFormat("Latency: %d; 0x%04x", mLatency, mFlags);
337     if (!flagsLiteral.empty()) {
338         allExtraInfo.appendFormat(" (%s)", flagsLiteral.c_str());
339     }
340     AudioOutputDescriptor::dump(dst, spaces, allExtraInfo.c_str());
341 }
342 
devices() const343 DeviceVector SwAudioOutputDescriptor::devices() const
344 {
345     if (isDuplicated()) {
346         DeviceVector devices = mOutput1->devices();
347         devices.merge(mOutput2->devices());
348         return devices;
349     }
350     return mDevices;
351 }
352 
sharesHwModuleWith(const sp<SwAudioOutputDescriptor> & outputDesc)353 bool SwAudioOutputDescriptor::sharesHwModuleWith(
354         const sp<SwAudioOutputDescriptor>& outputDesc)
355 {
356     if (isDuplicated()) {
357         return mOutput1->sharesHwModuleWith(outputDesc) || mOutput2->sharesHwModuleWith(outputDesc);
358     } else if (outputDesc->isDuplicated()){
359         return sharesHwModuleWith(outputDesc->subOutput1()) ||
360                     sharesHwModuleWith(outputDesc->subOutput2());
361     } else {
362         return AudioOutputDescriptor::sharesHwModuleWith(outputDesc);
363     }
364 }
365 
supportedDevices() const366 DeviceVector SwAudioOutputDescriptor::supportedDevices() const
367 {
368     if (isDuplicated()) {
369         DeviceVector supportedDevices = mOutput1->supportedDevices();
370         supportedDevices.merge(mOutput2->supportedDevices());
371         return supportedDevices;
372     }
373     return mProfile->getSupportedDevices();
374 }
375 
supportsDevice(const sp<DeviceDescriptor> & device) const376 bool SwAudioOutputDescriptor::supportsDevice(const sp<DeviceDescriptor> &device) const
377 {
378     return supportedDevices().contains(device);
379 }
380 
supportsAllDevices(const DeviceVector & devices) const381 bool SwAudioOutputDescriptor::supportsAllDevices(const DeviceVector &devices) const
382 {
383     return supportedDevices().containsAllDevices(devices);
384 }
385 
supportsDevicesForPlayback(const DeviceVector & devices) const386 bool SwAudioOutputDescriptor::supportsDevicesForPlayback(const DeviceVector &devices) const
387 {
388     // No considering duplicated output
389     // TODO: need to verify if the profile supports the devices combo for playback.
390     return !isDuplicated() && supportsAllDevices(devices);
391 }
392 
filterSupportedDevices(const DeviceVector & devices) const393 DeviceVector SwAudioOutputDescriptor::filterSupportedDevices(const DeviceVector &devices) const
394 {
395     DeviceVector filteredDevices = supportedDevices();
396     return filteredDevices.filter(devices);
397 }
398 
devicesSupportEncodedFormats(const DeviceTypeSet & deviceTypes)399 bool SwAudioOutputDescriptor::devicesSupportEncodedFormats(const DeviceTypeSet& deviceTypes)
400 {
401     if (isDuplicated()) {
402         return (mOutput1->devicesSupportEncodedFormats(deviceTypes)
403                     || mOutput2->devicesSupportEncodedFormats(deviceTypes));
404     } else {
405        return mProfile->devicesSupportEncodedFormats(deviceTypes);
406     }
407 }
408 
containsSingleDeviceSupportingEncodedFormats(const sp<DeviceDescriptor> & device) const409 bool SwAudioOutputDescriptor::containsSingleDeviceSupportingEncodedFormats(
410         const sp<DeviceDescriptor>& device) const
411 {
412     if (isDuplicated()) {
413         return (mOutput1->containsSingleDeviceSupportingEncodedFormats(device) &&
414                 mOutput2->containsSingleDeviceSupportingEncodedFormats(device));
415     }
416     return mProfile->containsSingleDeviceSupportingEncodedFormats(device);
417 }
418 
latency()419 uint32_t SwAudioOutputDescriptor::latency()
420 {
421     if (isDuplicated()) {
422         return (mOutput1->mLatency > mOutput2->mLatency) ? mOutput1->mLatency : mOutput2->mLatency;
423     } else {
424         return mLatency;
425     }
426 }
427 
setClientActive(const sp<TrackClientDescriptor> & client,bool active)428 void SwAudioOutputDescriptor::setClientActive(const sp<TrackClientDescriptor>& client, bool active)
429 {
430     // forward usage count change to attached outputs
431     if (isDuplicated()) {
432         mOutput1->setClientActive(client, active);
433         mOutput2->setClientActive(client, active);
434     }
435     AudioOutputDescriptor::setClientActive(client, active);
436 }
437 
isFixedVolume(const DeviceTypeSet & deviceTypes)438 bool SwAudioOutputDescriptor::isFixedVolume(const DeviceTypeSet& deviceTypes)
439 {
440     // unit gain if rerouting to external policy
441     if (isSingleDeviceType(deviceTypes, AUDIO_DEVICE_OUT_REMOTE_SUBMIX)) {
442         if (mPolicyMix != NULL) {
443             ALOGV("max gain when rerouting for output=%d", mIoHandle);
444             return true;
445         }
446     }
447     if (isSingleDeviceType(deviceTypes, AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
448         ALOGV("max gain when output device is telephony tx");
449         return true;
450     }
451     return false;
452 }
453 
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const454 void SwAudioOutputDescriptor::toAudioPortConfig(
455                                                  struct audio_port_config *dstConfig,
456                                                  const struct audio_port_config *srcConfig) const
457 {
458 
459     ALOG_ASSERT(!isDuplicated(), "toAudioPortConfig() called on duplicated output %d", mIoHandle);
460     AudioOutputDescriptor::toAudioPortConfig(dstConfig, srcConfig);
461 
462     dstConfig->ext.mix.handle = mIoHandle;
463 }
464 
toAudioPort(struct audio_port_v7 * port) const465 void SwAudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
466 {
467     ALOG_ASSERT(!isDuplicated(), "toAudioPort() called on duplicated output %d", mIoHandle);
468 
469     AudioOutputDescriptor::toAudioPort(port);
470 
471     toAudioPortConfig(&port->active_config);
472     port->ext.mix.handle = mIoHandle;
473     port->ext.mix.latency_class =
474             mFlags & AUDIO_OUTPUT_FLAG_FAST ? AUDIO_LATENCY_LOW : AUDIO_LATENCY_NORMAL;
475 }
476 
setSwMute(bool muted,VolumeSource vs,const StreamTypeVector & streamTypes,const DeviceTypeSet & deviceTypes,uint32_t delayMs)477 void SwAudioOutputDescriptor::setSwMute(
478         bool muted, VolumeSource vs, const StreamTypeVector &streamTypes,
479         const DeviceTypeSet& deviceTypes, uint32_t delayMs) {
480     // volume source active and more than one volume source is active, otherwise, no-op or let
481     // setVolume controlling SW and/or HW Gains
482     if (!streamTypes.empty() && isActive(vs) && (getActiveVolumeSources().size() > 1)) {
483         for (const auto& devicePort : devices()) {
484             if (isSingleDeviceType(deviceTypes, devicePort->type()) &&
485                     devicePort->hasGainController(true /*canUseForVolume*/)) {
486                 float volumeAmpl = muted ? 0.0f : Volume::DbToAmpl(0);
487                 ALOGV("%s: output: %d, vs: %d, muted: %d, active vs count: %zu", __func__,
488                       mIoHandle, vs, muted, getActiveVolumeSources().size());
489                 for (const auto &stream : streamTypes) {
490                     mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
491                 }
492                 return;
493             }
494         }
495     }
496 }
497 
setVolume(float volumeDb,bool muted,VolumeSource vs,const StreamTypeVector & streamTypes,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force)498 bool SwAudioOutputDescriptor::setVolume(float volumeDb, bool muted,
499                                         VolumeSource vs, const StreamTypeVector &streamTypes,
500                                         const DeviceTypeSet& deviceTypes,
501                                         uint32_t delayMs,
502                                         bool force)
503 {
504     StreamTypeVector streams = streamTypes;
505     if (!AudioOutputDescriptor::setVolume(
506             volumeDb, muted, vs, streamTypes, deviceTypes, delayMs, force)) {
507         return false;
508     }
509     if (streams.empty()) {
510         streams.push_back(AUDIO_STREAM_MUSIC);
511     }
512     for (const auto& devicePort : devices()) {
513         // APM loops on all group, so filter on active group to set the port gain,
514         // let the other groups set the stream volume as per legacy
515         // TODO: Pass in the device address and check against it.
516         if (isSingleDeviceType(deviceTypes, devicePort->type()) &&
517                 devicePort->hasGainController(true) && isActive(vs)) {
518             ALOGV("%s: device %s has gain controller", __func__, devicePort->toString().c_str());
519             // @todo: here we might be in trouble if the SwOutput has several active clients with
520             // different Volume Source (or if we allow several curves within same volume group)
521             //
522             // @todo: default stream volume to max (0) when using HW Port gain?
523             // Allows to set SW Gain on AudioFlinger if:
524             //    -volume group has explicit stream(s) associated
525             //    -volume group with no explicit stream(s) is the only active source on this output
526             // Allows to mute SW Gain on AudioFlinger only for volume group with explicit stream(s)
527             if (!streamTypes.empty() || (getActiveVolumeSources().size() == 1)) {
528                 const bool canMute = muted && (volumeDb != 0.0f) && !streamTypes.empty();
529                 float volumeAmpl = canMute ? 0.0f : Volume::DbToAmpl(0);
530                 for (const auto &stream : streams) {
531                     mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
532                 }
533             }
534             AudioGains gains = devicePort->getGains();
535             int gainMinValueInMb = gains[0]->getMinValueInMb();
536             int gainMaxValueInMb = gains[0]->getMaxValueInMb();
537             int gainStepValueInMb = gains[0]->getStepValueInMb();
538             int gainValueMb = ((volumeDb * 100)/ gainStepValueInMb) * gainStepValueInMb;
539             gainValueMb = std::max(gainMinValueInMb, std::min(gainValueMb, gainMaxValueInMb));
540 
541             audio_port_config config = {};
542             devicePort->toAudioPortConfig(&config);
543             config.config_mask = AUDIO_PORT_CONFIG_GAIN;
544             config.gain.values[0] = gainValueMb;
545             return mClientInterface->setAudioPortConfig(&config, 0) == NO_ERROR;
546         }
547     }
548     // Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is enabled
549     float volumeAmpl = Volume::DbToAmpl(getCurVolume(vs));
550     if (hasStream(streams, AUDIO_STREAM_BLUETOOTH_SCO)) {
551         mClientInterface->setStreamVolume(AUDIO_STREAM_VOICE_CALL, volumeAmpl, mIoHandle, delayMs);
552     }
553     for (const auto &stream : streams) {
554         ALOGV("%s output %d for volumeSource %d, volume %f, delay %d stream=%s", __func__,
555               mIoHandle, vs, volumeDb, delayMs, toString(stream).c_str());
556         mClientInterface->setStreamVolume(stream, volumeAmpl, mIoHandle, delayMs);
557     }
558     return true;
559 }
560 
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)561 status_t SwAudioOutputDescriptor::open(const audio_config_t *halConfig,
562                                        const audio_config_base_t *mixerConfig,
563                                        const DeviceVector &devices,
564                                        audio_stream_type_t stream,
565                                        audio_output_flags_t flags,
566                                        audio_io_handle_t *output)
567 {
568     mDevices = devices;
569     sp<DeviceDescriptor> device = devices.getDeviceForOpening();
570     LOG_ALWAYS_FATAL_IF(device == nullptr,
571                         "%s failed to get device descriptor for opening "
572                         "with the requested devices, all device types: %s",
573                         __func__, dumpDeviceTypes(devices.types()).c_str());
574 
575     audio_config_t lHalConfig;
576     if (halConfig == nullptr) {
577         lHalConfig = AUDIO_CONFIG_INITIALIZER;
578         lHalConfig.sample_rate = mSamplingRate;
579         lHalConfig.channel_mask = mChannelMask;
580         lHalConfig.format = mFormat;
581     } else {
582         lHalConfig = *halConfig;
583     }
584 
585     // if the selected profile is offloaded and no offload info was specified,
586     // create a default one
587     if ((mProfile->getFlags() & AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD) &&
588             lHalConfig.offload_info.format == AUDIO_FORMAT_DEFAULT) {
589         flags = (audio_output_flags_t)(flags | AUDIO_OUTPUT_FLAG_COMPRESS_OFFLOAD);
590         lHalConfig.offload_info = AUDIO_INFO_INITIALIZER;
591         lHalConfig.offload_info.sample_rate = lHalConfig.sample_rate;
592         lHalConfig.offload_info.channel_mask = lHalConfig.channel_mask;
593         lHalConfig.offload_info.format = lHalConfig.format;
594         lHalConfig.offload_info.stream_type = stream;
595     }
596 
597     audio_config_base_t lMixerConfig;
598     if (mixerConfig == nullptr) {
599         lMixerConfig = AUDIO_CONFIG_BASE_INITIALIZER;
600         lMixerConfig.sample_rate = lHalConfig.sample_rate;
601         lMixerConfig.channel_mask = lHalConfig.channel_mask;
602         lMixerConfig.format = lHalConfig.format;
603     } else {
604         lMixerConfig = *mixerConfig;
605     }
606 
607     mFlags = (audio_output_flags_t)(mFlags | flags);
608 
609     // If no mixer config is specified for a spatializer output, default to 5.1 for proper
610     // configuration of the final downmixer or spatializer
611     if ((mFlags & AUDIO_OUTPUT_FLAG_SPATIALIZER) != 0
612             && mixerConfig == nullptr) {
613         lMixerConfig.channel_mask = AUDIO_CHANNEL_OUT_5POINT1;
614     }
615 
616     ALOGV("opening output for device %s profile %p name %s",
617           mDevices.toString().c_str(), mProfile.get(), mProfile->getName().c_str());
618 
619     status_t status = mClientInterface->openOutput(mProfile->getModuleHandle(),
620                                                    output,
621                                                    &lHalConfig,
622                                                    &lMixerConfig,
623                                                    device,
624                                                    &mLatency,
625                                                    mFlags);
626 
627     if (status == NO_ERROR) {
628         LOG_ALWAYS_FATAL_IF(*output == AUDIO_IO_HANDLE_NONE,
629                             "%s openOutput returned output handle %d for device %s, "
630                             "selected device %s for opening",
631                             __FUNCTION__, *output, devices.toString().c_str(),
632                             device->toString().c_str());
633         mSamplingRate = lHalConfig.sample_rate;
634         mChannelMask = lHalConfig.channel_mask;
635         mFormat = lHalConfig.format;
636         mMixerChannelMask = lMixerConfig.channel_mask;
637         mId = PolicyAudioPort::getNextUniqueId();
638         mIoHandle = *output;
639         mProfile->curOpenCount++;
640     }
641 
642     return status;
643 }
644 
start()645 status_t SwAudioOutputDescriptor::start()
646 {
647     if (isDuplicated()) {
648         status_t status = mOutput1->start();
649         if (status != NO_ERROR) {
650             return status;
651         }
652         status = mOutput2->start();
653         if (status != NO_ERROR) {
654             mOutput1->stop();
655             return status;
656         }
657         return NO_ERROR;
658     }
659     if (!isActive()) {
660         if (!mProfile->canStartNewIo()) {
661             return INVALID_OPERATION;
662         }
663         mProfile->curActiveCount++;
664     }
665     return NO_ERROR;
666 }
667 
stop()668 void SwAudioOutputDescriptor::stop()
669 {
670     if (isDuplicated()) {
671         mOutput1->stop();
672         mOutput2->stop();
673         return;
674     }
675 
676     if (!isActive()) {
677         LOG_ALWAYS_FATAL_IF(mProfile->curActiveCount < 1,
678                             "%s invalid profile active count %u",
679                             __func__, mProfile->curActiveCount);
680         mProfile->curActiveCount--;
681     }
682 }
683 
close()684 void SwAudioOutputDescriptor::close()
685 {
686     if (mIoHandle != AUDIO_IO_HANDLE_NONE) {
687         // clean up active clients if any (can happen if close() is called to force
688         // clients to reconnect
689         for (const auto &client : getClientIterable()) {
690             if (client->active()) {
691                 ALOGW("%s client with port ID %d still active on output %d",
692                       __func__, client->portId(), mId);
693                 setClientActive(client, false);
694                 stop();
695             }
696         }
697 
698         AudioParameter param;
699         param.add(String8("closing"), String8("true"));
700         mClientInterface->setParameters(mIoHandle, param.toString());
701 
702         mClientInterface->closeOutput(mIoHandle);
703 
704         LOG_ALWAYS_FATAL_IF(mProfile->curOpenCount < 1, "%s profile open count %u",
705                             __FUNCTION__, mProfile->curOpenCount);
706         mProfile->curOpenCount--;
707         mIoHandle = AUDIO_IO_HANDLE_NONE;
708     }
709 }
710 
openDuplicating(const sp<SwAudioOutputDescriptor> & output1,const sp<SwAudioOutputDescriptor> & output2,audio_io_handle_t * ioHandle)711 status_t SwAudioOutputDescriptor::openDuplicating(const sp<SwAudioOutputDescriptor>& output1,
712                                                   const sp<SwAudioOutputDescriptor>& output2,
713                                                   audio_io_handle_t *ioHandle)
714 {
715     // open a duplicating output thread for the new output and the primary output
716     // Note: openDuplicateOutput() API expects the output handles in the reverse order from the
717     // numbering in SwAudioOutputDescriptor mOutput1 and mOutput2
718     *ioHandle = mClientInterface->openDuplicateOutput(output2->mIoHandle, output1->mIoHandle);
719     if (*ioHandle == AUDIO_IO_HANDLE_NONE) {
720         return INVALID_OPERATION;
721     }
722 
723     mId = PolicyAudioPort::getNextUniqueId();
724     mIoHandle = *ioHandle;
725     mOutput1 = output1;
726     mOutput2 = output2;
727     mSamplingRate = output2->mSamplingRate;
728     mFormat = output2->mFormat;
729     mChannelMask = output2->mChannelMask;
730     mLatency = output2->mLatency;
731 
732     return NO_ERROR;
733 }
734 
getRecommendedMuteDurationMs() const735 uint32_t SwAudioOutputDescriptor::getRecommendedMuteDurationMs() const
736 {
737     if (isDuplicated()) {
738         return std::max(mOutput1->getRecommendedMuteDurationMs(),
739                 mOutput2->getRecommendedMuteDurationMs());
740     }
741     return mProfile->recommendedMuteDurationMs;
742 }
743 
setTracksInvalidatedStatusByStrategy(product_strategy_t strategy)744 void SwAudioOutputDescriptor::setTracksInvalidatedStatusByStrategy(product_strategy_t strategy) {
745     for (const auto &client : getClientIterable()) {
746         if (strategy == client->strategy()) {
747             client->setIsInvalid();
748         }
749     }
750 }
751 
752 // HwAudioOutputDescriptor implementation
HwAudioOutputDescriptor(const sp<SourceClientDescriptor> & source,AudioPolicyClientInterface * clientInterface)753 HwAudioOutputDescriptor::HwAudioOutputDescriptor(const sp<SourceClientDescriptor>& source,
754                                                  AudioPolicyClientInterface *clientInterface)
755     : AudioOutputDescriptor(source->srcDevice(), clientInterface),
756       mSource(source)
757 {
758 }
759 
dump(String8 * dst,int spaces,const char * extraInfo) const760 void HwAudioOutputDescriptor::dump(String8 *dst, int spaces, const char* extraInfo) const
761 {
762     AudioOutputDescriptor::dump(dst, spaces, extraInfo);
763     dst->appendFormat("%*sSource:\n", spaces, "");
764     mSource->dump(dst, spaces);
765 }
766 
toAudioPortConfig(struct audio_port_config * dstConfig,const struct audio_port_config * srcConfig) const767 void HwAudioOutputDescriptor::toAudioPortConfig(
768                                                  struct audio_port_config *dstConfig,
769                                                  const struct audio_port_config *srcConfig) const
770 {
771     mSource->srcDevice()->toAudioPortConfig(dstConfig, srcConfig);
772 }
773 
toAudioPort(struct audio_port_v7 * port) const774 void HwAudioOutputDescriptor::toAudioPort(struct audio_port_v7 *port) const
775 {
776     mSource->srcDevice()->toAudioPort(port);
777 }
778 
779 
setVolume(float volumeDb,bool muted,VolumeSource volumeSource,const StreamTypeVector & streams,const DeviceTypeSet & deviceTypes,uint32_t delayMs,bool force)780 bool HwAudioOutputDescriptor::setVolume(float volumeDb, bool muted,
781                                         VolumeSource volumeSource, const StreamTypeVector &streams,
782                                         const DeviceTypeSet& deviceTypes,
783                                         uint32_t delayMs,
784                                         bool force)
785 {
786     bool changed = AudioOutputDescriptor::setVolume(
787             volumeDb, muted, volumeSource, streams, deviceTypes, delayMs, force);
788 
789     if (changed) {
790       // TODO: use gain controller on source device if any to adjust volume
791     }
792     return changed;
793 }
794 
795 // SwAudioOutputCollection implementation
isActive(VolumeSource volumeSource,uint32_t inPastMs) const796 bool SwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const
797 {
798     nsecs_t sysTime = systemTime();
799     for (size_t i = 0; i < this->size(); i++) {
800         const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
801         if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
802             return true;
803         }
804     }
805     return false;
806 }
807 
isActiveLocally(VolumeSource volumeSource,uint32_t inPastMs) const808 bool SwAudioOutputCollection::isActiveLocally(VolumeSource volumeSource, uint32_t inPastMs) const
809 {
810     nsecs_t sysTime = systemTime();
811     for (size_t i = 0; i < this->size(); i++) {
812         const sp<SwAudioOutputDescriptor> outputDesc = this->valueAt(i);
813         if (outputDesc->isActive(volumeSource, inPastMs, sysTime)
814                 && (!(outputDesc->devices()
815                         .containsDeviceAmongTypes(getAllOutRemoteDevices())
816                         || outputDesc->devices()
817                             .onlyContainsDevicesWithType(AUDIO_DEVICE_OUT_TELEPHONY_TX)))) {
818             return true;
819         }
820     }
821     return false;
822 }
823 
isActiveRemotely(VolumeSource volumeSource,uint32_t inPastMs) const824 bool SwAudioOutputCollection::isActiveRemotely(VolumeSource volumeSource, uint32_t inPastMs) const
825 {
826     nsecs_t sysTime = systemTime();
827     for (size_t i = 0; i < size(); i++) {
828         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
829         if (outputDesc->devices().containsDeviceAmongTypes(getAllOutRemoteDevices()) &&
830                 outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
831             // do not consider re routing (when the output is going to a dynamic policy)
832             // as "remote playback"
833             if (outputDesc->mPolicyMix == NULL) {
834                 return true;
835             }
836         }
837     }
838     return false;
839 }
840 
isStrategyActiveOnSameModule(product_strategy_t ps,const sp<SwAudioOutputDescriptor> & desc,uint32_t inPastMs,nsecs_t sysTime) const841 bool SwAudioOutputCollection::isStrategyActiveOnSameModule(product_strategy_t ps,
842                                                            const sp<SwAudioOutputDescriptor>& desc,
843                                                            uint32_t inPastMs, nsecs_t sysTime) const
844 {
845     for (size_t i = 0; i < size(); i++) {
846         const sp<SwAudioOutputDescriptor> otherDesc = valueAt(i);
847         if (desc->sharesHwModuleWith(otherDesc) &&
848                 otherDesc->isStrategyActive(ps, inPastMs, sysTime)) {
849             if (desc == otherDesc
850                     || !otherDesc->devices()
851                             .onlyContainsDevicesWithType(AUDIO_DEVICE_OUT_TELEPHONY_TX)) {
852                 return true;
853             }
854         }
855     }
856     return false;
857 }
858 
isStrategyActive(product_strategy_t ps) const859 bool SwAudioOutputCollection::isStrategyActive(product_strategy_t ps) const
860 {
861     for (size_t i = 0; i < size(); i++) {
862         if (valueAt(i)->isStrategyActive(ps)) {
863             return true;
864         }
865     }
866     return false;
867 }
868 
getA2dpOutput() const869 audio_io_handle_t SwAudioOutputCollection::getA2dpOutput() const
870 {
871     for (size_t i = 0; i < size(); i++) {
872         sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
873         if (!outputDesc->isDuplicated() &&
874              outputDesc->devices().containsDeviceAmongTypes(getAudioDeviceOutAllA2dpSet()) &&
875              outputDesc->devicesSupportEncodedFormats(getAudioDeviceOutAllA2dpSet())) {
876             return this->keyAt(i);
877         }
878     }
879     return 0;
880 }
881 
isA2dpOffloadedOnPrimary() const882 bool SwAudioOutputCollection::isA2dpOffloadedOnPrimary() const
883 {
884     sp<SwAudioOutputDescriptor> primaryOutput = getPrimaryOutput();
885 
886     if ((primaryOutput != NULL) && (primaryOutput->mProfile != NULL)
887         && (primaryOutput->mProfile->getModule() != NULL)) {
888         sp<HwModule> primaryHwModule = primaryOutput->mProfile->getModule();
889 
890         for (const auto &outputProfile : primaryHwModule->getOutputProfiles()) {
891             if (outputProfile->supportsDeviceTypes(getAudioDeviceOutAllA2dpSet())) {
892                 return true;
893             }
894         }
895     }
896     return false;
897 }
898 
getPrimaryOutput() const899 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getPrimaryOutput() const
900 {
901     for (size_t i = 0; i < size(); i++) {
902         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
903         if (outputDesc->mFlags & AUDIO_OUTPUT_FLAG_PRIMARY) {
904             return outputDesc;
905         }
906     }
907     return NULL;
908 }
909 
getOutputFromId(audio_port_handle_t id) const910 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputFromId(audio_port_handle_t id) const
911 {
912     for (size_t i = 0; i < size(); i++) {
913         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
914         if (outputDesc->getId() == id) {
915             return outputDesc;
916         }
917     }
918     return NULL;
919 }
920 
getOutputForClient(audio_port_handle_t portId)921 sp<SwAudioOutputDescriptor> SwAudioOutputCollection::getOutputForClient(audio_port_handle_t portId)
922 {
923     for (size_t i = 0; i < size(); i++) {
924         sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
925         if (outputDesc->getClient(portId) != nullptr) {
926             return outputDesc;
927         }
928     }
929     return 0;
930 }
931 
clearSessionRoutesForDevice(const sp<DeviceDescriptor> & disconnectedDevice)932 void SwAudioOutputCollection::clearSessionRoutesForDevice(
933         const sp<DeviceDescriptor> &disconnectedDevice)
934 {
935     for (size_t i = 0; i < size(); i++) {
936         sp<AudioOutputDescriptor> outputDesc = valueAt(i);
937         for (const auto& client : outputDesc->getClientIterable()) {
938             if (client->preferredDeviceId() == disconnectedDevice->getId()) {
939                 client->setPreferredDeviceId(AUDIO_PORT_HANDLE_NONE);
940             }
941         }
942     }
943 }
isAnyDeviceTypeActive(const DeviceTypeSet & deviceTypes) const944 bool SwAudioOutputCollection::isAnyDeviceTypeActive(const DeviceTypeSet& deviceTypes) const {
945     for (size_t i = 0; i < size(); i++) {
946         const sp<SwAudioOutputDescriptor> outputDesc = valueAt(i);
947         if (outputDesc->isActive()
948                 && outputDesc->devices().containsDeviceAmongTypes(deviceTypes)) {
949             return true;
950         }
951     }
952     return false;
953 }
954 
dump(String8 * dst) const955 void SwAudioOutputCollection::dump(String8 *dst) const
956 {
957     dst->appendFormat("\n Outputs (%zu):\n", size());
958     for (size_t i = 0; i < size(); i++) {
959         const std::string prefix = base::StringPrintf("  %zu. ", i + 1);
960         const std::string extraInfo = base::StringPrintf("I/O handle: %d", keyAt(i));
961         dst->appendFormat("%s", prefix.c_str());
962         valueAt(i)->dump(dst, prefix.size(), extraInfo.c_str());
963     }
964 }
965 
966 // HwAudioOutputCollection implementation
isActive(VolumeSource volumeSource,uint32_t inPastMs) const967 bool HwAudioOutputCollection::isActive(VolumeSource volumeSource, uint32_t inPastMs) const
968 {
969     nsecs_t sysTime = systemTime();
970     for (size_t i = 0; i < this->size(); i++) {
971         const sp<HwAudioOutputDescriptor> outputDesc = this->valueAt(i);
972         if (outputDesc->isActive(volumeSource, inPastMs, sysTime)) {
973             return true;
974         }
975     }
976     return false;
977 }
978 
dump(String8 * dst) const979 void HwAudioOutputCollection::dump(String8 *dst) const
980 {
981     dst->appendFormat("\n Outputs (%zu):\n", size());
982     for (size_t i = 0; i < size(); i++) {
983         const std::string prefix = base::StringPrintf("  %zu. ", i + 1);
984         const std::string extraInfo = base::StringPrintf("I/O handle: %d", keyAt(i));
985         dst->appendFormat("%s", prefix.c_str());
986         valueAt(i)->dump(dst, prefix.size(), extraInfo.c_str());
987     }
988 }
989 
990 }; //namespace android
991