1 /* 2 * Copyright (C) 2014 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 "ATVAudioPolicyManager" 18 //#define LOG_NDEBUG 0 19 #include <media/AudioParameter.h> 20 #include <media/mediarecorder.h> 21 #include <utils/Log.h> 22 #include <utils/String16.h> 23 #include <utils/String8.h> 24 #include <utils/StrongPointer.h> 25 26 #include "AudioHardwareOutput.h" 27 #include "ATVAudioPolicyManager.h" 28 29 #ifdef REMOTE_CONTROL_INTERFACE 30 #include <IRemoteControlService.h> 31 #endif 32 33 34 namespace android { 35 extern AudioHardwareOutput gAudioHardwareOutput; 36 37 // ---------------------------------------------------------------------------- 38 // Common audio policy manager code is implemented in AudioPolicyManager class 39 // ---------------------------------------------------------------------------- 40 41 // --- class factory 42 43 44 extern "C" AudioPolicyInterface* createAudioPolicyManager( 45 AudioPolicyClientInterface *clientInterface) 46 { 47 return new ATVAudioPolicyManager(clientInterface); 48 } 49 50 extern "C" void destroyAudioPolicyManager(AudioPolicyInterface *interface) 51 { 52 delete interface; 53 } 54 55 ATVAudioPolicyManager::ATVAudioPolicyManager( 56 AudioPolicyClientInterface *clientInterface) 57 : AudioPolicyManager(clientInterface), mForceSubmixInputSelection(false) 58 { 59 } 60 61 float ATVAudioPolicyManager::computeVolume(audio_stream_type_t stream, 62 int index, 63 audio_devices_t device) 64 { 65 // We only use master volume, so all audio flinger streams 66 // should be set to maximum 67 (void)stream; 68 (void)index; 69 (void)device; 70 return 0.0; // no attenuation == 0.0dB 71 } 72 73 status_t ATVAudioPolicyManager::setDeviceConnectionState(audio_devices_t device, 74 audio_policy_dev_state_t state, 75 const char *device_address, 76 const char *device_name) 77 { 78 audio_devices_t tmp = AUDIO_DEVICE_NONE;; 79 ALOGE("setDeviceConnectionState %08x %x %s", device, state, 80 device_address ? device_address : "(null)"); 81 82 // If the input device is the remote submix and an address starting with "force=" was 83 // specified, enable "force=1" / disable "force=0" the forced selection of the remote submix 84 // input device over hardware input devices (e.g RemoteControl). 85 if (device == AUDIO_DEVICE_IN_REMOTE_SUBMIX && device_address) { 86 AudioParameter parameters = AudioParameter(String8(device_address)); 87 int forceValue; 88 if (parameters.getInt(String8("force"), forceValue) == OK) { 89 mForceSubmixInputSelection = forceValue != 0; 90 } 91 } 92 93 if (audio_is_output_device(device)) { 94 switch (state) { 95 case AUDIO_POLICY_DEVICE_STATE_AVAILABLE: 96 tmp = mAvailableOutputDevices.types() | device; 97 break; 98 99 case AUDIO_POLICY_DEVICE_STATE_UNAVAILABLE: 100 tmp = mAvailableOutputDevices.types() & ~device; 101 break; 102 default: 103 ALOGE("setDeviceConnectionState() invalid state: %x", state); 104 return BAD_VALUE; 105 } 106 107 gAudioHardwareOutput.updateRouting(tmp); 108 tmp = mAvailableOutputDevices.types(); 109 } 110 111 status_t ret = 0; 112 if (device != AUDIO_DEVICE_IN_REMOTE_SUBMIX) { 113 ret = AudioPolicyManager::setDeviceConnectionState( 114 device, state, device_address, device_name); 115 } 116 117 if (audio_is_output_device(device)) { 118 if (tmp != mAvailableOutputDevices.types()) 119 gAudioHardwareOutput.updateRouting(mAvailableOutputDevices.types()); 120 } 121 122 return ret; 123 } 124 125 audio_devices_t ATVAudioPolicyManager::getDeviceForInputSource(audio_source_t inputSource) 126 { 127 uint32_t device = AUDIO_DEVICE_NONE; 128 bool usePhysRemote = true; 129 130 if (inputSource == AUDIO_SOURCE_VOICE_RECOGNITION) { 131 #ifdef REMOTE_CONTROL_INTERFACE 132 // Check if remote is actually connected or we should move on 133 sp<IRemoteControlService> service = IRemoteControlService::getInstance(); 134 if (service == NULL) { 135 ALOGV("getDeviceForInputSource No RemoteControl service detected, ignoring"); 136 usePhysRemote = false; 137 } else if (!service->hasActiveRemote()) { 138 ALOGV("getDeviceForInputSource No active connected device, passing onto submix"); 139 usePhysRemote = false; 140 } 141 #endif 142 ALOGV("getDeviceForInputSource %s %s", usePhysRemote ? "use physical" : "", 143 mForceSubmixInputSelection ? "use virtual" : ""); 144 audio_devices_t availableDeviceTypes = mAvailableInputDevices.types() & 145 ~AUDIO_DEVICE_BIT_IN; 146 if (availableDeviceTypes & AUDIO_DEVICE_IN_WIRED_HEADSET && 147 usePhysRemote) { 148 // User a wired headset (physical remote) if available, connected and active 149 ALOGV("Wired Headset available"); 150 device = AUDIO_DEVICE_IN_WIRED_HEADSET; 151 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_REMOTE_SUBMIX && 152 mForceSubmixInputSelection) { 153 // REMOTE_SUBMIX should always be avaible, let's make sure it's being forced at the moment 154 ALOGV("Virtual remote available"); 155 device = AUDIO_DEVICE_IN_REMOTE_SUBMIX; 156 } else if (availableDeviceTypes & AUDIO_DEVICE_IN_USB_DEVICE) { 157 ALOGV("Use USB audio input"); 158 device = AUDIO_DEVICE_IN_USB_DEVICE; 159 } 160 } 161 162 ALOGV("getDeviceForInputSource() input source %d, device %08x", inputSource, device); 163 return device; 164 } 165 166 } // namespace android 167