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