标签:
在某些国家(比如Japan),为了防止偷拍,强制拍照声是需要从Speaker出来的(即使插入耳机的情况下)。
实现该功能比较简单的方法就是将拍照声类型设置为Ringtone 或 Alarm 或 Notification类型,这样在AudioPolicyManager.cpp中device选择时就会将Speaker设为output device。
还有一种方式就是设置拍照声为ENFORCED_AUDIBLE,该类型音频流的类型解释:
ENFORCED_AUDIBLE = 7, // Sounds that cannot be muted by user and must be routed to speaker
该解释应该就是说这类型的声音不能被静音,而且必须从speaker出来。
但是仅仅将音频流类型设置为ENFORCED_AUDIBLE,并不能保证声音从speaker出来,从AudioPolicyManager.cpp里逻辑里看:
case STRATEGY_ENFORCED_AUDIBLE: // strategy STRATEGY_ENFORCED_AUDIBLE uses same routing policy as STRATEGY_SONIFICATION // except: // - when in call where it doesn‘t default to STRATEGY_PHONE behavior // - in countries where not enforced in which case it follows STRATEGY_MEDIA if ((strategy == STRATEGY_SONIFICATION) || (mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_SYSTEM_ENFORCED)) { device = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; if (device == AUDIO_DEVICE_NONE) { ALOGE("getDeviceForStrategy() speaker device not found for STRATEGY_SONIFICATION"); } } // The second device used for sonification is the same as the device used by media strategy // FALL THROUGH case STRATEGY_MEDIA: { uint32_t device2 = AUDIO_DEVICE_NONE; if (strategy != STRATEGY_SONIFICATION) { // no sonification on remote submix (e.g. WFD) device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_REMOTE_SUBMIX; } if ((device2 == AUDIO_DEVICE_NONE) && mHasA2dp && (mForceUse[AudioSystem::FOR_MEDIA] != AudioSystem::FORCE_NO_BT_A2DP) && (getA2dpOutput() != 0) && !mA2dpSuspended) { device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP; if (device2 == AUDIO_DEVICE_NONE) { device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES; } if (device2 == AUDIO_DEVICE_NONE) { device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER; } } if (device2 == AUDIO_DEVICE_NONE) { device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADPHONE; } if (device2 == AUDIO_DEVICE_NONE) { device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_WIRED_HEADSET; } if (device2 == AUDIO_DEVICE_NONE) { device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_ACCESSORY; } if (device2 == AUDIO_DEVICE_NONE) { device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_USB_DEVICE; } if (device2 == AUDIO_DEVICE_NONE) { device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_DGTL_DOCK_HEADSET; } if ((device2 == AUDIO_DEVICE_NONE) && (strategy != STRATEGY_SONIFICATION)) { // no sonification on aux digital (e.g. HDMI) device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_AUX_DIGITAL; } if ((device2 == AUDIO_DEVICE_NONE) && (mForceUse[AudioSystem::FOR_DOCK] == AudioSystem::FORCE_ANALOG_DOCK)) { device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_ANLG_DOCK_HEADSET; } if (device2 == AUDIO_DEVICE_NONE) { device2 = mAvailableOutputDevices & AUDIO_DEVICE_OUT_SPEAKER; } // device is DEVICE_OUT_SPEAKER if we come from case STRATEGY_SONIFICATION or // STRATEGY_ENFORCED_AUDIBLE, AUDIO_DEVICE_NONE otherwise device |= device2; if (device) break; device = mDefaultOutputDevice; if (device == AUDIO_DEVICE_NONE) { ALOGE("getDeviceForStrategy() no device found for STRATEGY_MEDIA"); } } break;
在case STRATEGY_ENFORCED_AUDIBLE中,因为目前(strategy != STRATEGY_SONIFICATION) 所以想要在音频流类型是ENFORCED_AUDIBLE的情况下Speaker还能出声的话,就需要满足:(mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_SYSTEM_ENFORCED),否则就会follow case STRATEGY_MEDIA的device。
而(mForceUse[AudioSystem::FOR_SYSTEM] == AudioSystem::FORCE_SYSTEM_ENFORCED)是在哪边设定的呢?
全局搜索了代码,原来在AudioService初始化时:
boolean cameraSoundForced = mContext.getResources().getBoolean( com.android.internal.R.bool.config_camera_sound_forced); mCameraSoundForced = new Boolean(cameraSoundForced); sendMsg(mAudioHandler, MSG_SET_FORCE_USE, SENDMSG_QUEUE, AudioSystem.FOR_SYSTEM, cameraSoundForced ? AudioSystem.FORCE_SYSTEM_ENFORCED :AudioSystem.FORCE_NONE, null, 0);
所以当cameraSoundForced的值为true时,就会setforceuse(FOR_SYSTEM,FORCE_SYSTEM_ENFORCED);而com.android.internal.R.bool.config_camera_sound_forced是在config.xml中设定的,所以还需要在config.xml档里将config_camera_sound_forced变量设置为true。
标签:
原文地址:http://www.cnblogs.com/Peter-Chen/p/5361427.html