SystemUI VolumeService

//当手机设备当前活动窗口在Launcher桌面,Launcher没有对音量事件做拦截操作,音量键事件将会在PhoneWindow中被消化。
protected boolean onKeyDown(int featureId, int keyCode, KeyEvent event) {
final KeyEvent.DispatcherState dispatcher =
mDecor != null ? mDecor.getKeyDispatcherState() : null;
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN:
case KeyEvent.KEYCODE_VOLUME_MUTE: {
int direction = 0;
switch (keyCode) {
//direction为音量控制类型,为0时保持不变
case KeyEvent.KEYCODE_VOLUME_UP:
direction = AudioManager.ADJUST_RAISE;
break;
case KeyEvent.KEYCODE_VOLUME_DOWN:
direction = AudioManager.ADJUST_LOWER;
break;
case KeyEvent.KEYCODE_VOLUME_MUTE:
direction = AudioManager.ADJUST_TOGGLE_MUTE;
break;
}
if (mMediaController != null) {
mMediaController.adjustVolume(direction, AudioManager.FLAG_SHOW_UI);
} else {
//mVolumeControlStreamType表示音量类型
//direction表示音量控制类型
//第三个参数控制VolumeUI的显示
MediaSessionLegacyHelper.getHelper(getContext()).sendAdjustVolumeBy(
mVolumeControlStreamType, direction,
AudioManager.FLAG_SHOW_UI | AudioManager.FLAG_VIBRATE
| AudioManager.FLAG_FROM_KEY);
}
return true;
}
...
}
return false;
}


private int mVolumeControlStreamType = AudioManager.USE_DEFAULT_STREAM_TYPE;
public static final int USE_DEFAULT_STREAM_TYPE = Integer.MIN_VALUE;
//音量键松开
protected boolean onKeyUp(int featureId, int keyCode, KeyEvent event) {
final KeyEvent.DispatcherState dispatcher =
mDecor != null ? mDecor.getKeyDispatcherState() : null;
if (dispatcher != null) {
dispatcher.handleUpEvent(event);
}
switch (keyCode) {
case KeyEvent.KEYCODE_VOLUME_UP:
case KeyEvent.KEYCODE_VOLUME_DOWN: {
final int flags = AudioManager.FLAG_PLAY_SOUND | AudioManager.FLAG_VIBRATE
| AudioManager.FLAG_FROM_KEY;
if (mMediaController != null) {
mMediaController.adjustVolume(0, flags);
} else {
MediaSessionLegacyHelper.getHelper(getContext()).sendAdjustVolumeBy(
mVolumeControlStreamType, 0, flags);
}
return true;
}
...
}


return false;
}


private MediaSessionManager mSessionManager;
public void sendAdjustVolumeBy(int suggestedStream, int delta, int flags) {
mSessionManager.dispatchAdjustVolume(suggestedStream, delta, flags);
if (DEBUG) {
Log.d(TAG, "dispatched volume adjustment");
}
}


private final ISessionManager mService;
public MediaSessionManager(Context context) {
mContext = context;
IBinder b = ServiceManager.getService(Context.MEDIA_SESSION_SERVICE);
mService = ISessionManager.Stub.asInterface(b);
}
//mservice为MediaSessionService对象
public void dispatchAdjustVolume(int suggestedStream, int direction, int flags) {
try {
mService.dispatchAdjustVolume(suggestedStream, direction, flags);
} catch (RemoteException e) {
Log.e(TAG, "Failed to send adjust volume.", e);
}
}






public void dispatchAdjustVolume(int suggestedStream, int delta, int flags) {
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
final long token = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
//获取MediaSessionRecord对象来控制音量
MediaSessionRecord session = mPriorityStack.getDefaultVolumeSession(mCurrentUserId);
dispatchAdjustVolumeLocked(suggestedStream, delta, flags, session);
}
} finally {
Binder.restoreCallingIdentity(token);
}
}


private IAudioService mAudioService;
 mAudioService = getAudioService();
 private IAudioService getAudioService() {
IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
return IAudioService.Stub.asInterface(b);
}
private void dispatchAdjustVolumeLocked(int suggestedStream, int direction, int flags,
MediaSessionRecord session) {
...
boolean preferSuggestedStream = false;
...
if (session == null || preferSuggestedStream) {
...
try {
//mAudioService实际上是AudioService的对象
String packageName = getContext().getOpPackageName();
mAudioService.adjustSuggestedStreamVolume(direction, suggestedStream,
flags, packageName, TAG);
} catch (RemoteException e) {
Log.e(TAG, "Error adjusting default volume.", e);
}
}
...
}




