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
createAudioPolicyManager(AudioPolicyClientInterface * clientInterface)39 extern "C" AudioPolicyInterface* createAudioPolicyManager(AudioPolicyClientInterface *clientInterface)
40 {
41 return new AudioPolicyManager(clientInterface);
42 }
43
destroyAudioPolicyManager(AudioPolicyInterface * interface)44 extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface)
45 {
46 delete interface;
47 }
48
setPhoneState(int state)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