之前我们分析了无线鼠标右键无效,hal层的分析,我们可以把修改成返回键。

uint32_t CursorButtonAccumulator::getButtonState() const {  uint32_t result = 0;  if (mBtnLeft) {  result |= AMOTION_EVENT_BUTTON_PRIMARY;  }  if (mBtnRight) {  //result |= AMOTION_EVENT_BUTTON_SECONDARY;  result |= AMOTION_EVENT_BUTTON_BACK;//修改成返回键  }

但是具体AMOTION_EVENT_BUTTON_SECONDARY在哪里被过滤了,我们还没有分析到,现在我们来分析下鼠标按键机制的Framework层的分析,为什么之前的右键会被上层过滤?

我们先来看下ViewRootImpl.java这个文件,至于如何从hal层的按键进程,到Framework层的应用进程我们不分析了,之前的博客都分析过了。我们直接从鼠标处理的地方分析:

    final class ViewPostImeInputStage extends InputStage {public ViewPostImeInputStage(InputStage next) {super(next);}@Overrideprotected int onProcess(QueuedInputEvent q) {if (q.mEvent instanceof KeyEvent) {return processKeyEvent(q);//普通按键处理} else {// If delivering a new non-key event, make sure the window is// now allowed to start updating.handleDispatchWindowAnimationStopped();final int source = q.mEvent.getSource();if ((source & InputDevice.SOURCE_CLASS_POINTER) != 0) {return processPointerEvent(q);//鼠标按键处理} else if ((source & InputDevice.SOURCE_CLASS_TRACKBALL) != 0) {return processTrackballEvent(q);} else {return processGenericMotionEvent(q);}}}

ViewRootImpl文件处理按键消息会经过各个InputStage,而鼠标按键的处理是在ViewPostImeInputStage 和普通按键处理一样,会调用processPointerEvent来处理鼠标按键。

        private int processPointerEvent(QueuedInputEvent q) {final MotionEvent event = (MotionEvent)q.mEvent;mAttachInfo.mUnbufferedDispatchRequested = false;boolean handled = mView.dispatchPointerEvent(event);if (mAttachInfo.mUnbufferedDispatchRequested && !mUnbufferedInputDispatch) {mUnbufferedInputDispatch = true;if (mConsumeBatchedInputScheduled) {scheduleConsumeBatchedInputImmediately();}}return handled ? FINISH_HANDLED : FORWARD;}

processPointerEvent又调用了dispatchPointerEvent函数

    public final boolean dispatchPointerEvent(MotionEvent event) {if (event.isTouchEvent()) {return dispatchTouchEvent(event);//第一次鼠标按键进入这个函数} else {return dispatchGenericMotionEvent(event);}}

第一次鼠标按键进入dispatchTouchEvent这个函数

    public boolean dispatchTouchEvent(MotionEvent event) {// If the event should be handled by accessibility focus first.if (event.isTargetAccessibilityFocus()) {// We don't have focus or no virtual descendant has it, do not handle the event.if (!isAccessibilityFocusedViewOrHost()) {return false;}// We have focus and got the event, then use normal event dispatch.event.setTargetAccessibilityFocus(false);}boolean result = false;if (mInputEventConsistencyVerifier != null) {mInputEventConsistencyVerifier.onTouchEvent(event, 0);}final int actionMasked = event.getActionMasked();if (actionMasked == MotionEvent.ACTION_DOWN) {// Defensive cleanup for new gesturestopNestedScroll();}if (onFilterTouchEventForSecurity(event)) {//noinspection SimplifiableIfStatementListenerInfo li = mListenerInfo;if (li != null && li.mOnTouchListener != null&& (mViewFlags & ENABLED_MASK) == ENABLED&& li.mOnTouchListener.onTouch(this, event)) {result = true;}if (!result && onTouchEvent(event)) {//关键看onTouchEvent函数result = true;}}if (!result && mInputEventConsistencyVerifier != null) {mInputEventConsistencyVerifier.onUnhandledEvent(event, 0);}// Clean up after nested scrolls if this is the end of a gesture;// also cancel it if we tried an ACTION_DOWN but we didn't want the rest// of the gesture.if (actionMasked == MotionEvent.ACTION_UP ||actionMasked == MotionEvent.ACTION_CANCEL ||(actionMasked == MotionEvent.ACTION_DOWN && !result)) {stopNestedScroll();}return result;}       

下面我们再来看下onTouchEvent函数,在对aciton进行分别处理,当是MotionEvent.ACTION_DOWN:会先调用performButtonActionOnTouchDown函数

    public boolean onTouchEvent(MotionEvent event) {......if (((viewFlags & CLICKABLE) == CLICKABLE ||(viewFlags & LONG_CLICKABLE) == LONG_CLICKABLE) ||(viewFlags & CONTEXT_CLICKABLE) == CONTEXT_CLICKABLE) {switch (action) {......case MotionEvent.ACTION_DOWN:mHasPerformedLongPress = false;if (performButtonActionOnTouchDown(event)) {break;}// Walk up the hierarchy to determine if we're inside a scrolling container.boolean isInScrollingContainer = isInScrollingContainer();// For views inside a scrolling container, delay the pressed feedback for// a short period in case this is a scroll.if (isInScrollingContainer) {mPrivateFlags |= PFLAG_PREPRESSED;if (mPendingCheckForTap == null) {mPendingCheckForTap = new CheckForTap();}mPendingCheckForTap.x = event.getX();mPendingCheckForTap.y = event.getY();Log.e(TAG, "kangchen postDelayed setPressed");postDelayed(mPendingCheckForTap, ViewConfiguration.getTapTimeout());} else {// Not inside a scrolling container, so show the feedback right awaysetPressed(true, x, y);Log.e(TAG, "kangchen setPressed");checkForLongClick(0);}break;......

主要是下面这个函数,当获取ButtonState是MotionEvent.BUTTON_SECONDARY,就返回true,而在onTouchEvent函数中当performButtonActionOnTouchDown返回true,就会执行break,下面代码就不执行了。也就是因为这个导致右键无效,具体代码这边就不继续跟下去了,比较复杂。

    protected boolean performButtonActionOnTouchDown(MotionEvent event) {if (event.getToolType(0) == MotionEvent.TOOL_TYPE_MOUSE &&(event.getButtonState() & MotionEvent.BUTTON_SECONDARY) != 0) {showContextMenu(event.getX(), event.getY(), event.getMetaState());mPrivateFlags |= PFLAG_CANCEL_NEXT_UP_EVENT;return true;//返回true}return false;}

这样我们就大致分析了Framework层把鼠标右键过滤的分析。



Android6.0 按键流程(七)无线鼠标右键无效 -- Framework层相关推荐

  1. [RK3288][Android6.0] 调试笔记 --- AndroidTool低格无效问题

    Platform: Rockchip OS: Android 6.0 Kernel: 3.10.92 现象: 之前文章 [RK3288][Android6.0] 调试笔记 - AndroidTool两 ...

  2. android6.0按键处理浅析

    处理流程及示意图: 1,硬件配置: kernel-3.18\arch\arm\boot\dts\projectxxx.dts &keypad { mediatek,kpd-key-deboun ...

  3. android6.0 wifi流程,[RK3288][Android6.0] WiFi之从Linkspeed看获取流程

    Platform: Rockchip OS: Android 6.0 Kernel: 3.10.92 WiFi的(Link speed)连接速度可以从Settings里查看 从连接速度来看下获取WiF ...

  4. android获取ion信息,[RK3288][Android6.0] ION 流程和使用小结

    Platform: RK3288 OS: Android 6.0 Kernel: 3.10.92 之前Qualcomm平台有分析过ION, 可参考 http://www.voidcn.com/arti ...

  5. 零死角玩转Android6.0系统Healthd深入分析

    零死角玩转Android6.0系统Healthd深入分析 概述 Healthd是android4.4之后提出来的一种中介模型,该模型向下监听来自底层的电池事件,向上传递电池数据信息给Framework ...

  6. Android10.0 Binder通信原理(八)-Framework层分析

    摘要:本节主要来讲解Android10.0 Binder 在Framework的使用分析 阅读本文大约需要花费15分钟. 文章首发微信公众号:IngresGe 专注于Android系统级源码分析,An ...

  7. android6.0源码分析之Camera API2.0下的Preview(预览)流程分析

    1.Camera2 preview的应用层流程分析 preview流程都是从startPreview开始的,所以来看startPreview方法的代码: <code class="hl ...

  8. (原创)Android6.0亮屏流程分析

    1.概述 Android的亮屏流程从android系统结构层次来分可以分为三个流程,App应用唤醒源:Framework层Power结合Display,Light服务做亮屏绘制准备工作:底层驱动点亮背 ...

  9. android6.0源码分析之Camera API2.0下的初始化流程分析

    1.Camera2初始化的应用层流程分析 Camera2的初始化流程与Camera1.0有所区别,本文将就Camera2的内置应用来分析Camera2.0的初始化过程.Camera2.0首先启动的是C ...

最新文章

  1. SAP PM 初级系列1 – 定义维护工厂和维护计划工厂
  2. 【响应式Web前端设计】css中:overflow:hidden解决塌陷
  3. Python的日志模块logging的使用
  4. 元组-元组变量的常用操作
  5. 使用Math 类 和 Random类 两种方式生成 20 到30之间的随机整数---java基础
  6. Docker制作dotnet core控制台程序镜像
  7. spark job生成的时间驱动
  8. java纯数字正则表达式_JAVA验证数字的正则表达式,来一发
  9. 谷歌chrome浏览器桌面提醒 webkitNotifications
  10. URL中文传值乱码解决方式
  11. leecode - 入门 -- 双指针秒杀数组/链表题目
  12. unable to apply changes:plugins App links assistant,firebase services won'
  13. 简单sql存储过程实例、储过程实战
  14. 磁共振成像原理-物理基础(质子在外部磁场的情况)
  15. linux ttl信号处理,TTL和带缓冲的TTL信号(详细)
  16. PostgreSQL下载与安装
  17. mac备忘录html,MAC 使用备忘录
  18. Windows10 下面一个非常快速而精悍的看图软件 - IrfanView
  19. 极客时间学习笔记:03芯片分类
  20. 【面试招聘】 科班小硕的2020年面试小结

热门文章

  1. python字符串前面u、r、b含义以及str、bytes互转
  2. 提高 Python 代码的可读性,你需要知道这10个技巧
  3. 日常学习之:使用均值来填补缺失值的条件
  4. linux启用NAT功能,双网卡共享网络,iptables简单实现
  5. 通达OA工作流程-使用方法
  6. 电脑桌面的快捷方式的字体有背景颜色,怎么修改?
  7. 电脑下载速度一快电脑就卡的问题解决
  8. nba底层球员_探索个人NBA球员
  9. 简单三招,设计复杂ERP报表
  10. 【边学边记_12】——VGA原理与FPGA实现