分类: Java
2012-06-25 19:23:19
//设置stream音量
mRingVolumePlayer.setStreamVolume(index);
在这里,streamVolume就是我们要设置的音量大小,接着就是调用AudioManager的方法进行设置。
3.AudioManager.java
public void setStreamVolume(int streamType, int index, int flags) {
//IAudioService 是AudioService的本地代理
IAudioService service = getService();
try {
service.setStreamVolume(streamType, index, flags);
} catch (RemoteException e) {
Log.e(TAG, "Dead object in setStreamVolume", e);
}
}
这就开始调用AudioService的相关方法设置音量:streamType假设为STREAM_RING,
flags为FLAG_REMOVE_SOUND_AND_VIBRATE
4.AudioService.java
public void setStreamVolume(int streamType, int index, int flags) {
//获取stream的状态,在AudioService的构造函数中createStreamStates()时创建
VolumeStreamState streamState = mStreamStates[STREAM_VOLUME_ALIAS[streamType]];
//原来stream的音量
final int oldIndex = (streamState.muteCount() != 0) ? streamState.mLastAudibleIndex : streamState.mIndex;
……
//获取stream的音量和最大音量一半的平均值
index = rescaleIndex(index * 10, streamType, STREAM_VOLUME_ALIAS[streamType]);
setStreamVolumeInt(STREAM_VOLUME_ALIAS[streamType], index, false, true);
}
private void setStreamVolumeInt(int streamType, int index, boolean force, boolean lastAudible)
{
VolumeStreamState streamState = mStreamStates[streamType];
//假设没有被静音
if
(streamState.setIndex(index, lastAudible) || force) {
//发送base id为MSG_SET_SYSTEM_VOLUME的msg
sendMsg(mAudioHandler, MSG_SET_SYSTEM_VOLUME, streamType, SENDMSG_NOOP, 0, 0,
streamState, 0);
}
}
//SetIndex实际上就是判断当前的Index和要设置的index是否一致,不同才进行变更
public boolean setIndex(int index, boolean lastAudible) {
int oldIndex = mIndex;
mIndex = getValidIndex(index);
if (oldIndex != mIndex) {
if (lastAudible) {
mLastAudibleIndex = mIndex;
}
// Apply change to all streams using this one as alias
int numStreamTypes = AudioSystem.getNumStreamTypes();
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
if (streamType != mStreamType
&& STREAM_VOLUME_ALIAS[streamType] == mStreamType) {
mStreamStates[streamType].setIndex(rescaleIndex(mIndex, mStreamType, streamType), lastAudible);
}
}
return true;
} else {
return false;
}
}
在处理刚才发送那个Message时:
AudioHandler {
public void handleMessage(Message msg) {
//一般对于内置的stream都是返回0
int baseMsgWhat = getMsgBase(msg.what);
switch (baseMsgWhat) {
case MSG_SET_SYSTEM_VOLUME:
setSystemVolume((VolumeStreamState) msg.obj);
break;
}
}
private void setSystemVolume(VolumeStreamState streamState) {
//这一步调用AudioSystem的方法,再通过JNI对底层直接操作
setStreamVolumeIndex(streamState.mStreamType, streamState.mIndex);
// Apply change to all streams using this one as alias
int numStreamTypes = AudioSystem.getNumStreamTypes();
for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {
if (streamType != streamState.mStreamType &&
STREAM_VOLUME_ALIAS[streamType] == streamState.mStreamType) {
setStreamVolumeIndex(streamType, mStreamStates[streamType].mIndex);
}
}
// Post a persist volume msg
sendMsg(mAudioHandler, MSG_PERSIST_VOLUME, streamState.mStreamType,
SENDMSG_REPLACE, 1, 1, streamState, PERSIST_DELAY);
}
重点看:setStreamVolumeIndex()
AudioSystem下
public static native int setStreamVolumeIndex(int stream, int index);
它的实现在:
5./frameworks/base/media/libmedia/android_media_AudioSystem.cpp
static int
android_media_AudioSystem_setStreamVolumeIndex(JNIEnv *env, jobject thiz, jint stream, jint index)
{
return check_AudioSystem_Command(AudioSystem::setStreamVolumeIndex(static_cast
}
6.AudioSystem.cpp
//设置stream的音量
status_t AudioSystem::setStreamVolumeIndex(audio_stream_type_t stream, int index)
{
status_t AudioSystem::setStreamVolumeIndex(audio_stream_type_t stream, int index)
{
//获取AudioSystem中的AudioPolicyService的本地代理
const sp
if (aps == 0) return PERMISSION_DENIED;
return aps->setStreamVolumeIndex(stream, index);
}
}
const sp
{
gLock.lock();
if (gAudioPolicyService.get() == 0) {
//获取ServiceManager
sp
sp
do {
//获取audiopolicyservice
binder = sm->getService(String16("media.audio_policy"));
if (binder != 0)
break;
// 0.5 s
usleep(500000);
} while(true);
if (gAudioPolicyServiceClient == NULL) {
gAudioPolicyServiceClient = new AudioPolicyServiceClient();
}
binder->linkToDeath(gAudioPolicyServiceClient);
//这一步是获取获取AudioPolicyService的BpBinder形式,然后将它赋给gAudioPolicyService
//的mRemote
gAudioPolicyService = interface_cast
gLock.unlock();
} else {
gLock.unlock();
}
return gAudioPolicyService;
}
AudioPolicyService.cpp
status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream, int index)
{
//这是一个指针:struct audio_policy *mpAudioPolicy(AudioPolicyService.h)
if (mpAudioPolicy == NULL) {
return NO_INIT;
}
if (!checkPermission()) {
return PERMISSION_DENIED;
}
if (stream < 0 || stream >= AUDIO_STREAM_CNT) {
return BAD_VALUE;
}
return mpAudioPolicy->set_stream_volume_index(mpAudioPolicy, stream, index);
}
在这里正式转入对驱动的操作。
参考: