AudioSystem在audio框架中的关系和位置如图所示,
AudioSystem提供native接口,通过jni访问native提供的audio功能,在native层,有一个对应的AudioSystem.cpp文件
Jave层主要功能清单可见代码。
这里定义了音频流的类型、输入输出器件类型等。
对于比较复杂的,如音频输入输出器件的名称如下,
输出设备: 1. DEVICE_OUT_EARPIECE : 听筒 2. 3. DEVICE_OUT_SPEAKER : 扬声器 4. 5. DEVICE_OUT_WIRED_HEADSET : 带话筒的耳机 6. DEVICE_OUT_WIRED_HEADPHONE : 不带话筒的耳机 7. 8. DEVICE_OUT_BLUETOOTH_SCO : 蓝牙.面向连接(SCO)方式:主要用于话音传输 9. DEVICE_OUT_BLUETOOTH_SCO_HEADSET : 蓝牙耳机,带话筒 10. DEVICE_OUT_BLUETOOTH_SCO_CARKIT : 蓝牙车载设备 11. DEVICE_OUT_BLUETOOTH_A2DP : 蓝牙立体声 12. DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES: 蓝牙立体声音耳机 13. DEVICE_OUT_BLUETOOTH_A2DP_SPEAKER : 带话筒的 14. 15. DEVICE_OUT_AUX_DIGITAL : 16. DEVICE_OUT_ANLG_DOCK_HEADSET : 通过基座连接的模拟有线耳机 17. DEVICE_OUT_DGTL_DOCK_HEADSET : 通过基座连接的数字有线耳机 18. DEVICE_OUT_FM_HEADPHONE : FM 耳机 19. DEVICE_OUT_FM_SPEAKER :FM 扬声器 20. DEVICE_OUT_SPEAKER_SSPA2 21. DEVICE_OUT_HDMI : HDMI接口 22. DEVICE_OUT_FM_TRANSMITTER
输入设备 1. DEVICE_IN_COMMUNICATION : 手机上的话筒 2. DEVICE_IN_AMBIENT : 3. DEVICE_IN_BUILTIN_MIC : 蓝牙麦克 4. DEVICE_IN_BLUETOOTH_SCO_HEADSET : 蓝牙耳机上的话筒 5. DEVICE_IN_WIRED_HEADSET : 有线耳机上的话筒 6. DEVICE_IN_AUX_DIGITAL : 7. DEVICE_IN_VOICE_CALL : 通话中 8. DEVICE_IN_BACK_MIC : 9. DEVICE_IN_VT_MIC : 10. DEVICE_IN_FMRADIO : FM的输入
|
在native层,AudioSystem主要和AF、APS交互,通过下面几个对象、client和回调,完成向上向下的连接,
sp<IAudioFlinger> AudioSystem::gAudioFlinger; sp<AudioSystem::AudioFlingerClient> AudioSystem::gAudioFlingerClient; audio_error_callback AudioSystem::gAudioErrorCallback = NULL; dynamic_policy_callback AudioSystem::gDynPolicyCallback = NULL; record_config_callback AudioSystem::gRecordConfigCallback = NULL;
sp<IAudioPolicyService> AudioSystem::gAudioPolicyService; sp<AudioSystem::AudioPolicyServiceClient> AudioSystem::gAudioPolicyServiceClient; |
通过get_audio_flinger,获取AF的服务引用,并创建AFC,促发回调,之后便可以通过af的引用使用AF的服务了,对于AF向上的通知,可以使用client实现,AS的向上通知使用callback。
const sp<IAudioFlinger> AudioSystem::get_audio_flinger() { sp<IAudioFlinger> af; sp<AudioFlingerClient> afc; { Mutex::Autolock _l(gLock); if (gAudioFlinger == 0) { sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> binder; do { binder = sm->getService(String16("media.audio_flinger")); if (binder != 0) break; ALOGW("AudioFlinger not published, waiting..."); usleep(500000); // 0.5 s } while (true); if (gAudioFlingerClient == NULL) { gAudioFlingerClient = new AudioFlingerClient(); } else { if (gAudioErrorCallback) { gAudioErrorCallback(NO_ERROR); } } binder->linkToDeath(gAudioFlingerClient); gAudioFlinger = interface_cast<IAudioFlinger>(binder); LOG_ALWAYS_FATAL_IF(gAudioFlinger == 0); afc = gAudioFlingerClient; } af = gAudioFlinger; } if (afc != 0) { af->registerClient(afc); } return af; } |
通过get_audio_policy_service,获取APS的服务引用,并创建APSC,之后便可以通过af的引用使用APS的服务了,对于APS向上的通知,可以使用client实现。
const sp<IAudioPolicyService> AudioSystem::get_audio_policy_service() { sp<IAudioPolicyService> ap; sp<AudioPolicyServiceClient> apc; { Mutex::Autolock _l(gLockAPS); if (gAudioPolicyService == 0) { sp<IServiceManager> sm = defaultServiceManager(); sp<IBinder> binder; do { binder = sm->getService(String16("media.audio_policy")); if (binder != 0) break; ALOGW("AudioPolicyService not published, waiting..."); usleep(500000); // 0.5 s } while (true); if (gAudioPolicyServiceClient == NULL) { gAudioPolicyServiceClient = new AudioPolicyServiceClient(); } binder->linkToDeath(gAudioPolicyServiceClient); gAudioPolicyService = interface_cast<IAudioPolicyService>(binder); LOG_ALWAYS_FATAL_IF(gAudioPolicyService == 0); apc = gAudioPolicyServiceClient; } ap = gAudioPolicyService; } if (apc != 0) { ap->registerClient(apc); }
return ap; } |
AudioFlingerClient和AudioPolicyServiceClient的定义都在AudioSystem.h,实现在AudioSystem.c里面。
对于AudioFlingerClient,首先是向AF注册,AF内创建NotificationClient对象,添加到其内部队列,最后AF的player/recorder线程向其客户端发送通道打开事件。
void AudioFlinger::registerClient(const sp<IAudioFlingerClient>& client) { Mutex::Autolock _l(mLock); if (client == 0) { return; } pid_t pid = IPCThreadState::self()->getCallingPid(); { Mutex::Autolock _cl(mClientLock); if (mNotificationClients.indexOfKey(pid) < 0) { sp<NotificationClient> notificationClient = new NotificationClient(this, client, pid); ALOGV("registerClient() client %p, pid %d", notificationClient.get(), pid);
mNotificationClients.add(pid, notificationClient);
sp<IBinder> binder = IInterface::asBinder(client); binder->linkToDeath(notificationClient); } }
for (size_t i = 0; i < mPlaybackThreads.size(); i++) { mPlaybackThreads.valueAt(i)->sendIoConfigEvent(AUDIO_OUTPUT_OPENED, pid); }
for (size_t i = 0; i < mRecordThreads.size(); i++) { mRecordThreads.valueAt(i)->sendIoConfigEvent(AUDIO_INPUT_OPENED, pid); } } |
事件上,AF通过AFC的方式向AS传递事件使用得并不多,这可以通过mNotificationClients和NotificationClient. mAudioFlingerClient看出,所以这并不是一个主要流程。
AudioSystem的setErrorCallback的简单分析,
应用通过setErrorCallback,向java注册自己的回调函数,
private final CameraErrorCallback mCameraErrorCallback = new CameraErrorCallback();
private final class CameraErrorCallback implements android.hardware.Camera.ErrorCallback { public void onError(int error, android.hardware.Camera camera) { Assert.fail(String.format("Camera error, code: %d", error)); } } |
Java framework里,errorCallbackFromNative将native的状态回调转给应用的监听回调,根据java的逻辑,每个应用进入时必须设置自己的回调,退出可以清空,不保证在后台可以适合回调,因为这里不支持多用户,只支持最新设置的回调。
public static void setErrorCallback(ErrorCallback cb) { synchronized (AudioSystem.class) { mErrorCallback = cb; if (cb != null) { cb.onError(checkAudioFlinger()); } } } |
private static void errorCallbackFromNative(int error) { ErrorCallback errorCallback = null; synchronized (AudioSystem.class) { if (mErrorCallback != null) { errorCallback = mErrorCallback; } } if (errorCallback != null) { errorCallback.onError(error); } } |
在jni层,android_media_AudioSystem_error_callback调用java的errorCallbackFromNative,
static void android_media_AudioSystem_error_callback(status_t err) { JNIEnv *env = AndroidRuntime::getJNIEnv(); if (env == NULL) { return; }
jclass clazz = env->FindClass(kClassPathName);
env->CallStaticVoidMethod(clazz, env->GetStaticMethodID(clazz, "errorCallbackFromNative","(I)V"), check_AudioSystem_Command(err));
env->DeleteLocalRef(clazz); } |
向native注册
AudioSystem::setErrorCallback(android_media_AudioSystem_error_callback); |
Native层,AudioSystem.cpp里,gAudioErrorCallback被设置和回调的地方如下,可见该回调目前只在AF服务获取成功和AFC解除绑定才会使用,即当前这个回调实际并没什么用。
/* static */ void AudioSystem::setErrorCallback(audio_error_callback cb) { Mutex::Autolock _l(gLock); gAudioErrorCallback = cb; } |
const sp<IAudioFlinger> AudioSystem::get_audio_flinger() { … if (gAudioErrorCallback) { gAudioErrorCallback(NO_ERROR); } |
void AudioSystem::AudioFlingerClient::binderDied(const wp<IBinder>& who __unused) { cb = gAudioErrorCallback; … if (cb) { cb(DEAD_OBJECT); } … |
AudioManager类提供audio相关的控制接口,包括音量设置、通道控制、音频焦点控制、音效设置、参数设置、振铃模式等等。使用Context.getSystemService(Context.AUDIO_SERVICE)来得到这个类的一个实例。
在应用侧,如下,只需获取服务实例,就可以使用服务接口了。
private AudioManager aManger; aManger = (AudioManager) getSystemService(Service.AUDIO_SERVICE);
aManger.adjustStreamVolume(AudioManager.STREAM_MUSIC, AudioManager.ADJUST_LOWER, AudioManager.FLAG_SHOW_UI);
|
AudioManager只是一个功能的接口类和封装类,其功能主要是由AudioService和AudioSystem完成的,通过IAudioService sService和AudioSystem 调用功能的方法。
private static IAudioService sService;
private static IAudioService getService() { if (sService != null) { return sService; } IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE); sService = IAudioService.Stub.asInterface(b); return sService; }
public boolean isMicrophoneMute() { return AudioSystem.isMicrophoneMuted(); } |
AudioService是java层的Audio服务类,在SystemServer里被启动,之后就可以被应用使用。
private void startOtherServices() { … traceBeginAndSlog("StartAudioService"); mSystemServiceManager.startService(AudioService.Lifecycle.class); Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
|
AudioService extendsIAudioService.Stub,它内部有handler、callback、receiver来维护整个服务的运行,再借助AudioSystem、BT、Soundpoll、mediaplayer、mediaRecorder等中间类,实现audio的功能。
public class AudioService extends IAudioService.Stub { /** @see AudioSystemThread */ private AudioSystemThread mAudioSystemThread; /** @see AudioHandler */ private AudioHandler mAudioHandler;
private final BroadcastReceiver mReceiver = new AudioServiceBroadcastReceiver();
// BluetoothHeadset API to control SCO connection private BluetoothHeadset mBluetoothHeadset;
// Bluetooth headset device private BluetoothDevice mBluetoothHeadsetDevice;
private volatile IRingtonePlayer mRingtonePlayer;
private final MediaFocusControl mMediaFocusControl;
private SoundPool mSoundPool;
|
要清楚的几个概念,
Mode:设置电话音频状态的模式
/* modes for setPhoneState, must match AudioSystem.h audio_mode */ public static final int MODE_INVALID = -2; public static final int MODE_CURRENT = -1; public static final int MODE_NORMAL = 0; public static final int MODE_RINGTONE = 1; public static final int MODE_IN_CALL = 2; public static final int MODE_IN_COMMUNICATION = 3; public static final int NUM_MODES = 4; |
音量:分不同stream类型设置音量大小
/* The default audio stream */ public static final int STREAM_DEFAULT = -1; /* The audio stream for phone calls */ public static final int STREAM_VOICE_CALL = 0; /* The audio stream for system sounds */ public static final int STREAM_SYSTEM = 1; /* The audio stream for the phone ring and message alerts */ public static final int STREAM_RING = 2; /* The audio stream for music playback */ public static final int STREAM_MUSIC = 3; /* The audio stream for alarms */ public static final int STREAM_ALARM = 4; /* The audio stream for notifications */ public static final int STREAM_NOTIFICATION = 5; /* @hide The audio stream for phone calls when connected on bluetooth */ public static final int STREAM_BLUETOOTH_SCO = 6; /* @hide The audio stream for enforced system sounds in certain countries (e.g camera in Japan) */ public static final int STREAM_SYSTEM_ENFORCED = 7; /* @hide The audio stream for DTMF tones */ public static final int STREAM_DTMF = 8; /* @hide The audio stream for text to speech (TTS) */ public static final int STREAM_TTS = 9; |
这两个类具体的代码分析会穿插在其他的业务流程里面。