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