说明:作为学习的笔记,可能有不少的错误
调用关系:
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); }
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); } }
未完待续。。。