说明:作为学习的笔记,可能有不少的错误
调用关系:
1.从上往下涉及的主要代码文件如下:
1) AudioManager.java
2) AudioService.java
3) AudioSystem.java
4) AudioSystem.cpp
5) audioFlinger ….
6) audio policy
2.
以调节音量方法为例,进行分析。adjustStreamVolume()
1) AudioManager ,这也是APK直接接触到的接口,APP通过调用调用AudioManager的方法,来设置声音相关的操作。
2)
a) 构造函数,会读取内部的默认配置,从XML文件中获取。
<pre name="code" class="java">
public AudioManager(Context context) {
mContext = context;
mUseMasterVolume = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_useMasterVolume);
mUseVolumeKeySounds = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_useVolumeKeySounds);
mAudioPortEventHandler = new AudioPortEventHandler(this);
mUseFixedVolume = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_useFixedVolume);
}
b) 通过 IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE); 获取audioService 服务,AudioService 和AudioManager通过aidl接口进行通信的。
private static IAudioService getService()
{
if (sService != null) {
return sService;
}
IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
sService = IAudioService.Stub.asInterface(b);
return sService;
}
c) AudioService 继承了 IAudioService.Stub,
public class AudioService extends IAudioService.Stub {
d) 再来看设置音量的方法setMasterVolume, 由于上上面通过getService获取到audioService,这里就可以同过service.setMasterVolume的方法去设置音量。
public void setMasterVolume(int index, int flags) {
IAudioService service = getService();
try {
service.setMasterVolume(index, flags, mContext.getOpPackageName());
} catch (RemoteException e) {
Log.e(TAG, "Dead object in setMasterVolume", e);
}
}
e) IAudioService.aidl
AIDL 全称为android interface definition language ,
它是一种android内部进程通信接口的描述语言,通过它我们可以定义进程间的通信接口
f)setMasterVolume()
public void setMasterVolume(int volume, int flags, String callingPackage) {
if (mUseFixedVolume) {
return;
}
if (mAppOps.noteOp(AppOpsManager.OP_AUDIO_MASTER_VOLUME, Binder.getCallingUid(),
callingPackage) != AppOpsManager.MODE_ALLOWED) {
return;
}
if (volume < 0) {
volume = 0;
} else if (volume > MAX_MASTER_VOLUME) {
volume = MAX_MASTER_VOLUME;
}
doSetMasterVolume((float)volume / MAX_MASTER_VOLUME, flags);
}
g) doSetMasterVolume () 主要做了三件事。1) 调用AudioSystem,java类中的设置音频的方法 2) 发送MSG_PERSIST_MASTER_VOLUME 消息到mAudioHandler
3)发送音量更新的广播sendMasterVolumeUpdate, 一个是会更新UI,还有就是更新音量的消息广播到所有应用(看源代码说明只有预装的APP才能收到广播。)
private void doSetMasterVolume(float volume, int flags) {
// don't allow changing master volume when muted
if (!AudioSystem.getMasterMute()) {
int oldVolume = getMasterVolume();
<span style="color:#ff0000;"> AudioSystem.setMasterVolume(volume);</span>
int newVolume = getMasterVolume();
if (newVolume != oldVolume) {
// Post a persist master volume msg
sendMsg(mAudioHandler, MSG_PERSIST_MASTER_VOLUME, SENDMSG_REPLACE,
Math.round(volume * (float)1000.0), 0, null, PERSIST_DELAY);
}
// Send the volume update regardless whether there was a change.
sendMasterVolumeUpdate(flags, oldVolume, newVolume);
}
}
h) AudioSystem.java
未完待续。。。