| François Gaffie | 2110e04 | 2015-03-24 08:41:51 +0100 | [diff] [blame^] | 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::AudioPolicyEngine" | 
 | 18 | //#define LOG_NDEBUG 0 | 
 | 19 |  | 
 | 20 | //#define VERY_VERBOSE_LOGGING | 
 | 21 | #ifdef VERY_VERBOSE_LOGGING | 
 | 22 | #define ALOGVV ALOGV | 
 | 23 | #else | 
 | 24 | #define ALOGVV(a...) do { } while(0) | 
 | 25 | #endif | 
 | 26 |  | 
 | 27 | #include "Engine.h" | 
 | 28 | #include "Gains.h" | 
 | 29 | #include <AudioPolicyManagerObserver.h> | 
 | 30 | #include <AudioPort.h> | 
 | 31 | #include <IOProfile.h> | 
 | 32 | #include <policy.h> | 
 | 33 | #include <utils/String8.h> | 
 | 34 | #include <utils/Log.h> | 
 | 35 |  | 
 | 36 | namespace android | 
 | 37 | { | 
 | 38 | namespace audio_policy | 
 | 39 | { | 
 | 40 |  | 
 | 41 | Engine::Engine() | 
 | 42 |     : mManagerInterface(this), | 
 | 43 |       mPhoneState(AUDIO_MODE_NORMAL), | 
 | 44 |       mApmObserver(NULL) | 
 | 45 | { | 
 | 46 |     for (int i = 0; i < AUDIO_POLICY_FORCE_USE_CNT; i++) { | 
 | 47 |         mForceUse[i] = AUDIO_POLICY_FORCE_NONE; | 
 | 48 |     } | 
 | 49 | } | 
 | 50 |  | 
 | 51 | Engine::~Engine() | 
 | 52 | { | 
 | 53 | } | 
 | 54 |  | 
 | 55 | void Engine::setObserver(AudioPolicyManagerObserver *observer) | 
 | 56 | { | 
 | 57 |     ALOG_ASSERT(observer != NULL, "Invalid Audio Policy Manager observer"); | 
 | 58 |     mApmObserver = observer; | 
 | 59 | } | 
 | 60 |  | 
 | 61 | status_t Engine::initCheck() | 
 | 62 | { | 
 | 63 |     return (mApmObserver != NULL) ?  NO_ERROR : NO_INIT; | 
 | 64 | } | 
 | 65 |  | 
 | 66 | float Engine::volIndexToAmpl(Volume::device_category category, audio_stream_type_t streamType, | 
 | 67 |                              int indexInUi) | 
 | 68 | { | 
 | 69 |     const StreamDescriptor &streamDesc = mApmObserver->getStreamDescriptors().valueAt(streamType); | 
 | 70 |     return Gains::volIndexToAmpl(category, streamDesc, indexInUi); | 
 | 71 | } | 
 | 72 |  | 
 | 73 | status_t Engine::initStreamVolume(audio_stream_type_t stream, int indexMin, int indexMax) | 
 | 74 | { | 
 | 75 |     ALOGV("initStreamVolume() stream %d, min %d, max %d", stream , indexMin, indexMax); | 
 | 76 |     if (indexMin < 0 || indexMin >= indexMax) { | 
 | 77 |         ALOGW("initStreamVolume() invalid index limits for stream %d, min %d, max %d", | 
 | 78 |               stream , indexMin, indexMax); | 
 | 79 |         return BAD_VALUE; | 
 | 80 |     } | 
 | 81 |     mApmObserver->getStreamDescriptors().setVolumeIndexMin(stream, indexMin); | 
 | 82 |     mApmObserver->getStreamDescriptors().setVolumeIndexMax(stream, indexMax); | 
 | 83 |     return NO_ERROR; | 
 | 84 | } | 
 | 85 |  | 
 | 86 | void Engine::initializeVolumeCurves(bool isSpeakerDrcEnabled) | 
 | 87 | { | 
 | 88 |     StreamDescriptorCollection &streams = mApmObserver->getStreamDescriptors(); | 
 | 89 |  | 
 | 90 |     for (int i = 0; i < AUDIO_STREAM_CNT; i++) { | 
 | 91 |         for (int j = 0; j < Volume::DEVICE_CATEGORY_CNT; j++) { | 
 | 92 |             streams.setVolumeCurvePoint(static_cast<audio_stream_type_t>(i), | 
 | 93 |                                          static_cast<Volume::device_category>(j), | 
 | 94 |                                          Gains::sVolumeProfiles[i][j]); | 
 | 95 |         } | 
 | 96 |     } | 
 | 97 |  | 
 | 98 |     // Check availability of DRC on speaker path: if available, override some of the speaker curves | 
 | 99 |     if (isSpeakerDrcEnabled) { | 
 | 100 |         streams.setVolumeCurvePoint(AUDIO_STREAM_SYSTEM, Volume::DEVICE_CATEGORY_SPEAKER, | 
 | 101 |                 Gains::sDefaultSystemVolumeCurveDrc); | 
 | 102 |         streams.setVolumeCurvePoint(AUDIO_STREAM_RING, Volume::DEVICE_CATEGORY_SPEAKER, | 
 | 103 |                 Gains::sSpeakerSonificationVolumeCurveDrc); | 
 | 104 |         streams.setVolumeCurvePoint(AUDIO_STREAM_ALARM, Volume::DEVICE_CATEGORY_SPEAKER, | 
 | 105 |                 Gains::sSpeakerSonificationVolumeCurveDrc); | 
 | 106 |         streams.setVolumeCurvePoint(AUDIO_STREAM_NOTIFICATION, Volume::DEVICE_CATEGORY_SPEAKER, | 
 | 107 |                 Gains::sSpeakerSonificationVolumeCurveDrc); | 
 | 108 |         streams.setVolumeCurvePoint(AUDIO_STREAM_MUSIC, Volume::DEVICE_CATEGORY_SPEAKER, | 
 | 109 |                 Gains::sSpeakerMediaVolumeCurveDrc); | 
 | 110 |         streams.setVolumeCurvePoint(AUDIO_STREAM_ACCESSIBILITY, Volume::DEVICE_CATEGORY_SPEAKER, | 
 | 111 |                 Gains::sSpeakerMediaVolumeCurveDrc); | 
 | 112 |     } | 
 | 113 | } | 
 | 114 |  | 
 | 115 |  | 
 | 116 | status_t Engine::setPhoneState(audio_mode_t state) | 
 | 117 | { | 
 | 118 |     ALOGV("setPhoneState() state %d", state); | 
 | 119 |  | 
 | 120 |     if (state < 0 || state >= AUDIO_MODE_CNT) { | 
 | 121 |         ALOGW("setPhoneState() invalid state %d", state); | 
 | 122 |         return BAD_VALUE; | 
 | 123 |     } | 
 | 124 |  | 
 | 125 |     if (state == mPhoneState ) { | 
 | 126 |         ALOGW("setPhoneState() setting same state %d", state); | 
 | 127 |         return BAD_VALUE; | 
 | 128 |     } | 
 | 129 |  | 
 | 130 |     // store previous phone state for management of sonification strategy below | 
 | 131 |     int oldState = mPhoneState; | 
 | 132 |     mPhoneState = state; | 
 | 133 |     StreamDescriptorCollection &streams = mApmObserver->getStreamDescriptors(); | 
 | 134 |     // are we entering or starting a call | 
 | 135 |     if (!is_state_in_call(oldState) && is_state_in_call(state)) { | 
 | 136 |         ALOGV("  Entering call in setPhoneState()"); | 
 | 137 |         for (int j = 0; j < Volume::DEVICE_CATEGORY_CNT; j++) { | 
 | 138 |             streams.setVolumeCurvePoint(AUDIO_STREAM_DTMF, static_cast<Volume::device_category>(j), | 
 | 139 |                                          Gains::sVolumeProfiles[AUDIO_STREAM_VOICE_CALL][j]); | 
 | 140 |         } | 
 | 141 |     } else if (is_state_in_call(oldState) && !is_state_in_call(state)) { | 
 | 142 |         ALOGV("  Exiting call in setPhoneState()"); | 
 | 143 |         for (int j = 0; j < Volume::DEVICE_CATEGORY_CNT; j++) { | 
 | 144 |             streams.setVolumeCurvePoint(AUDIO_STREAM_DTMF, static_cast<Volume::device_category>(j), | 
 | 145 |                                          Gains::sVolumeProfiles[AUDIO_STREAM_DTMF][j]); | 
 | 146 |         } | 
 | 147 |     } | 
 | 148 |     return NO_ERROR; | 
 | 149 | } | 
 | 150 |  | 
 | 151 | status_t Engine::setForceUse(audio_policy_force_use_t usage, audio_policy_forced_cfg_t config) | 
 | 152 | { | 
 | 153 |     switch(usage) { | 
 | 154 |     case AUDIO_POLICY_FORCE_FOR_COMMUNICATION: | 
 | 155 |         if (config != AUDIO_POLICY_FORCE_SPEAKER && config != AUDIO_POLICY_FORCE_BT_SCO && | 
 | 156 |             config != AUDIO_POLICY_FORCE_NONE) { | 
 | 157 |             ALOGW("setForceUse() invalid config %d for FOR_COMMUNICATION", config); | 
 | 158 |             return BAD_VALUE; | 
 | 159 |         } | 
 | 160 |         mForceUse[usage] = config; | 
 | 161 |         break; | 
 | 162 |     case AUDIO_POLICY_FORCE_FOR_MEDIA: | 
 | 163 |         if (config != AUDIO_POLICY_FORCE_HEADPHONES && config != AUDIO_POLICY_FORCE_BT_A2DP && | 
 | 164 |             config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && | 
 | 165 |             config != AUDIO_POLICY_FORCE_ANALOG_DOCK && | 
 | 166 |             config != AUDIO_POLICY_FORCE_DIGITAL_DOCK && config != AUDIO_POLICY_FORCE_NONE && | 
 | 167 |             config != AUDIO_POLICY_FORCE_NO_BT_A2DP && config != AUDIO_POLICY_FORCE_SPEAKER ) { | 
 | 168 |             ALOGW("setForceUse() invalid config %d for FOR_MEDIA", config); | 
 | 169 |             return BAD_VALUE; | 
 | 170 |         } | 
 | 171 |         mForceUse[usage] = config; | 
 | 172 |         break; | 
 | 173 |     case AUDIO_POLICY_FORCE_FOR_RECORD: | 
 | 174 |         if (config != AUDIO_POLICY_FORCE_BT_SCO && config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && | 
 | 175 |             config != AUDIO_POLICY_FORCE_NONE) { | 
 | 176 |             ALOGW("setForceUse() invalid config %d for FOR_RECORD", config); | 
 | 177 |             return BAD_VALUE; | 
 | 178 |         } | 
 | 179 |         mForceUse[usage] = config; | 
 | 180 |         break; | 
 | 181 |     case AUDIO_POLICY_FORCE_FOR_DOCK: | 
 | 182 |         if (config != AUDIO_POLICY_FORCE_NONE && config != AUDIO_POLICY_FORCE_BT_CAR_DOCK && | 
 | 183 |             config != AUDIO_POLICY_FORCE_BT_DESK_DOCK && | 
 | 184 |             config != AUDIO_POLICY_FORCE_WIRED_ACCESSORY && | 
 | 185 |             config != AUDIO_POLICY_FORCE_ANALOG_DOCK && | 
 | 186 |             config != AUDIO_POLICY_FORCE_DIGITAL_DOCK) { | 
 | 187 |             ALOGW("setForceUse() invalid config %d for FOR_DOCK", config); | 
 | 188 |         } | 
 | 189 |         mForceUse[usage] = config; | 
 | 190 |         break; | 
 | 191 |     case AUDIO_POLICY_FORCE_FOR_SYSTEM: | 
 | 192 |         if (config != AUDIO_POLICY_FORCE_NONE && | 
 | 193 |             config != AUDIO_POLICY_FORCE_SYSTEM_ENFORCED) { | 
 | 194 |             ALOGW("setForceUse() invalid config %d for FOR_SYSTEM", config); | 
 | 195 |         } | 
 | 196 |         mForceUse[usage] = config; | 
 | 197 |         break; | 
 | 198 |     case AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO: | 
 | 199 |         if (config != AUDIO_POLICY_FORCE_NONE && | 
 | 200 |             config != AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED) { | 
 | 201 |             ALOGW("setForceUse() invalid config %d forHDMI_SYSTEM_AUDIO", config); | 
 | 202 |         } | 
 | 203 |         mForceUse[usage] = config; | 
 | 204 |         break; | 
 | 205 |     default: | 
 | 206 |         ALOGW("setForceUse() invalid usage %d", usage); | 
 | 207 |         break; | 
 | 208 |     } | 
 | 209 |     return NO_ERROR; | 
 | 210 | } | 
 | 211 |  | 
 | 212 | routing_strategy Engine::getStrategyForStream(audio_stream_type_t stream) | 
 | 213 | { | 
 | 214 |     // stream to strategy mapping | 
 | 215 |     switch (stream) { | 
 | 216 |     case AUDIO_STREAM_VOICE_CALL: | 
 | 217 |     case AUDIO_STREAM_BLUETOOTH_SCO: | 
 | 218 |         return STRATEGY_PHONE; | 
 | 219 |     case AUDIO_STREAM_RING: | 
 | 220 |     case AUDIO_STREAM_ALARM: | 
 | 221 |         return STRATEGY_SONIFICATION; | 
 | 222 |     case AUDIO_STREAM_NOTIFICATION: | 
 | 223 |         return STRATEGY_SONIFICATION_RESPECTFUL; | 
 | 224 |     case AUDIO_STREAM_DTMF: | 
 | 225 |         return STRATEGY_DTMF; | 
 | 226 |     default: | 
 | 227 |         ALOGE("unknown stream type %d", stream); | 
 | 228 |     case AUDIO_STREAM_SYSTEM: | 
 | 229 |         // NOTE: SYSTEM stream uses MEDIA strategy because muting music and switching outputs | 
 | 230 |         // while key clicks are played produces a poor result | 
 | 231 |     case AUDIO_STREAM_MUSIC: | 
 | 232 |         return STRATEGY_MEDIA; | 
 | 233 |     case AUDIO_STREAM_ENFORCED_AUDIBLE: | 
 | 234 |         return STRATEGY_ENFORCED_AUDIBLE; | 
 | 235 |     case AUDIO_STREAM_TTS: | 
 | 236 |         return STRATEGY_TRANSMITTED_THROUGH_SPEAKER; | 
 | 237 |     case AUDIO_STREAM_ACCESSIBILITY: | 
 | 238 |         return STRATEGY_ACCESSIBILITY; | 
 | 239 |     case AUDIO_STREAM_REROUTING: | 
 | 240 |         return STRATEGY_REROUTING; | 
 | 241 |     } | 
 | 242 | } | 
 | 243 |  | 
 | 244 | routing_strategy Engine::getStrategyForUsage(audio_usage_t usage) | 
 | 245 | { | 
 | 246 |     const AudioOutputCollection &outputs = mApmObserver->getOutputs(); | 
 | 247 |  | 
 | 248 |     // usage to strategy mapping | 
 | 249 |     switch (usage) { | 
 | 250 |     case AUDIO_USAGE_ASSISTANCE_ACCESSIBILITY: | 
 | 251 |         if (outputs.isStreamActive(AUDIO_STREAM_RING) || | 
 | 252 |                 outputs.isStreamActive(AUDIO_STREAM_ALARM)) { | 
 | 253 |             return STRATEGY_SONIFICATION; | 
 | 254 |         } | 
 | 255 |         if (isInCall()) { | 
 | 256 |             return STRATEGY_PHONE; | 
 | 257 |         } | 
 | 258 |         return STRATEGY_ACCESSIBILITY; | 
 | 259 |  | 
 | 260 |     case AUDIO_USAGE_MEDIA: | 
 | 261 |     case AUDIO_USAGE_GAME: | 
 | 262 |     case AUDIO_USAGE_ASSISTANCE_NAVIGATION_GUIDANCE: | 
 | 263 |     case AUDIO_USAGE_ASSISTANCE_SONIFICATION: | 
 | 264 |         return STRATEGY_MEDIA; | 
 | 265 |  | 
 | 266 |     case AUDIO_USAGE_VOICE_COMMUNICATION: | 
 | 267 |         return STRATEGY_PHONE; | 
 | 268 |  | 
 | 269 |     case AUDIO_USAGE_VOICE_COMMUNICATION_SIGNALLING: | 
 | 270 |         return STRATEGY_DTMF; | 
 | 271 |  | 
 | 272 |     case AUDIO_USAGE_ALARM: | 
 | 273 |     case AUDIO_USAGE_NOTIFICATION_TELEPHONY_RINGTONE: | 
 | 274 |         return STRATEGY_SONIFICATION; | 
 | 275 |  | 
 | 276 |     case AUDIO_USAGE_NOTIFICATION: | 
 | 277 |     case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_REQUEST: | 
 | 278 |     case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_INSTANT: | 
 | 279 |     case AUDIO_USAGE_NOTIFICATION_COMMUNICATION_DELAYED: | 
 | 280 |     case AUDIO_USAGE_NOTIFICATION_EVENT: | 
 | 281 |         return STRATEGY_SONIFICATION_RESPECTFUL; | 
 | 282 |  | 
 | 283 |     case AUDIO_USAGE_UNKNOWN: | 
 | 284 |     default: | 
 | 285 |         return STRATEGY_MEDIA; | 
 | 286 |     } | 
 | 287 | } | 
 | 288 |  | 
 | 289 | audio_devices_t Engine::getDeviceForStrategy(routing_strategy strategy) const | 
 | 290 | { | 
 | 291 |     const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices(); | 
 | 292 |     const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices(); | 
 | 293 |  | 
 | 294 |     const AudioOutputCollection &outputs = mApmObserver->getOutputs(); | 
 | 295 |  | 
 | 296 |     uint32_t device = AUDIO_DEVICE_NONE; | 
 | 297 |     uint32_t availableOutputDevicesType = availableOutputDevices.types(); | 
 | 298 |  | 
 | 299 |     switch (strategy) { | 
 | 300 |  | 
 | 301 |     case STRATEGY_TRANSMITTED_THROUGH_SPEAKER: | 
 | 302 |         device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER; | 
 | 303 |         if (!device) { | 
 | 304 |             ALOGE("getDeviceForStrategy() no device found for "\ | 
 | 305 |                     "STRATEGY_TRANSMITTED_THROUGH_SPEAKER"); | 
 | 306 |         } | 
 | 307 |         break; | 
 | 308 |  | 
 | 309 |     case STRATEGY_SONIFICATION_RESPECTFUL: | 
 | 310 |         if (isInCall()) { | 
 | 311 |             device = getDeviceForStrategy(STRATEGY_SONIFICATION); | 
 | 312 |         } else if (outputs.isStreamActiveRemotely(AUDIO_STREAM_MUSIC, | 
 | 313 |                 SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { | 
 | 314 |             // while media is playing on a remote device, use the the sonification behavior. | 
 | 315 |             // Note that we test this usecase before testing if media is playing because | 
 | 316 |             //   the isStreamActive() method only informs about the activity of a stream, not | 
 | 317 |             //   if it's for local playback. Note also that we use the same delay between both tests | 
 | 318 |             device = getDeviceForStrategy(STRATEGY_SONIFICATION); | 
 | 319 |             //user "safe" speaker if available instead of normal speaker to avoid triggering | 
 | 320 |             //other acoustic safety mechanisms for notification | 
 | 321 |             if (device == AUDIO_DEVICE_OUT_SPEAKER && (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) | 
 | 322 |                 device = AUDIO_DEVICE_OUT_SPEAKER_SAFE; | 
 | 323 |         } else if (outputs.isStreamActive(AUDIO_STREAM_MUSIC, SONIFICATION_RESPECTFUL_AFTER_MUSIC_DELAY)) { | 
 | 324 |             // while media is playing (or has recently played), use the same device | 
 | 325 |             device = getDeviceForStrategy(STRATEGY_MEDIA); | 
 | 326 |         } else { | 
 | 327 |             // when media is not playing anymore, fall back on the sonification behavior | 
 | 328 |             device = getDeviceForStrategy(STRATEGY_SONIFICATION); | 
 | 329 |             //user "safe" speaker if available instead of normal speaker to avoid triggering | 
 | 330 |             //other acoustic safety mechanisms for notification | 
 | 331 |             if (device == AUDIO_DEVICE_OUT_SPEAKER && (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER_SAFE)) | 
 | 332 |                 device = AUDIO_DEVICE_OUT_SPEAKER_SAFE; | 
 | 333 |         } | 
 | 334 |         break; | 
 | 335 |  | 
 | 336 |     case STRATEGY_DTMF: | 
 | 337 |         if (!isInCall()) { | 
 | 338 |             // when off call, DTMF strategy follows the same rules as MEDIA strategy | 
 | 339 |             device = getDeviceForStrategy(STRATEGY_MEDIA); | 
 | 340 |             break; | 
 | 341 |         } | 
 | 342 |         // when in call, DTMF and PHONE strategies follow the same rules | 
 | 343 |         // FALL THROUGH | 
 | 344 |  | 
 | 345 |     case STRATEGY_PHONE: | 
 | 346 |         // Force use of only devices on primary output if: | 
 | 347 |         // - in call AND | 
 | 348 |         //   - cannot route from voice call RX OR | 
 | 349 |         //   - audio HAL version is < 3.0 and TX device is on the primary HW module | 
 | 350 |         if (getPhoneState() == AUDIO_MODE_IN_CALL) { | 
 | 351 |             audio_devices_t txDevice = getDeviceForInputSource(AUDIO_SOURCE_VOICE_COMMUNICATION); | 
 | 352 |             sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput(); | 
 | 353 |             audio_devices_t availPrimaryInputDevices = | 
 | 354 |                  availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle()); | 
 | 355 |             audio_devices_t availPrimaryOutputDevices = | 
 | 356 |                     primaryOutput->supportedDevices() & availableOutputDevices.types(); | 
 | 357 |  | 
 | 358 |             if (((availableInputDevices.types() & | 
 | 359 |                     AUDIO_DEVICE_IN_TELEPHONY_RX & ~AUDIO_DEVICE_BIT_IN) == 0) || | 
 | 360 |                     (((txDevice & availPrimaryInputDevices & ~AUDIO_DEVICE_BIT_IN) != 0) && | 
 | 361 |                          (primaryOutput->getAudioPort()->mModule->mHalVersion < | 
 | 362 |                              AUDIO_DEVICE_API_VERSION_3_0))) { | 
 | 363 |                 availableOutputDevicesType = availPrimaryOutputDevices; | 
 | 364 |             } | 
 | 365 |         } | 
 | 366 |         // for phone strategy, we first consider the forced use and then the available devices by order | 
 | 367 |         // of priority | 
 | 368 |         switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) { | 
 | 369 |         case AUDIO_POLICY_FORCE_BT_SCO: | 
 | 370 |             if (!isInCall() || strategy != STRATEGY_DTMF) { | 
 | 371 |                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_CARKIT; | 
 | 372 |                 if (device) break; | 
 | 373 |             } | 
 | 374 |             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO_HEADSET; | 
 | 375 |             if (device) break; | 
 | 376 |             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_SCO; | 
 | 377 |             if (device) break; | 
 | 378 |             // if SCO device is requested but no SCO device is available, fall back to default case | 
 | 379 |             // FALL THROUGH | 
 | 380 |  | 
 | 381 |         default:    // FORCE_NONE | 
 | 382 |             // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to A2DP | 
 | 383 |             if (!isInCall() && | 
 | 384 |                     (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && | 
 | 385 |                     (outputs.getA2dpOutput() != 0)) { | 
 | 386 |                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; | 
 | 387 |                 if (device) break; | 
 | 388 |                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; | 
 | 389 |                 if (device) break; | 
 | 390 |             } | 
 | 391 |             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; | 
 | 392 |             if (device) break; | 
 | 393 |             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET; | 
 | 394 |             if (device) break; | 
 | 395 |             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE; | 
 | 396 |             if (device) break; | 
 | 397 |             if (!isInCall()) { | 
 | 398 |                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY; | 
 | 399 |                 if (device) break; | 
 | 400 |                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; | 
 | 401 |                 if (device) break; | 
 | 402 |                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL; | 
 | 403 |                 if (device) break; | 
 | 404 |                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; | 
 | 405 |                 if (device) break; | 
 | 406 |             } | 
 | 407 |             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_EARPIECE; | 
 | 408 |             if (device) break; | 
 | 409 |             device = mApmObserver->getDefaultOutputDevice()->type(); | 
 | 410 |             if (device == AUDIO_DEVICE_NONE) { | 
 | 411 |                 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE"); | 
 | 412 |             } | 
 | 413 |             break; | 
 | 414 |  | 
 | 415 |         case AUDIO_POLICY_FORCE_SPEAKER: | 
 | 416 |             // when not in a phone call, phone strategy should route STREAM_VOICE_CALL to | 
 | 417 |             // A2DP speaker when forcing to speaker output | 
 | 418 |             if (!isInCall() && | 
 | 419 |                     (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && | 
 | 420 |                     (outputs.getA2dpOutput() != 0)) { | 
 | 421 |                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; | 
 | 422 |                 if (device) break; | 
 | 423 |             } | 
 | 424 |             if (!isInCall()) { | 
 | 425 |                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY; | 
 | 426 |                 if (device) break; | 
 | 427 |                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE; | 
 | 428 |                 if (device) break; | 
 | 429 |                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; | 
 | 430 |                 if (device) break; | 
 | 431 |                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL; | 
 | 432 |                 if (device) break; | 
 | 433 |                 device = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; | 
 | 434 |                 if (device) break; | 
 | 435 |             } | 
 | 436 |             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE; | 
 | 437 |             if (device) break; | 
 | 438 |             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER; | 
 | 439 |             if (device) break; | 
 | 440 |             device = mApmObserver->getDefaultOutputDevice()->type(); | 
 | 441 |             if (device == AUDIO_DEVICE_NONE) { | 
 | 442 |                 ALOGE("getDeviceForStrategy() no device found for STRATEGY_PHONE, FORCE_SPEAKER"); | 
 | 443 |             } | 
 | 444 |             break; | 
 | 445 |         } | 
 | 446 |     break; | 
 | 447 |  | 
 | 448 |     case STRATEGY_SONIFICATION: | 
 | 449 |  | 
 | 450 |         // If incall, just select the STRATEGY_PHONE device: The rest of the behavior is handled by | 
 | 451 |         // handleIncallSonification(). | 
 | 452 |         if (isInCall()) { | 
 | 453 |             device = getDeviceForStrategy(STRATEGY_PHONE); | 
 | 454 |             break; | 
 | 455 |         } | 
 | 456 |         // FALL THROUGH | 
 | 457 |  | 
 | 458 |     case STRATEGY_ENFORCED_AUDIBLE: | 
 | 459 |         // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION | 
 | 460 |         // except: | 
 | 461 |         //   - when in call where it doesn't default to STRATEGY_PHONE behavior | 
 | 462 |         //   - in countries where not enforced in which case it follows STRATEGY_MEDIA | 
 | 463 |  | 
 | 464 |         if ((strategy == STRATEGY_SONIFICATION) || | 
 | 465 |                 (mForceUse[AUDIO_POLICY_FORCE_FOR_SYSTEM] == AUDIO_POLICY_FORCE_SYSTEM_ENFORCED)) { | 
 | 466 |             device = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER; | 
 | 467 |             if (device == AUDIO_DEVICE_NONE) { | 
 | 468 |                 ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION"); | 
 | 469 |             } | 
 | 470 |         } | 
 | 471 |         // The second device used for sonification is the same as the device used by media strategy | 
 | 472 |         // FALL THROUGH | 
 | 473 |  | 
 | 474 |     // FIXME: STRATEGY_ACCESSIBILITY and STRATEGY_REROUTING follow STRATEGY_MEDIA for now | 
 | 475 |     case STRATEGY_ACCESSIBILITY: | 
 | 476 |         if (strategy == STRATEGY_ACCESSIBILITY) { | 
 | 477 |             // do not route accessibility prompts to a digital output currently configured with a | 
 | 478 |             // compressed format as they would likely not be mixed and dropped. | 
 | 479 |             for (size_t i = 0; i < outputs.size(); i++) { | 
 | 480 |                 sp<AudioOutputDescriptor> desc = outputs.valueAt(i); | 
 | 481 |                 audio_devices_t devices = desc->device() & | 
 | 482 |                     (AUDIO_DEVICE_OUT_HDMI | AUDIO_DEVICE_OUT_SPDIF | AUDIO_DEVICE_OUT_HDMI_ARC); | 
 | 483 |                 if (desc->isActive() && !audio_is_linear_pcm(desc->mFormat) && | 
 | 484 |                         devices != AUDIO_DEVICE_NONE) { | 
 | 485 |                     availableOutputDevicesType = availableOutputDevices.types() & ~devices; | 
 | 486 |                 } | 
 | 487 |             } | 
 | 488 |         } | 
 | 489 |         // FALL THROUGH | 
 | 490 |  | 
 | 491 |     case STRATEGY_REROUTING: | 
 | 492 |     case STRATEGY_MEDIA: { | 
 | 493 |         uint32_t device2 = AUDIO_DEVICE_NONE; | 
 | 494 |         if (strategy != STRATEGY_SONIFICATION) { | 
 | 495 |             // no sonification on remote submix (e.g. WFD) | 
 | 496 |             if (availableOutputDevices.getDevice(AUDIO_DEVICE_OUT_REMOTE_SUBMIX, String8("0")) != 0) { | 
 | 497 |                 device2 = availableOutputDevices.types() & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; | 
 | 498 |             } | 
 | 499 |         } | 
 | 500 |         if ((device2 == AUDIO_DEVICE_NONE) && | 
 | 501 |                 (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] != AUDIO_POLICY_FORCE_NO_BT_A2DP) && | 
 | 502 |                 (outputs.getA2dpOutput() != 0)) { | 
 | 503 |             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; | 
 | 504 |             if (device2 == AUDIO_DEVICE_NONE) { | 
 | 505 |                 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; | 
 | 506 |             } | 
 | 507 |             if (device2 == AUDIO_DEVICE_NONE) { | 
 | 508 |                 device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; | 
 | 509 |             } | 
 | 510 |         } | 
 | 511 |         if ((device2 == AUDIO_DEVICE_NONE) && | 
 | 512 |             (mForceUse[AUDIO_POLICY_FORCE_FOR_MEDIA] == AUDIO_POLICY_FORCE_SPEAKER)) { | 
 | 513 |             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER; | 
 | 514 |         } | 
 | 515 |         if (device2 == AUDIO_DEVICE_NONE) { | 
 | 516 |             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; | 
 | 517 |         } | 
 | 518 |         if ((device2 == AUDIO_DEVICE_NONE)) { | 
 | 519 |             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_LINE; | 
 | 520 |         } | 
 | 521 |         if (device2 == AUDIO_DEVICE_NONE) { | 
 | 522 |             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_WIRED_HEADSET; | 
 | 523 |         } | 
 | 524 |         if (device2 == AUDIO_DEVICE_NONE) { | 
 | 525 |             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_ACCESSORY; | 
 | 526 |         } | 
 | 527 |         if (device2 == AUDIO_DEVICE_NONE) { | 
 | 528 |             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_USB_DEVICE; | 
 | 529 |         } | 
 | 530 |         if (device2 == AUDIO_DEVICE_NONE) { | 
 | 531 |             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; | 
 | 532 |         } | 
 | 533 |         if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) { | 
 | 534 |             // no sonification on aux digital (e.g. HDMI) | 
 | 535 |             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_DIGITAL; | 
 | 536 |         } | 
 | 537 |         if ((device2 == AUDIO_DEVICE_NONE) && | 
 | 538 |                 (mForceUse[AUDIO_POLICY_FORCE_FOR_DOCK] == AUDIO_POLICY_FORCE_ANALOG_DOCK)) { | 
 | 539 |             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; | 
 | 540 |         } | 
 | 541 |         if (device2 == AUDIO_DEVICE_NONE) { | 
 | 542 |             device2 = availableOutputDevicesType & AUDIO_DEVICE_OUT_SPEAKER; | 
 | 543 |         } | 
 | 544 |         int device3 = AUDIO_DEVICE_NONE; | 
 | 545 |         if (strategy == STRATEGY_MEDIA) { | 
 | 546 |             // ARC, SPDIF and AUX_LINE can co-exist with others. | 
 | 547 |             device3 = availableOutputDevicesType & AUDIO_DEVICE_OUT_HDMI_ARC; | 
 | 548 |             device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_SPDIF); | 
 | 549 |             device3 |= (availableOutputDevicesType & AUDIO_DEVICE_OUT_AUX_LINE); | 
 | 550 |         } | 
 | 551 |  | 
 | 552 |         device2 |= device3; | 
 | 553 |         // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or | 
 | 554 |         // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise | 
 | 555 |         device |= device2; | 
 | 556 |  | 
 | 557 |         // If hdmi system audio mode is on, remove speaker out of output list. | 
 | 558 |         if ((strategy == STRATEGY_MEDIA) && | 
 | 559 |             (mForceUse[AUDIO_POLICY_FORCE_FOR_HDMI_SYSTEM_AUDIO] == | 
 | 560 |                 AUDIO_POLICY_FORCE_HDMI_SYSTEM_AUDIO_ENFORCED)) { | 
 | 561 |             device &= ~AUDIO_DEVICE_OUT_SPEAKER; | 
 | 562 |         } | 
 | 563 |  | 
 | 564 |         if (device) break; | 
 | 565 |         device = mApmObserver->getDefaultOutputDevice()->type(); | 
 | 566 |         if (device == AUDIO_DEVICE_NONE) { | 
 | 567 |             ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA"); | 
 | 568 |         } | 
 | 569 |         } break; | 
 | 570 |  | 
 | 571 |     default: | 
 | 572 |         ALOGW("getDeviceForStrategy() unknown strategy: %d", strategy); | 
 | 573 |         break; | 
 | 574 |     } | 
 | 575 |  | 
 | 576 |     ALOGVV("getDeviceForStrategy() strategy %d, device %x", strategy, device); | 
 | 577 |     return device; | 
 | 578 | } | 
 | 579 |  | 
 | 580 |  | 
 | 581 | audio_devices_t Engine::getDeviceForInputSource(audio_source_t inputSource) const | 
 | 582 | { | 
 | 583 |     const DeviceVector &availableOutputDevices = mApmObserver->getAvailableOutputDevices(); | 
 | 584 |     const DeviceVector &availableInputDevices = mApmObserver->getAvailableInputDevices(); | 
 | 585 |     const AudioOutputCollection &outputs = mApmObserver->getOutputs(); | 
 | 586 |     audio_devices_t availableDeviceTypes = availableInputDevices.types() & ~AUDIO_DEVICE_BIT_IN; | 
 | 587 |  | 
 | 588 |     uint32_t device = AUDIO_DEVICE_NONE; | 
 | 589 |  | 
 | 590 |     switch (inputSource) { | 
 | 591 |     case AUDIO_SOURCE_VOICE_UPLINK: | 
 | 592 |       if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) { | 
 | 593 |           device = AUDIO_DEVICE_IN_VOICE_CALL; | 
 | 594 |           break; | 
 | 595 |       } | 
 | 596 |       break; | 
 | 597 |  | 
 | 598 |     case AUDIO_SOURCE_DEFAULT: | 
 | 599 |     case AUDIO_SOURCE_MIC: | 
 | 600 |     if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_A2DP) { | 
 | 601 |         device = AUDIO_DEVICE_IN_BLUETOOTH_A2DP; | 
 | 602 |     } else if ((mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO) && | 
 | 603 |         (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET)) { | 
 | 604 |         device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; | 
 | 605 |     } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) { | 
 | 606 |         device = AUDIO_DEVICE_IN_WIRED_HEADSET; | 
 | 607 |     } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { | 
 | 608 |         device = AUDIO_DEVICE_IN_USB_DEVICE; | 
 | 609 |     } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { | 
 | 610 |         device = AUDIO_DEVICE_IN_BUILTIN_MIC; | 
 | 611 |     } | 
 | 612 |     break; | 
 | 613 |  | 
 | 614 |     case AUDIO_SOURCE_VOICE_COMMUNICATION: | 
 | 615 |         // Allow only use of devices on primary input if in call and HAL does not support routing | 
 | 616 |         // to voice call path. | 
 | 617 |         if ((getPhoneState() == AUDIO_MODE_IN_CALL) && | 
 | 618 |                 (availableOutputDevices.types() & AUDIO_DEVICE_OUT_TELEPHONY_TX) == 0) { | 
 | 619 |             sp<AudioOutputDescriptor> primaryOutput = outputs.getPrimaryOutput(); | 
 | 620 |             availableDeviceTypes = | 
 | 621 |                     availableInputDevices.getDevicesFromHwModule(primaryOutput->getModuleHandle()) | 
 | 622 |                     & ~AUDIO_DEVICE_BIT_IN; | 
 | 623 |         } | 
 | 624 |  | 
 | 625 |         switch (mForceUse[AUDIO_POLICY_FORCE_FOR_COMMUNICATION]) { | 
 | 626 |         case AUDIO_POLICY_FORCE_BT_SCO: | 
 | 627 |             // if SCO device is requested but no SCO device is available, fall back to default case | 
 | 628 |             if (availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { | 
 | 629 |                 device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; | 
 | 630 |                 break; | 
 | 631 |             } | 
 | 632 |             // FALL THROUGH | 
 | 633 |  | 
 | 634 |         default:    // FORCE_NONE | 
 | 635 |             if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) { | 
 | 636 |                 device = AUDIO_DEVICE_IN_WIRED_HEADSET; | 
 | 637 |             } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { | 
 | 638 |                 device = AUDIO_DEVICE_IN_USB_DEVICE; | 
 | 639 |             } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { | 
 | 640 |                 device = AUDIO_DEVICE_IN_BUILTIN_MIC; | 
 | 641 |             } | 
 | 642 |             break; | 
 | 643 |  | 
 | 644 |         case AUDIO_POLICY_FORCE_SPEAKER: | 
 | 645 |             if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) { | 
 | 646 |                 device = AUDIO_DEVICE_IN_BACK_MIC; | 
 | 647 |             } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { | 
 | 648 |                 device = AUDIO_DEVICE_IN_BUILTIN_MIC; | 
 | 649 |             } | 
 | 650 |             break; | 
 | 651 |         } | 
 | 652 |         break; | 
 | 653 |  | 
 | 654 |     case AUDIO_SOURCE_VOICE_RECOGNITION: | 
 | 655 |     case AUDIO_SOURCE_HOTWORD: | 
 | 656 |         if (mForceUse[AUDIO_POLICY_FORCE_FOR_RECORD] == AUDIO_POLICY_FORCE_BT_SCO && | 
 | 657 |                 availableDeviceTypes & AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET) { | 
 | 658 |             device = AUDIO_DEVICE_IN_BLUETOOTH_SCO_HEADSET; | 
 | 659 |         } else if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET) { | 
 | 660 |             device = AUDIO_DEVICE_IN_WIRED_HEADSET; | 
 | 661 |         } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { | 
 | 662 |             device = AUDIO_DEVICE_IN_USB_DEVICE; | 
 | 663 |         } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { | 
 | 664 |             device = AUDIO_DEVICE_IN_BUILTIN_MIC; | 
 | 665 |         } | 
 | 666 |         break; | 
 | 667 |     case AUDIO_SOURCE_CAMCORDER: | 
 | 668 |         if (availableDeviceTypes & AUDIO_DEVICE_IN_BACK_MIC) { | 
 | 669 |             device = AUDIO_DEVICE_IN_BACK_MIC; | 
 | 670 |         } else if (availableDeviceTypes & AUDIO_DEVICE_IN_BUILTIN_MIC) { | 
 | 671 |             device = AUDIO_DEVICE_IN_BUILTIN_MIC; | 
 | 672 |         } | 
 | 673 |         break; | 
 | 674 |     case AUDIO_SOURCE_VOICE_DOWNLINK: | 
 | 675 |     case AUDIO_SOURCE_VOICE_CALL: | 
 | 676 |         if (availableDeviceTypes & AUDIO_DEVICE_IN_VOICE_CALL) { | 
 | 677 |             device = AUDIO_DEVICE_IN_VOICE_CALL; | 
 | 678 |         } | 
 | 679 |         break; | 
 | 680 |     case AUDIO_SOURCE_REMOTE_SUBMIX: | 
 | 681 |         if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX) { | 
 | 682 |             device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; | 
 | 683 |         } | 
 | 684 |         break; | 
 | 685 |      case AUDIO_SOURCE_FM_TUNER: | 
 | 686 |         if (availableDeviceTypes & AUDIO_DEVICE_IN_FM_TUNER) { | 
 | 687 |             device = AUDIO_DEVICE_IN_FM_TUNER; | 
 | 688 |         } | 
 | 689 |         break; | 
 | 690 |     default: | 
 | 691 |         ALOGW("getDeviceForInputSource() invalid input source %d", inputSource); | 
 | 692 |         break; | 
 | 693 |     } | 
 | 694 |     ALOGV("getDeviceForInputSource()input source %d, device %08x", inputSource, device); | 
 | 695 |     return device; | 
 | 696 | } | 
 | 697 |  | 
 | 698 | template <> | 
 | 699 | AudioPolicyManagerInterface *Engine::queryInterface() | 
 | 700 | { | 
 | 701 |     return &mManagerInterface; | 
 | 702 | } | 
 | 703 |  | 
 | 704 | } // namespace audio_policy | 
 | 705 | } // namespace android | 
 | 706 |  | 
 | 707 |  |