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) {
AudioFlingerClient();
} else {
if (gAudioErrorCallback) {
gAudioErrorCallback(NO_ERROR);
}
}
binder->linkToDeath(gAudioFlingerClient);
gAudioFlinger = interface_cast<IAudioFlinger>(binder);
LOG_ALWAYS_FATAL_IF(gAudioFlinger == 0);
afc = gAudioFlingerClient;
}
gAudioFlinger;
}
if (afc != 0) {
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) {
AudioPolicyServiceClient();
}
binder->linkToDeath(gAudioPolicyServiceClient);
gAudioPolicyService = interface_cast<IAudioPolicyService>(binder);
LOG_ALWAYS_FATAL_IF(gAudioPolicyService == 0);
apc = gAudioPolicyServiceClient;
}
gAudioPolicyService;
}
if (apc != 0) {
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
if (cb != null) {
cb.onError(checkAudioFlinger());
}
}
}
|
errorCallbackFromNative(int error)
{
ErrorCallback errorCallback = null;
synchronized (AudioSystem.class) {
if (mErrorCallback != null) {
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
}
|
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;
|
这两个类具体的代码分析会穿插在其他的业务流程里面。