android volume keyevents传递流程梳理

Tv的遥控器传递普通的keyevent是通过Tv的dispatchKeyEvent函数,经ITvInputSession onKeyUp/onKeyDown,最终调用HdmiControlService的sendKeyEvent方法将KeyEvent变成HdmiCecKeyCode,发送message MESSAGE_USER_CONTROL_PRESSED/MESSAGE_USER_CONTROL_RELEASED通过hdmi cec总线发送给playbacks/amplifiers.

音量键的传递流程则是由AudioService来控制的。

1.在调节音量的实现方法最后,会判断是否需要将volume update信息发送给hdmi system audio。

    protected void adjustStreamVolume(int streamType, int direction, int flags,
            String callingPackage, String caller, int uid) {
        if (mUseFixedVolume) {
            return;
        }
        if (DEBUG_VOL) Log.d(TAG, "adjustStreamVolume() stream=" + streamType + ", dir=" + direction
                + ", flags=" + flags + ", caller=" + caller);


    ......

             // Check if volume update should be sent to Hdmi system audio.
            if (streamTypeAlias == AudioSystem.STREAM_MUSIC) {
                setSystemAudioVolume(oldIndex, newIndex, getStreamMaxVolume(streamType), flags);
            }
            if (mHdmiManager != null) {
                synchronized (mHdmiManager) {
                    // mHdmiCecSink true => mHdmiPlaybackClient != null
                    if (mHdmiCecSink &&
                            streamTypeAlias == AudioSystem.STREAM_MUSIC &&
                            oldIndex != newIndex) {
                        synchronized (mHdmiPlaybackClient) {
                            int keyCode = (direction == -1) ? KeyEvent.KEYCODE_VOLUME_DOWN :
                                    KeyEvent.KEYCODE_VOLUME_UP;
                            final long ident = Binder.clearCallingIdentity();
                            try {
                                mHdmiPlaybackClient.sendKeyEvent(keyCode, true);
                                mHdmiPlaybackClient.sendKeyEvent(keyCode, false);
                            } finally {
                                Binder.restoreCallingIdentity(ident);
                            }
                        }
                    }
                }
            }
        }
        int index = mStreamStates[streamType].getIndex(device);
        sendVolumeUpdate(streamType, oldIndex, index, flags);
    ......
    }

1.1如果平台是tv,并且此时连接avr并进入system audio mode on,那么直接通过HdmiCecLocalDeviceTv来通过VolumeControlAction来处理avr的volume。

    private void setSystemAudioVolume(int oldVolume, int newVolume, int maxVolume, int flags) {
        if (mHdmiManager == null
                || mHdmiTvClient == null
                || oldVolume == newVolume
                || (flags & AudioManager.FLAG_HDMI_SYSTEM_AUDIO_VOLUME) != 0) return;

        // Sets the audio volume of AVR when we are in system audio mode. The new volume in
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值