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