private final ControllerService mControllerService = new ControllerService();
private void adjustSuggestedStreamVolume(int direction, int suggestedStreamType, int flags,
String callingPackage, String caller, int uid) {
...
int streamType;
boolean isMute = isMuteAdjust(direction);
if (mVolumeControlStream != -1) {
streamType = mVolumeControlStream;
} else {
//将Integer.MIN_VALUE转换成streamType的形式,取值范围为0-10,表示音量值
streamType = getActiveStreamType(suggestedStreamType);
}
ensureValidStreamType(streamType);//数据正确性检查
final int resolvedStream = mStreamVolumeAlias[streamType];


//FLAG_PLAY_SOUND表示调整音量时播放声音
if ((flags & AudioManager.FLAG_PLAY_SOUND) != 0 &&
resolvedStream != AudioSystem.STREAM_RING) {
flags &= ~AudioManager.FLAG_PLAY_SOUND;
}



if (mVolumeController.suppressAdjustment(resolvedStream, flags, isMute)) {
direction = 0;
flags &= ~AudioManager.FLAG_PLAY_SOUND;
flags &= ~AudioManager.FLAG_VIBRATE;//震动模式
if (DEBUG_VOL) Log.d(TAG, "Volume controller suppressed adjustment");
}
adjustStreamVolume(streamType, direction, flags, callingPackage, caller, uid);
}










 private void adjustStreamVolume(int streamType, int direction, int flags,
            String callingPackage, String caller, int uid) {
...
//数据正确性检查
ensureValidDirection(direction);
ensureValidStreamType(streamType);
boolean isMuteAdjust = isMuteAdjust(direction);
...
//获取streamType映射到的流类型
int streamTypeAlias = mStreamVolumeAlias[streamType];
//VolumeStreamState类,保存与一个流类型所有音量相关的信息
VolumeStreamState streamState = mStreamStates[streamTypeAlias];
//获取流类型所对应的音频设备
final int device = getDeviceForStream(streamTypeAlias);
//获取当前音量
int aliasIndex = streamState.getIndex(device);
boolean adjustVolume = true;
int step;
...
flags &= ~AudioManager.FLAG_FIXED_VOLUME;
if ((streamTypeAlias == AudioSystem.STREAM_MUSIC) &&
   ((device & mFixedVolumeDevices) != 0)) {
flags |= AudioManager.FLAG_FIXED_VOLUME;
...
} else {
//rescaleIndex用于将音量值的变化量从源流类型变换到目标流类型
//由于不同的流类型的音量调节范围不同,所以这个转换是必需的
step = rescaleIndex(10, streamType, streamTypeAlias);
}
...
//获取原始音量
int oldIndex = mStreamStates[streamType].getIndex(device);
//获取调整后的音量值
int newIndex = mStreamStates[streamType].getIndex(device);
...
int index = mStreamStates[streamType].getIndex(device);
//通知外接音量值发生变化
sendVolumeUpdate(streamType, oldIndex, index, flags);
}


private final VolumeController mVolumeController = new VolumeController();
private void sendVolumeUpdate(int streamType, int oldIndex, int index, int flags) {
streamType = mStreamVolumeAlias[streamType];
if (streamType == AudioSystem.STREAM_MUSIC) {
flags = updateFlagsForSystemAudio(flags);
}
//将音量变化信息通知给SystemUI
mVolumeController.postVolumeChanged(streamType, flags);
}


private IVolumeController mController;
public void postVolumeChanged(int streamType, int flags) {
if (mController == null)
return;
try {
//mController为VolumeDialogController的实例
mController.volumeChanged(streamType, flags);
} catch (RemoteException e) {
Log.w(TAG, "Error calling volumeChanged", e);
}
}


public void volumeChanged(int streamType, int flags) throws RemoteException {
if (D.BUG) Log.d(TAG, "volumeChanged " + AudioSystem.streamToString(streamType)
+ " " + Util.audioManagerFlagsToString(flags));
if (mDestroyed) return;
//发送消息,mWork为VolumeDialogController的内部类W的实例
mWorker.obtainMessage(W.VOLUME_CHANGED, streamType, flags).sendToTarget();
}






@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case VOLUME_CHANGED: onVolumeChangedW(msg.arg1, msg.arg2); break;
...
}
}






private void onVolumeChangedW(int stream, int flags) {
final boolean showUI = (flags & AudioManager.FLAG_SHOW_UI) != 0;
final boolean fromKey = (flags & AudioManager.FLAG_FROM_KEY) != 0;
final boolean showVibrateHint = (flags & AudioManager.FLAG_SHOW_VIBRATE_HINT) != 0;
final boolean showSilentHint = (flags & AudioManager.FLAG_SHOW_SILENT_HINT) != 0;
boolean changed = false;
if (showUI) {
changed |= updateActiveStreamW(stream);
}
int lastAudibleStreamVolume = mAudio.getLastAudibleStreamVolume(stream);
changed |= updateStreamLevelW(stream, lastAudibleStreamVolume);
changed |= checkRoutedToBluetoothW(showUI ? AudioManager.STREAM_MUSIC : stream);
if (changed) {
mCallbacks.onStateChanged(mState);
}
if (showUI) {
mCallbacks.onShowRequested(Events.SHOW_REASON_VOLUME_CHANGED);
}
if (showVibrateHint) {
mCallbacks.onShowVibrateHint();
}
if (showSilentHint) {
mCallbacks.onShowSilentHint();
}
if (changed && fromKey) {
Events.writeEvent(mContext, Events.EVENT_KEY, stream, lastAudibleStreamVolume);
}
}




public void onStateChanged(final State state) {
final long time = System.currentTimeMillis();
final State copy = state.copy();
for (final Map.Entry<Callbacks, Handler> entry : mCallbackMap.entrySet()) {
entry.getValue().post(new Runnable() {
@Override
public void run() {
entry.getKey().onStateChanged(copy);
}
});
}
Events.writeState(time, copy);
}





















  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值