[AudioService.java-->AudioService.setStreamVolume()] public void setStreamVolume(int streamType, int index, int flags) { // 这里先判断一下流类型这个参数的有效性 ensureValidStreamType(streamType); // 获取保存了指定流类型音量信息的VolumeStreamState对象 // 注意,这里面使用mStreamVolumeAlias对这个数组进行流类型转换 VolumeStreamState streamState = mStreamStates[mStreamVolumeAlias[streamType]]; // 获取当前流将使用哪一个音频设备进行播放。它最终会被调用到AudioPolicyService中 final int device = getDeviceForStream(streamType); // 获取流当前的音量 final int oldIndex = streamState.getIndex(device, (streamState.muteCount() != 0) /* lastAudible */); // 将原流类型下的音量值映射到目标流类型下的音量值 // 因为不同流类型的音量值刻度不一样,所以需要进行转换 index = rescaleIndex(index * 10, streamType, mStreamVolumeAlias[streamType]); //暂时先忽略下面这段if中的代码。它的作用是根据flags的要求修改手机的情景模式 if (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) || (mStreamVolumeAlias[streamType] == getMasterStreamType())) { ...... } // 调用setStreamVolumeInt() setStreamVolumeInt(mStreamVolumeAlias[streamType], index, device, false, true); // 获取设置的结果 index = mStreamStates[streamType].getIndex(device, (mStreamStates[streamType].muteCount() != 0) /* lastAudible */); // 广播通知 sendVolumeUpdate(streamType, oldIndex, index, flags); }
[AudioService.java-->AudioService.setStreamVolumeInt()] private void setStreamVolumeInt(int streamType, int index, int device, boolean force, boolean lastAudible) { // 获取保存音量信息的VolumeStreamState对象 VolumeStreamState streamState = mStreamStates[streamType]; if (streamState.muteCount() != 0) { // 这里的内容是为了处理当流被静音后的情况。我们在讨论静音的实现时再考虑这段代码 ...... } else { // 调用streamState.setIndex() if (streamState.setIndex(index, device, lastAudible) || force) { // 如果setIndex返回true,或者force参数为true,就在这里向mAudioHandler发送消息 sendMsg(mAudioHandler, MSG_SET_DEVICE_VOLUME, SENDMSG_QUEUE, device, 0, streamState, 0); } } }