标签:
1、在AudioManager.java中的handleKeyDown函数中接收音量键的按键消息
public void handleKeyDown(KeyEvent event, int stream) {int keyCode = event.getKeyCode();switch (keyCode) {case KeyEvent.KEYCODE_VOLUME_UP:case KeyEvent.KEYCODE_VOLUME_DOWN:/** Adjust the volume in on key down since it is more* responsive to the user.*/int flags = FLAG_SHOW_UI | FLAG_VIBRATE;if (mUseMasterVolume) {adjustMasterVolume(keyCode == KeyEvent.KEYCODE_VOLUME_UP? ADJUST_RAISE: ADJUST_LOWER,flags);} else {adjustSuggestedStreamVolume(keyCode == KeyEvent.KEYCODE_VOLUME_UP? ADJUST_RAISE: ADJUST_LOWER,stream,flags);}break;case KeyEvent.KEYCODE_VOLUME_MUTE:if (event.getRepeatCount() == 0) {if (mUseMasterVolume) {setMasterMute(!isMasterMute());} else {// TODO: Actually handle MUTE.}}break;}}
public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags) {IAudioService service = getService();Log.d(TAG, "adjustSuggestedStreamVolume: Direction = " + direction+ ", streamType = " + suggestedStreamType);try {if (mUseMasterVolume) {service.adjustMasterVolume(direction, flags, mContext.getOpPackageName());} else {service.adjustSuggestedStreamVolume(direction, suggestedStreamType, flags,mContext.getOpPackageName());}} catch (RemoteException e) {Log.e(TAG, "Dead object in adjustSuggestedStreamVolume", e);}}
public void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,String callingPackage) {if (DEBUG_VOL) Log.d(TAG, "adjustSuggestedStreamVolume() stream="+suggestedStreamType+" direction ="+direction+" flags="+flags);int streamType;Log.d(TAG, "adjustSuggestedStreamVolume() mVolumeControlStream="+mVolumeControlStream);if (mVolumeControlStream != -1) {streamType = mVolumeControlStream;Log.d(TAG, "adjustSuggestedStreamVolume() getMode()="+getMode());Log.d(TAG, "adjustSuggestedStreamVolume() AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0) ="+AudioSystem.isStreamActive(AudioSystem.STREAM_MUSIC, 0));Log.d(TAG, "adjustSuggestedStreamVolume() AudioSystem.isStreamActive(AudioSystem.STREAM_VOICE_CALL, 0) ="+AudioSystem.isStreamActive(AudioSystem.STREAM_VOICE_CALL, 0));} else {streamType = getActiveStreamType(suggestedStreamType);}Log.d(TAG, "adjustSuggestedStreamVolume() streamType2="+streamType);// Play sounds on STREAM_RING only and if lock screen is not on.if ((streamType != STREAM_REMOTE_MUSIC) &&(flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&((mStreamVolumeAlias[streamType] != AudioSystem.STREAM_RING)|| (mKeyguardManager != null && mKeyguardManager.isKeyguardLocked()))) {flags &= ~AudioManager.FLAG_PLAY_SOUND;}if (streamType == STREAM_REMOTE_MUSIC) {// don‘t play sounds for remoteflags &= ~(AudioManager.FLAG_PLAY_SOUND|AudioManager.FLAG_FIXED_VOLUME);//if (DEBUG_VOL) Log.i(TAG, "Need to adjust remote volume: calling adjustRemoteVolume()");mMediaFocusControl.adjustRemoteVolume(AudioSystem.STREAM_MUSIC, direction, flags);} else {adjustStreamVolume(streamType, direction, flags, callingPackage);}}
/** @see AudioManager#adjustStreamVolume(int, int, int) */public void adjustStreamVolume(int streamType, int direction, int flags,String callingPackage) {if (mUseFixedVolume) {return;}if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream="+streamType+", dir="+direction);ensureValidDirection(direction);ensureValidStreamType(streamType);Log.v(TAG,"adjustStreamVolume streamType1 : "+streamType);// use stream type alias here so that streams with same alias have the same behavior,// including with regard to silent mode control (e.g the use of STREAM_RING below and in// checkForRingerModeChange() in place of STREAM_RING or STREAM_NOTIFICATION)int streamTypeAlias = mStreamVolumeAlias[streamType];VolumeStreamState streamState = mStreamStates[streamTypeAlias];final int device = getDeviceForStream(streamTypeAlias);Log.v(TAG,"adjustStreamVolume streamTypeAlias : "+streamTypeAlias+" device:"+device);int aliasIndex = streamState.getIndex(device);boolean adjustVolume = true;int step;// skip a2dp absolute volume control request when the device// is not an a2dp deviceif ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) == 0 &&(flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) != 0) {return;}if (mAppOps.noteOp(STEAM_VOLUME_OPS[streamTypeAlias], Binder.getCallingUid(),callingPackage) != AppOpsManager.MODE_ALLOWED) {return;}// reset any pending volume commandsynchronized (mSafeMediaVolumeState) {mPendingVolumeCommand = null;}flags &= ~AudioManager.FLAG_FIXED_VOLUME;if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) &&((device & mFixedVolumeDevices) != 0)) {flags |= AudioManager.FLAG_FIXED_VOLUME;// Always toggle between max safe volume and 0 for fixed volume devices where safe// volume is enforced, and max and 0 for the others.// This is simulated by stepping by the full allowed volume rangeif (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE &&(device & mSafeMediaVolumeDevices) != 0) {step = mSafeMediaVolumeIndex;} else {step = streamState.getMaxIndex();}if (aliasIndex != 0) {aliasIndex = step;}} else {// convert one UI step (+/-1) into a number of internal units on the stream aliasstep = rescaleIndex(10, streamType, streamTypeAlias);}// If either the client forces allowing ringer modes for this adjustment,// or the stream type is one that is affected by ringer modesif (((flags & AudioManager.FLAG_ALLOW_RINGER_MODES) != 0) ||(streamTypeAlias == getMasterStreamType())) {int ringerMode = getRingerMode();// do not vibrate if already in vibrate modeif (ringerMode == AudioManager.RINGER_MODE_VIBRATE) {flags &= ~AudioManager.FLAG_VIBRATE;}// Check if the ringer mode changes with this volume adjustment. If// it does, it will handle adjusting the volume, so we won‘t belowadjustVolume = checkForRingerModeChange(aliasIndex, direction, step);}int oldIndex = mStreamStates[streamType].getIndex(device);if (adjustVolume && (direction != AudioManager.ADJUST_SAME)) {// Check if volume update should be send to AVRCPif (streamTypeAlias == AudioSystem.STREAM_MUSIC &&(device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 &&(flags & AudioManager.FLAG_BLUETOOTH_ABS_VOLUME) == 0) {synchronized (mA2dpAvrcpLock) {if (mA2dp != null && mAvrcpAbsVolSupported) {mA2dp.adjustAvrcpAbsoluteVolume(direction);}}}if ((direction == AudioManager.ADJUST_RAISE) &&!checkSafeMediaVolume(streamTypeAlias, aliasIndex + step, device)) {Log.e(TAG, "adjustStreamVolume() safe volume index = "+oldIndex);mVolumePanel.postDisplaySafeVolumeWarning(flags);} else if (streamState.adjustIndex(direction * step, device)) {// Post message to set system volume (it in turn will post a message// to persist). Do not change volume if stream is muted.sendMsg(mAudioHandler,MSG_SET_DEVICE_VOLUME,SENDMSG_QUEUE,device,0,streamState,0);}}int index = mStreamStates[streamType].getIndex(device);sendVolumeUpdate(streamType, oldIndex, index, flags);}
private void setDeviceVolume(VolumeStreamState streamState, int device) {// Apply volumestreamState.applyDeviceVolume(device);// Apply change to all streams using this one as aliasint numStreamTypes = AudioSystem.getNumStreamTypes();for (int streamType = numStreamTypes - 1; streamType >= 0; streamType--) {if (streamType != streamState.mStreamType &&mStreamVolumeAlias[streamType] == streamState.mStreamType) {// Make sure volume is also maxed out on A2DP device for aliased stream// that may have a different device selectedint streamDevice = getDeviceForStream(streamType);if ((device != streamDevice) && mAvrcpAbsVolSupported &&((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0)) {mStreamStates[streamType].applyDeviceVolume(device);}mStreamStates[streamType].applyDeviceVolume(streamDevice);}}// Post a persist volume msgsendMsg(mAudioHandler,MSG_PERSIST_VOLUME,SENDMSG_QUEUE,device,0,streamState,PERSIST_DELAY);}
public void applyDeviceVolume(int device) {int index;if (isMuted()) {index = 0;} else if ((device & AudioSystem.DEVICE_OUT_ALL_A2DP) != 0 &&mAvrcpAbsVolSupported) {index = (mIndexMax + 5)/10;} else {index = (getIndex(device) + 5)/10;}Log.d(TAG,"applyDeviceVolume index:"+index + " mStreamType:" + mStreamType + ",device:" + device);AudioSystem.setStreamVolumeIndex(mStreamType, index, device);}
public static native int setStreamVolumeIndex(int stream, int index, int device);
status_t AudioSystem::setStreamVolumeIndex(audio_stream_type_t stream,int index,audio_devices_t device){const sp<IAudioPolicyService>& aps = AudioSystem::get_audio_policy_service();if (aps == 0) return PERMISSION_DENIED;return aps->setStreamVolumeIndex(stream, index, device);}
status_t AudioPolicyService::setStreamVolumeIndex(audio_stream_type_t stream,int index,audio_devices_t device){ALOGD("AudioPolicyService::setStreamVolumeIndex");if (mpAudioPolicy == NULL) {return NO_INIT;}if (!settingsAllowed()) {return PERMISSION_DENIED;}if (uint32_t(stream) >= AUDIO_STREAM_CNT) {return BAD_VALUE;}Mutex::Autolock _l(mLock);if (mpAudioPolicy->set_stream_volume_index_for_device) {ALOGD("mpAudioPolicy->set_stream_volume_index_for_device");return mpAudioPolicy->set_stream_volume_index_for_device(mpAudioPolicy,stream,index,device);} else {ALOGD("mpAudioPolicy->set_stream_volume_index");return mpAudioPolicy->set_stream_volume_index(mpAudioPolicy, stream, index);}}
status_t AudioMTKPolicyManager::setStreamVolumeIndex(AudioSystem::stream_type stream,int index,audio_devices_t device){ALOGD("AudioMTKPolicyManager setStreamVolumeIndex stream = %d index = %d device = 0x%x",stream,index,device);if ((index < mStreams[stream].mIndexMin) || (index > mStreams[stream].mIndexMax)) {return BAD_VALUE;}if (!audio_is_output_device(device)) {return BAD_VALUE;}// Force max volume if stream cannot be mutedif (!mStreams[stream].mCanBeMuted) index = mStreams[stream].mIndexMax;ALOGV("setStreamVolumeIndex() stream %d, device %04x, index %d",stream, device, index);// if device is AUDIO_DEVICE_OUT_DEFAULT set default value and// clear all device specific valuesif (device == AUDIO_DEVICE_OUT_DEFAULT) {mStreams[stream].mIndexCur.clear();}mStreams[stream].mIndexCur.add(device, index);#ifdef MTK_AUDIO#ifdef MTK_AUDIO_GAIN_TABLEmAudioUCM->setStreamVolIndex(stream,index,device);#endif#endif// compute and apply stream volume on all outputs according to connected devicestatus_t status = NO_ERROR;for (size_t i = 0; i < mOutputs.size(); i++) {audio_devices_t curDevice =getDeviceForVolume(mOutputs.valueAt(i)->device());if ((device == AUDIO_DEVICE_OUT_DEFAULT) || (device == curDevice)) {#ifdef MTK_AUDIOstatus_t volStatus;// alps00053099 adjust matv volume when record sound stoping, matv sound will out through speaker.// delay -1 to put this volume command at the end of command queue in audiopolicy serviceif(stream ==AudioSystem::MATV &&(mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADSET ||mAvailableOutputDevices & AudioSystem::DEVICE_OUT_WIRED_HEADPHONE)){volStatus =checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice,-1);}else{volStatus =checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);}#elsestatus_t volStatus = checkAndSetVolume(stream, index, mOutputs.keyAt(i), curDevice);#endifif (volStatus != NO_ERROR) {status = volStatus;}}}return status;}
status_t AudioMTKPolicyManager::checkAndSetVolume(int stream,int index,audio_io_handle_t output,audio_devices_t device,int delayMs,bool force){ALOGD(" checkAndSetVolume stream = %d index = %d output = %d device = 0x%x delayMs = %d force = %d",stream,index,output,device,delayMs,force);// do not change actual stream volume if the stream is mutedif (mOutputs.valueFor(output)->mMuteCount[stream] != 0) {ALOGVV("checkAndSetVolume() stream %d muted count %d",stream, mOutputs.valueFor(output)->mMuteCount[stream]);return NO_ERROR;}// do not change in call volume if bluetooth is connected and vice versaif ((stream == AudioSystem::VOICE_CALL && mForceUse[AudioSystem::FOR_COMMUNICATION] == AudioSystem::FORCE_BT_SCO) ||(stream == AudioSystem::BLUETOOTH_SCO && mForceUse[AudioSystem::FOR_COMMUNICATION] != AudioSystem::FORCE_BT_SCO)) {ALOGD("checkAndSetVolume() cannot set stream %d volume with force use = %d for comm",stream, mForceUse[AudioSystem::FOR_COMMUNICATION]);return INVALID_OPERATION;}float volume = computeVolume(stream, index, output, device);ALOGD("checkAndSetVolume volume = %f stream=%d device=%d",volume,stream,device);#ifdef MTK_AUDIO#ifdef MTK_AUDIO_GAIN_TABLEupdateAnalogVolume(output,device,delayMs);#endif#endif#ifdef MTK_AUDIO//for VT notify tone when incoming call. it‘s volume will be adusted in hardware.if((stream == AudioSystem::VOICE_CALL ||stream == AudioSystem::BLUETOOTH_SCO) && mOutputs.valueFor(output)->mRefCount[stream]!=0 && mPhoneState==AudioSystem::MODE_IN_CALL){volume =1.0;}// ALPS00554824 KH: If notifiaction is exist, FM should be muteif ((stream == AudioSystem::FM) &&(mOutputs.valueFor(output)->mRefCount[AudioSystem::NOTIFICATION]|| mOutputs.valueFor(output)->mRefCount[AudioSystem::RING]|| mOutputs.valueFor(output)->mRefCount[AudioSystem::ALARM])){volume =0.0;}// ALPS001125976 Mute music at ringtone from BT to primary//if ( (stream == AudioSystem::MUSIC) && (mPhoneState ==AudioSystem::MODE_RINGTONE) && (mStreams[AudioSystem::RING].getVolumeIndex(device)!=mStreams[AudioSystem::RING].mIndexMin) ) {// volume =0.0;//}#endif//ALOGD("checkAndSetVolume newvolume %f, oldvolume %f,output %d",volume,mOutputs.valueFor(output)->mCurVolume[stream],output);// We actually change the volume if:// - the float value returned by computeVolume() changed// - the force flag is setif (volume != mOutputs.valueFor(output)->mCurVolume[stream] ||force#ifdef MTK_AUDIO||(stream==AudioSystem::FM && output==mPrimaryOutput && (device == AUDIO_DEVICE_OUT_WIRED_HEADSET ||device == AUDIO_DEVICE_OUT_WIRED_HEADPHONE) )//WFD output can‘t affect HwGain,however affect mFmVolume . But PrimaryOutput will use mFmVolume setting#endif) {#ifdef MTK_AUDIOint bSetStreamVolume=1;//Overall, Don‘t set volume to affect direct mode volume setting if the later routing is still direct mode . HoChi . This is very tricky that WFD support FM,others(BT/...) don‘t.#ifdef MATV_AUDIO_SUPPORTif( matv_use_analog_input == true){if((stream==AudioSystem::MATV)&&(output!=mPrimaryOutput||device==AUDIO_DEVICE_NONE)&&device!=AUDIO_DEVICE_OUT_REMOTE_SUBMIX){bSetStreamVolume=0; //MATV with line-in path is only ouput from primaryoutput}}#endif//Add device==AUDIO_DEVICE_NONE for ALPSif((stream==AudioSystem::FM)&&(output!=mPrimaryOutput||device==AUDIO_DEVICE_NONE)&&device!=AUDIO_DEVICE_OUT_REMOTE_SUBMIX){bSetStreamVolume=0; //FM with line-in path is only ouput from primaryoutput}if(bSetStreamVolume==1){#endifmOutputs.valueFor(output)->mCurVolume[stream] = volume;ALOGD("checkAndSetVolume() for output %d stream %d, volume %f, delay %d", output, stream, volume, delayMs);// Force VOICE_CALL to track BLUETOOTH_SCO stream volume when bluetooth audio is// enabledif (stream == AudioSystem::BLUETOOTH_SCO) {mpClientInterface->setStreamVolume(AudioSystem::VOICE_CALL, volume, output, delayMs);}mpClientInterface->setStreamVolume((AudioSystem::stream_type)stream, volume, output, delayMs);#ifdef MTK_AUDIO}else{ALOGD("skip setStreamVolume for output %d stream %d, volume %f, delay %d",output, stream, volume, delayMs);}#endif}ALOGD("checkAndSetVolume() for output %d stream %d, volume %f, delay %d, loc 2", output, stream, volume, delayMs);if (stream == AudioSystem::VOICE_CALL ||stream == AudioSystem::BLUETOOTH_SCO) {float voiceVolume;// Force voice volume to max for bluetooth SCO as volume is managed by the headsetif (stream == AudioSystem::VOICE_CALL) {#ifdef MTK_AUDIO#ifndef MTK_AUDIO_GAIN_TABLEvoiceVolume = computeCustomVoiceVolume(stream, index, output, device);#endif#elsevoiceVolume = (float)index/(float)mStreams[stream].mIndexMax;#endif} else {voiceVolume = 1.0;}ALOGD("checkAndSetVolume() voiceVolume %f mLastVoiceVolume %f mPrimaryOutput %d output %d",voiceVolume, mLastVoiceVolume,mPrimaryOutput,output);if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) {mpClientInterface->setVoiceVolume(voiceVolume, delayMs);#ifdef MTK_AUDIO#ifdef EVDO_DT_SUPPORTALOGD("SetVoiceVolumeIndex=%d %f,%f,%d", index, voiceVolume, mLastVoiceVolume, output == mPrimaryOutput);//set Volume Index ( for external modem)AudioParameter param = AudioParameter();param.addInt(String8("SetVoiceVolumeIndex"), index);mpClientInterface->setParameters (0 , param.toString(), 0);#endif#endifmLastVoiceVolume = voiceVolume;}}return NO_ERROR;}
if (voiceVolume != mLastVoiceVolume && output == mPrimaryOutput) {mpClientInterface->setVoiceVolume(voiceVolume, delayMs);#ifdef MTK_AUDIO#ifdef EVDO_DT_SUPPORTALOGD("SetVoiceVolumeIndex=%d %f,%f,%d", index, voiceVolume, mLastVoiceVolume, output == mPrimaryOutput);//set Volume Index ( for external modem)AudioParameter param = AudioParameter();param.addInt(String8("SetVoiceVolumeIndex"), index);mpClientInterface->setParameters (0 , param.toString(), 0);#endif#endifmLastVoiceVolume = voiceVolume;}
标签:
原文地址:http://www.cnblogs.com/Michelangelo/p/4710068.html