android 音量设置源码分析

说明:作为学习的笔记,可能有不少的错误

调用关系:

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 

未完待续。。。

    原文作者:Android源码分析
    原文地址: https://blog.csdn.net/u012109245/article/details/52089973
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