Home | History | Annotate | Download | only in alsa_sound
      1 /*
      2  * Copyright (C) 2009 The Android Open Source Project
      3  * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
      4  *
      5  * Licensed under the Apache License, Version 2.0 (the "License");
      6  * you may not use this file except in compliance with the License.
      7  * You may obtain a copy of the License at
      8  *
      9  *      http://www.apache.org/licenses/LICENSE-2.0
     10  *
     11  * Unless required by applicable law or agreed to in writing, software
     12  * distributed under the License is distributed on an "AS IS" BASIS,
     13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14  * See the License for the specific language governing permissions and
     15  * limitations under the License.
     16  */
     17 
     18 #define LOG_TAG "AudioPolicyManagerALSA"
     19 //#define LOG_NDEBUG 0
     20 #define LOG_NDDEBUG 0
     21 #include <utils/Log.h>
     22 
     23 #include "AudioPolicyManagerALSA.h"
     24 #include <media/mediarecorder.h>
     25 
     26 namespace android_audio_legacy {
     27 
     28 // ----------------------------------------------------------------------------
     29 // AudioPolicyManagerALSA
     30 // ----------------------------------------------------------------------------
     31 
     32 //Compiling error seen if AudioParamer doesn't exist in this file
     33 
     34 AudioParameter param;
     35 
     36 // ---  class factory
     37 
     38 
     39 extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
     40 {
     41     return new AudioPolicyManager(clientInterface);
     42 }
     43 
     44 extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
     45 {
     46     delete interface;
     47 }
     48 
     49 void AudioPolicyManager::setPhoneState(int state) {
     50     ALOGV("setPhoneState() state %d", state);
     51     audio_devices_t newDevice = AUDIO_DEVICE_NONE;
     52     if (state < 0 || state >= AudioSystem::NUM_MODES) {
     53         ALOGW("setPhoneState() invalid state %d", state);
     54         return;
     55     }
     56 
     57     if (state == mPhoneState) {
     58         ALOGW("setPhoneState() setting same state %d", state);
     59         return;
     60     }
     61 
     62     // if leaving call state, handle special case of active streams
     63     // pertaining to sonification strategy see handleIncallSonification()
     64     if (isInCall()) {
     65         ALOGV("setPhoneState() in call state management: new state is %d", state);
     66         for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
     67             handleIncallSonification(stream, false, true);
     68         }
     69     }
     70 
     71     // store previous phone state for management of sonification strategy below
     72     int oldState = mPhoneState;
     73     mPhoneState = state;
     74     bool force = false;
     75 
     76     // are we entering or starting a call
     77     if (!isStateInCall(oldState) && isStateInCall(state)) {
     78         ALOGV("  Entering call in setPhoneState()");
     79         // force routing command to audio hardware when starting a call
     80         // even if no device change is needed
     81         force = true;
     82     } else if (isStateInCall(oldState) && !isStateInCall(state)) {
     83         ALOGV("  Exiting call in setPhoneState()");
     84         // force routing command to audio hardware when exiting a call
     85         // even if no device change is needed
     86         force = true;
     87     } else if (isStateInCall(state) && (state != oldState)) {
     88         ALOGV("  Switching between telephony and VoIP in setPhoneState()");
     89         // force routing command to audio hardware when switching between telephony and VoIP
     90         // even if no device change is needed
     91         force = true;
     92     }
     93 
     94     // check for device and output changes triggered by new phone state
     95     newDevice = getNewDevice(mPrimaryOutput, false /*fromCache*/);
     96     checkA2dpSuspend();
     97     checkOutputForAllStrategies();
     98     updateDevicesAndOutputs();
     99 
    100     AudioOutputDescriptor *hwOutputDesc = mOutputs.valueFor(mPrimaryOutput);
    101 
    102     // force routing command to audio hardware when ending call
    103     // even if no device change is needed
    104     if (isStateInCall(oldState) && newDevice == AUDIO_DEVICE_NONE) {
    105         newDevice = hwOutputDesc->device();
    106     }
    107 
    108     // when changing from ring tone to in call mode, mute the ringing tone
    109     // immediately and delay the route change to avoid sending the ring tone
    110     // tail into the earpiece or headset.
    111     int delayMs = 0;
    112     if (isStateInCall(state) && oldState == AudioSystem::MODE_RINGTONE) {
    113         // delay the device change command by twice the output latency to have some margin
    114         // and be sure that audio buffers not yet affected by the mute are out when
    115         // we actually apply the route change
    116         delayMs = hwOutputDesc->mLatency*2;
    117         setStreamMute(AudioSystem::RING, true, mPrimaryOutput);
    118     }
    119 
    120     if (isStateInCall(state)) {
    121         for (size_t i = 0; i < mOutputs.size(); i++) {
    122             AudioOutputDescriptor *desc = mOutputs.valueAt(i);
    123             //take the biggest latency for all outputs
    124             if (delayMs < desc->mLatency*2) {
    125                 delayMs = desc->mLatency*2;
    126             }
    127             //mute STRATEGY_MEDIA on all outputs
    128             if (desc->strategyRefCount(STRATEGY_MEDIA) != 0) {
    129                 setStrategyMute(STRATEGY_MEDIA, true, mOutputs.keyAt(i));
    130                 setStrategyMute(STRATEGY_MEDIA, false, mOutputs.keyAt(i), MUTE_TIME_MS,
    131                     getDeviceForStrategy(STRATEGY_MEDIA, true /*fromCache*/));
    132             }
    133         }
    134     }
    135 
    136     // Ignore the delay to enable voice call on this target as the enabling the
    137     // voice call has enough delay to make sure the ringtone audio completely
    138     // played out
    139     if (state == AudioSystem::MODE_IN_CALL && oldState == AudioSystem::MODE_RINGTONE) {
    140         delayMs = 40;
    141     }
    142 
    143     // change routing is necessary
    144     setOutputDevice(mPrimaryOutput, newDevice, force, delayMs);
    145 
    146     // if entering in call state, handle special case of active streams
    147     // pertaining to sonification strategy see handleIncallSonification()
    148     if (isStateInCall(state)) {
    149         ALOGV("setPhoneState() in call state management: new state is %d", state);
    150         // unmute the ringing tone after a sufficient delay if it was muted before
    151         // setting output device above
    152         if (oldState == AudioSystem::MODE_RINGTONE) {
    153             setStreamMute(AudioSystem::RING, false, mPrimaryOutput, MUTE_TIME_MS);
    154         }
    155         for (int stream = 0; stream < AudioSystem::NUM_STREAM_TYPES; stream++) {
    156             handleIncallSonification(stream, true, true);
    157         }
    158     }
    159 
    160     // Flag that ringtone volume must be limited to music volume until we exit MODE_RINGTONE
    161     if (state == AudioSystem::MODE_RINGTONE &&
    162         isStreamActive(AudioSystem::MUSIC, SONIFICATION_HEADSET_MUSIC_DELAY)) {
    163         mLimitRingtoneVolume = true;
    164     } else {
    165         mLimitRingtoneVolume = false;
    166     }
    167 }
    168 
    169 }; // namespace androidi_audio_legacy
    170