Home | History | Annotate | Download | only in src
      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::AudioInputDescriptor"
     18 //#define LOG_NDEBUG 0
     19 
     20 #include "AudioInputDescriptor.h"
     21 #include "IOProfile.h"
     22 #include "AudioGain.h"
     23 #include "HwModule.h"
     24 #include <media/AudioPolicy.h>
     25 #include <policy.h>
     26 
     27 namespace android {
     28 
     29 AudioInputDescriptor::AudioInputDescriptor(const sp<IOProfile>& profile)
     30     : mIoHandle(0),
     31       mDevice(AUDIO_DEVICE_NONE), mPolicyMix(NULL),
     32       mProfile(profile), mPatchHandle(AUDIO_PATCH_HANDLE_NONE), mId(0)
     33 {
     34     if (profile != NULL) {
     35         profile->pickAudioProfile(mSamplingRate, mChannelMask, mFormat);
     36         if (profile->mGains.size() > 0) {
     37             profile->mGains[0]->getDefaultConfig(&mGain);
     38         }
     39     }
     40 }
     41 
     42 void AudioInputDescriptor::setIoHandle(audio_io_handle_t ioHandle)
     43 {
     44     mId = AudioPort::getNextUniqueId();
     45     mIoHandle = ioHandle;
     46 }
     47 
     48 audio_module_handle_t AudioInputDescriptor::getModuleHandle() const
     49 {
     50     if (mProfile == 0) {
     51         return AUDIO_MODULE_HANDLE_NONE;
     52     }
     53     return mProfile->getModuleHandle();
     54 }
     55 
     56 uint32_t AudioInputDescriptor::getOpenRefCount() const
     57 {
     58     return mSessions.getOpenCount();
     59 }
     60 
     61 audio_port_handle_t AudioInputDescriptor::getId() const
     62 {
     63     return mId;
     64 }
     65 
     66 audio_source_t AudioInputDescriptor::inputSource() const
     67 {
     68     // TODO: return highest priority input source
     69     return mSessions.size() > 0 ? mSessions.valueAt(0)->inputSource() :
     70                        AUDIO_SOURCE_DEFAULT;
     71 }
     72 
     73 void AudioInputDescriptor::toAudioPortConfig(struct audio_port_config *dstConfig,
     74                                              const struct audio_port_config *srcConfig) const
     75 {
     76     ALOG_ASSERT(mProfile != 0,
     77                 "toAudioPortConfig() called on input with null profile %d", mIoHandle);
     78     dstConfig->config_mask = AUDIO_PORT_CONFIG_SAMPLE_RATE|AUDIO_PORT_CONFIG_CHANNEL_MASK|
     79                             AUDIO_PORT_CONFIG_FORMAT|AUDIO_PORT_CONFIG_GAIN;
     80     if (srcConfig != NULL) {
     81         dstConfig->config_mask |= srcConfig->config_mask;
     82     }
     83 
     84     AudioPortConfig::toAudioPortConfig(dstConfig, srcConfig);
     85 
     86     dstConfig->id = mId;
     87     dstConfig->role = AUDIO_PORT_ROLE_SINK;
     88     dstConfig->type = AUDIO_PORT_TYPE_MIX;
     89     dstConfig->ext.mix.hw_module = getModuleHandle();
     90     dstConfig->ext.mix.handle = mIoHandle;
     91     dstConfig->ext.mix.usecase.source = inputSource();
     92 }
     93 
     94 void AudioInputDescriptor::toAudioPort(struct audio_port *port) const
     95 {
     96     ALOG_ASSERT(mProfile != 0, "toAudioPort() called on input with null profile %d", mIoHandle);
     97 
     98     mProfile->toAudioPort(port);
     99     port->id = mId;
    100     toAudioPortConfig(&port->active_config);
    101     port->ext.mix.hw_module = getModuleHandle();
    102     port->ext.mix.handle = mIoHandle;
    103     port->ext.mix.latency_class = AUDIO_LATENCY_NORMAL;
    104 }
    105 
    106 void AudioInputDescriptor::setPreemptedSessions(const SortedVector<audio_session_t>& sessions)
    107 {
    108     mPreemptedSessions = sessions;
    109 }
    110 
    111 SortedVector<audio_session_t> AudioInputDescriptor::getPreemptedSessions() const
    112 {
    113     return mPreemptedSessions;
    114 }
    115 
    116 bool AudioInputDescriptor::hasPreemptedSession(audio_session_t session) const
    117 {
    118     return (mPreemptedSessions.indexOf(session) >= 0);
    119 }
    120 
    121 void AudioInputDescriptor::clearPreemptedSessions()
    122 {
    123     mPreemptedSessions.clear();
    124 }
    125 
    126 bool AudioInputDescriptor::isActive() const {
    127     return mSessions.hasActiveSession();
    128 }
    129 
    130 bool AudioInputDescriptor::isSourceActive(audio_source_t source) const
    131 {
    132     return mSessions.isSourceActive(source);
    133 }
    134 
    135 bool AudioInputDescriptor::isSoundTrigger() const {
    136     // sound trigger and non sound trigger sessions are not mixed
    137     // on a given input
    138     return mSessions.valueAt(0)->isSoundTrigger();
    139 }
    140 
    141 sp<AudioSession> AudioInputDescriptor::getAudioSession(
    142                                               audio_session_t session) const {
    143     return mSessions.valueFor(session);
    144 }
    145 
    146 AudioSessionCollection AudioInputDescriptor::getActiveAudioSessions() const
    147 {
    148     return mSessions.getActiveSessions();
    149 }
    150 
    151 status_t AudioInputDescriptor::addAudioSession(audio_session_t session,
    152                          const sp<AudioSession>& audioSession) {
    153     return mSessions.addSession(session, audioSession, /*AudioSessionInfoProvider*/this);
    154 }
    155 
    156 status_t AudioInputDescriptor::removeAudioSession(audio_session_t session) {
    157     return mSessions.removeSession(session);
    158 }
    159 
    160 audio_patch_handle_t AudioInputDescriptor::getPatchHandle() const
    161 {
    162     return mPatchHandle;
    163 }
    164 
    165 void AudioInputDescriptor::setPatchHandle(audio_patch_handle_t handle)
    166 {
    167     mPatchHandle = handle;
    168     mSessions.onSessionInfoUpdate();
    169 }
    170 
    171 audio_config_base_t AudioInputDescriptor::getConfig() const
    172 {
    173     const audio_config_base_t config = { .sample_rate = mSamplingRate, .channel_mask = mChannelMask,
    174             .format = mFormat };
    175     return config;
    176 }
    177 
    178 status_t AudioInputDescriptor::dump(int fd)
    179 {
    180     const size_t SIZE = 256;
    181     char buffer[SIZE];
    182     String8 result;
    183 
    184     snprintf(buffer, SIZE, " ID: %d\n", getId());
    185     result.append(buffer);
    186     snprintf(buffer, SIZE, " Sampling rate: %d\n", mSamplingRate);
    187     result.append(buffer);
    188     snprintf(buffer, SIZE, " Format: %d\n", mFormat);
    189     result.append(buffer);
    190     snprintf(buffer, SIZE, " Channels: %08x\n", mChannelMask);
    191     result.append(buffer);
    192     snprintf(buffer, SIZE, " Devices %08x\n", mDevice);
    193     result.append(buffer);
    194 
    195     write(fd, result.string(), result.size());
    196 
    197     mSessions.dump(fd, 1);
    198 
    199     return NO_ERROR;
    200 }
    201 
    202 bool AudioInputCollection::isSourceActive(audio_source_t source) const
    203 {
    204     for (size_t i = 0; i < size(); i++) {
    205         const sp<AudioInputDescriptor>  inputDescriptor = valueAt(i);
    206         if (inputDescriptor->isSourceActive(source)) {
    207             return true;
    208         }
    209     }
    210     return false;
    211 }
    212 
    213 sp<AudioInputDescriptor> AudioInputCollection::getInputFromId(audio_port_handle_t id) const
    214 {
    215     sp<AudioInputDescriptor> inputDesc = NULL;
    216     for (size_t i = 0; i < size(); i++) {
    217         inputDesc = valueAt(i);
    218         if (inputDesc->getId() == id) {
    219             break;
    220         }
    221     }
    222     return inputDesc;
    223 }
    224 
    225 uint32_t AudioInputCollection::activeInputsCount() const
    226 {
    227     uint32_t count = 0;
    228     for (size_t i = 0; i < size(); i++) {
    229         const sp<AudioInputDescriptor>  inputDescriptor = valueAt(i);
    230         if (inputDescriptor->isActive()) {
    231             count++;
    232         }
    233     }
    234     return count;
    235 }
    236 
    237 audio_io_handle_t AudioInputCollection::getActiveInput(bool ignoreVirtualInputs)
    238 {
    239     for (size_t i = 0; i < size(); i++) {
    240         const sp<AudioInputDescriptor>  inputDescriptor = valueAt(i);
    241         if ((inputDescriptor->isActive())
    242                 && (!ignoreVirtualInputs ||
    243                     !is_virtual_input_device(inputDescriptor->mDevice))) {
    244             return keyAt(i);
    245         }
    246     }
    247     return 0;
    248 }
    249 
    250 audio_devices_t AudioInputCollection::getSupportedDevices(audio_io_handle_t handle) const
    251 {
    252     sp<AudioInputDescriptor> inputDesc = valueFor(handle);
    253     audio_devices_t devices = inputDesc->mProfile->getSupportedDevicesType();
    254     return devices;
    255 }
    256 
    257 status_t AudioInputCollection::dump(int fd) const
    258 {
    259     const size_t SIZE = 256;
    260     char buffer[SIZE];
    261 
    262     snprintf(buffer, SIZE, "\nInputs dump:\n");
    263     write(fd, buffer, strlen(buffer));
    264     for (size_t i = 0; i < size(); i++) {
    265         snprintf(buffer, SIZE, "- Input %d dump:\n", keyAt(i));
    266         write(fd, buffer, strlen(buffer));
    267         valueAt(i)->dump(fd);
    268     }
    269 
    270     return NO_ERROR;
    271 }
    272 
    273 }; //namespace android
    274