Andorid6.0音量调整(设置)流程

按文件分步骤,代码版本Android6.0.1
1.上层调用AudioManager的接口,要么是setStreamVolume(),要么是按了音量键adjustStreamVolume().
2.AudioService.java:
	1.1分两种情况
	情况一:如果setStreamVolume()--------------------------应用层调用
		(1)setStreamVolume()
			onSetStreamVolume(streamType, index, flags, device, caller);
		(2) onSetStreamVolume()
			setStreamVolumeInt(stream, index, device, false, caller);
		(3)setStreamVolumeInt()
			sendMsg(mAudioHandler,
                        MSG_SET_DEVICE_VOLUME,
                        SENDMSG_QUEUE,
                        device,
                        0,
                        streamState,
                        0);
			mAudioHandler定义:AudioHandler mAudioHandler;
			->case MSG_SET_DEVICE_VOLUME:
                    	setDeviceVolume((VolumeStreamState) msg.obj, msg.arg1);
                    	break;
	情况二:如果adjustStreamVolume()-----------------------------音量键
		直接
		sendMsg(mAudioHandler,
                        MSG_SET_DEVICE_VOLUME,
                        SENDMSG_QUEUE,
                        device,
                        0,
                        streamState,
                        0);
	1.2setDeviceVolume():
		mStreamStates[streamType].applyDeviceVolume_syncVSS(device);
	1.3applyDeviceVolume_syncVSS():
		AudioSystem.setStreamVolumeIndex(mStreamType, index, device);
		这一步中的index值并不是通过msg传递过来的,那么是怎么来的呢?
		public void applyDeviceVolume_syncVSS(int device) {
            			int index;
            			if (mIsMuted) {//静音了
                		index = 0;
            		} else if (((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 && 								mAvrcpAbsVolSupported)//某类蓝牙设备保持在一个固定的音量上(雷柏a3060)
                    		|| ((device & mFullVolumeDevices) != 0)) {//某类可调,比如Leme(乐视蓝牙耳机)
                		index = (mIndexMax + 5)/10;
            		} else {
                		index = (getIndex(device) + 5)/10;
            		}
            		AudioSystem.setStreamVolumeIndex(mStreamType, index, device);
        	}
探讨一下Leme和雷柏a3060的表现不一样的问题
		用adb shell dump研究audio_flinger得知,此时,系统输出的音量db值都是0(即最大音量)。
	调音量是在哪调的呢?
		上代码:
			 if (mA2dp != null && mAvrcpAbsVolSupported) {
                        		mA2dp.setAvrcpAbsoluteVolume(index / 10);
                    }
		结果发现两个设备都会执行到这来,但是再往下jni层,雷柏的返回音量一直是0,其他蓝牙耳机,蓝牙音箱都正常音量值。。。估计雷柏本身支持的不够好了,毕竟设备比较久远,
我们就不深究了。
		至少在这可以得出一个结论:
		手机针对蓝牙音频输出设备的策略是:给你最大音量的输出,要调你自己调,比如这个地方用Avrcp协议去和蓝牙设备进行通讯来调整音量。
		言归正传。很明显。index来自getIndex方法,一路找下去,发现index来自 mIndexMap
	调用顺序:
	情况一:adjustStreamVolume():
	streamState.adjustIndex(direction * step, device, caller)
	setIndex(getIndex(device) + deltaIndex, device, caller);
	mIndexMap.put(device, index);

	情况二:setStreamVolume():
	在前面说到的1.1情况一的 setStreamVolumeInt()函数里index一路通过参数传过来,然后通过
	streamState.setIndex(index, device, caller) 也进行了赋值
	mIndexMap.put(device, index);

	put之后,那边就可以get出来了,不过要注意
		(1)set的地方和get的地方(收到msg之后)是异步的,两个线程.
		(2)setIndex有个参数device。不同device,index是不一样的。
		(3)setIndex里头:
	 		boolean currentDevice = (device == getDeviceForStream(mStreamType));
                    int numStreamTypes = AudioSystem.getNumStreamTypes();
                    for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
                        if (streamType != mStreamType &&
                                mStreamVolumeAlias[streamType] == mStreamType) {
                            int scaledIndex = rescaleIndex(index, mStreamType, streamType);
                            mStreamStates[streamType].setIndex(scaledIndex, device, caller);
				//根据上面的赋值可知,这个变量的意思是,本次调用想设置音量的device对应 						//mStreamType
                            if (currentDevice) {
                                mStreamStates[streamType].setIndex(scaledIndex,
                                        getDeviceForStream(streamType), caller);
                            }
                        }
                    }
		注意这段代码,打日志的话,setIndex会被调用多次。别名一样的也会被同时设置。我自己都没懂这块是什么意思?????????????????懂的人说下
2.AudioSystem.java
		public static native int setStreamVolumeIndex()
这下到ndk层了
3.android_media_AudioSystem.cpp
	android_media_AudioSystem_setStreamVolumeIndex():
		AudioSystem::setStreamVolumeIndex()
4.AudioSystem.cpp
	status_t AudioSystem::setStreamVolumeIndex
	到这层开始返回值变成了status_t这个结构体,虽然我不知道这个结构体在哪定义的,但是这个结构体很常见。
		return aps->setStreamVolumeIndex(stream, index, device);
	aps定义:const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();
	IaudioPolicyService是一个IInterface,我们找到
再往下,实在懒得分析了,等以后的吧!


猜你喜欢

转载自blog.csdn.net/bberdong/article/details/51792319