Android系统--输入系统(十六)APP跟输入系统建立联系_InputChannel和Connection

0. 核心:socketpair机制

1. 回顾Dispatch处理过程:

1.1 放入队列前稍加处理

  • 分类:Global Key/System Key/User Key
  • 处理紧急事件(比如来电的时候按下音量键静音)

1.2 InputReader线程将读到的输入事件稍加处理后放入mInboundQueue队列中,接着唤醒Dispatch线程

1.3 Dispatch从mInboundQueue队列中将输入事件取出,并稍加处理。

  • 对于Global Key/System Key按键处理:放入mCommandQueue队列中,依次处理,处理之后就release
  • 对于User Key,放入队列:查找目标APP,得到Connection,放入其OutBoundQueue队列中,稍后取出处理

2. 引入--如何找出目标应用程序,输入系统和应用程序如何建立联系?

PC和安卓系统都是运行着多个应用程序,但是只有屏幕最前面的应用程序才可以接收到输入事件,谁来告诉输入事件哪个是运行在屏幕最前面的应用程序呢?

2.1 引入WindowServiceManager窗口管理服务

  • 对于每一个应用程序,WindowServiceManager都有一个结构体WindowSate来表示该应用程序。假设新启动一个APP,通过binder通信,调用addToDisplay,会导致AddWindow被调用,AddWindow创建了WindowSate表示该应用程序,接着创建一个socketpair得到两个文件句柄fd0和fd1,fd1直接返回给应用程序,fd0将其封装为InputChannel类,一方面InputChannel会放进该APPWindowState中,另外一方面,他会将InputChannel注册给InputDispatch。

2.2 Dispatch线程

  • InputDispatch线程中里面有KeyedVector包含含有多个connection,这些connection可以通过注册实现,创建一个connection(含有InputChannel,InputChannel含有文件句柄fd),将创建好的connection放入Vector当中。
// All registered connections mapped by channel file descriptor.
KeyedVector<int, sp<Connection> > mConnectionsByFd;

2.3 引入connection

  • 对于每一个能够接受输入事件应用程序,在InputDispatch当中都有一个connection。假设还有一个应用程序APP,在WindowServiceManager中也有一个WindowState,在InputDispatch中也有一个对应的connection,放入Vector容器中,在connection中含有InputChannel和fd,其中fd来自Socketpair的fd0,另外一个fd1通过Binder通信返回给APP4。这样子InputDispatch线程想把输入事件发送给APP时候,先要找出当前在屏幕最前面的应用程序,然后从vector容器中找到他的connection,然后将数据写入fd当中既可。

2.4 总结

  • Dispatch线程从输入事件中读到数据后,可以通过Vector当中找出某个connection,把输入事件放入fd当中,另外一个应用程序可以从另外一个文件句柄中得到输入事件,将得到的文件句柄封装为InputChannel,再封装为WindowInputEventReceiver,最后把fd放入Looper中,使用Epoll机制查询等待数据,具体可以见下面关系图。

2.5 补充

  • InputReader线程、InputDispatch线程和WindowServiceManager都处于System进程当中,故这三个线程可以直接通信不需要Binder介入,而APP如果想跟这三个线程通信则需要通过Binder机制来实现或者通过事先建立好的Socketpair再通过Binder将文件句柄返回给APP,故其文件句柄可能发生变化。

3. APP获得SocketPair的fd过程分析

  • 发起addToDisplay的操作
ViewRootImpl.java
res = mWindowSession.addToDisplay(mWindow, mSeq, mWindowAttributes,
getHostVisibility(), mDisplay.getDisplayId(),
mAttachInfo.mContentInsets, mInputChannel);
  • 导致同文件下的onTransact被调用
IWindowSession.java
mRemote.transact(Stub.TRANSACTION_addToDisplay, _data, _reply, 0);
  • 根据code值调用本地的addToDisplay
IWindowSession.java
int _result = this.addToDisplay(_arg0, _arg1, _arg2, _arg3, _arg4, _arg5, _arg6);
- 得到两个文件句柄
Session.java
public int addToDisplay(IWindow window, int seq, WindowManager.LayoutParams attrs,
int viewVisibility, int displayId, Rect outContentInsets,
InputChannel outInputChannel) {
return mService.addWindow(this, window, seq, attrs, viewVisibility, displayId,
outContentInsets, outInputChannel);
}
WindowManagerService.java
InputChannel[] inputChannels = InputChannel.openInputChannelPair(name);
- 把fd1写给InputChanne
WindowManagerService.java
inputChannels[1].transferTo(outInputChannel); //outInputChannel含有fd1,实际上就是arg6
  • 根据_arg6的返回结果,把fd写给Binder驱动程序
IWindowSession.java
_arg6.writeToParcel(reply, android.os.Parcelable.PARCELABLE_WRITE_RETURN_VALUE);
- 最终调用该函数把fd写入bind驱动中
android_view_InputChannel.cpp
parcel->writeDupFileDescriptor(inputChannel->getFd());
  • 远程操作之后,从驱动程序读出fd
outContentInsets.readFromParcel(_reply);
- 从Binder驱动中读出fd
android_view_InputChannel.cpp
int rawFd = parcel->readFileDescriptor();
int dupFd = dup(rawFd);

4. 具体调用过程时序图

具体源码可以根据下面的时序图进行具体分析。注:引用韦东山老师

Android系统--输入系统(十六)APP跟输入系统建立联系_InputChannel和Connection的更多相关文章

  1. 第十六篇:Linux系统编程中环境变量的使用

    前言 在 UNIX Like 系统中,存有各类系统/应用程序的环境变量,可通过修改之改变系统/应用程序的执行效果:除此之外,用户还可以定义自己的环境变量,供自己写的程序使用. 本文将说明如何在程序中设 ...

  2. 第三十六节,os系统级别操作模块

    在使用os模块时需要先 import os 引入模块 os.getcwd()模块函数 功能:获取当前工作目录,即当前python脚本工作的目录路径[无参] 使用方法:os.getcwd() 格式如:a ...

  3. Android笔记(二十六) Android中的广播——BroadcastReceiver

    为了方便进行系统级别的消息通知,Android有一套类似广播的消息机制,每个应用程序都可以对自己感兴趣的广播进行注册,这样该程序就只会接收自己所关心的广播内容,这些广播可能是来自于系统,也可能是来自于 ...

  4. Android开发系列(十六):【Android小游戏成语连连看】第二篇

    写的晚了,在分工个Z市高中的一个成绩查询的系统,原系统居然是用VB写的,我不得不佩服原本写系统的那位哥们真能耐得住. 明天搭建下SVN就等着先发project款然后開始项目了.想想有工资进账,心里也为 ...

  5. Android核心分析之十六Android电话系统-概述篇

    Android电话系统之概述篇 首先抛开Android的一切概念来研究一下电话系统的最基本的描述.我们的手机首先用来打电话的,随后是需要一个电话本,随后是PIM,随后是网络应用,随后是云计算,随后是想 ...

  6. 【转】Pro Android学习笔记(十六):用户界面和控制(4):ImageView控件

    目录(?)[-] XML片段 代码设置ImageView ImageView是基础的控件,它是android.widget.ImageView的继承类. XML片段      <LinearLa ...

  7. Android学习笔记(十六) ContentProvider

    1.相关概念 ContentProvider:不同应用程序之间进行数据交换的标准API:程序“暴露”数据的方法. ContentResolver:一个程序访问另一个程序被“暴露”的数据的方法. Uri ...

  8. Android笔记(五十六) Android四大组件之一——ContentProvider,实现自己的ContentProvider

    有时候我们自己的程序也需要向外接提供数据,那么就需要我们自己实现ContentProvider. 自己实现ContentProvider的话需要新建一个类去继承ContentProvider,然后重写 ...

  9. Android笔记(四十六) Android中的数据存储——XML(二)PULL解析

    PULL 的工作原理: XML pull提供了开始元素和结束元素.当某个元素开始时,可以调用parser.nextText()从XML文档中提取所有字符数据.当解析到一个文档结束时,自动生成EndDo ...

随机推荐

  1. 【JAVAWEB学习笔记】网上商城实战:环境搭建和完成用户模块

    网上商城实战 今日任务 完成用户模块的功能 1.1      网上商城的实战: 1.1.1    演示网上商城的功能: 1.1.2    制作目的: 灵活运用所学知识完成商城实战. 1.1.3    ...

  2. sql还原(.mdf文件还原)

    第一步: 把备份文件放到目录:C:\Program Files\Microsoft SQL Server\MSSQL11.MSSQLSERVER\MSSQL\DATA (默认)(这里用 MyDB.md ...

  3. android studio 2.32躺坑记

    按说这是没啥记录意义的.不过作为一个偶尔用一下ADT开发安卓程序的跨界老码农,遇到一个尴尬事,现在手机已经用上安卓6了,而电脑里的ADT里SDK还是18,19.越来越多的项目是android stud ...

  4. Java内存管理思维导图

    文 by / 林本托 Tips 做一个终身学习的人. 如果想要成为一名合格的 Java 程序员,就必须要涉及和掌握一些 Java 虚拟机的内部结构和特性.最近在读<深入理解Java 虚拟机> ...

  5. 提高java编程质量 - (三)三目运算符的两个操作数类型尽量一致

    先看一个例子: package com.test; public class TernaryOperator { public static void main(String[] args) { in ...

  6. 多个项目MyEclipse中启动出现OutOfMemoryError: PermGen space如何解决

    在MyEclipse中启动程序运行,报错java.lang.OutOfMemoryError: PermGen space应该怎么办?这是eclipse 内存不够的原因. PermGen space的 ...

  7. js删除 object中的空值

    var data = { a: 'a', b: '' } 删除 b和''的配对, /** * Delete all null (or undefined) properties from an obj ...

  8. none 和 host 网络的适用场景 - 每天5分钟玩转 Docker 容器技术(31)

    本章开始讨论 Docker 网络. 我们会首先学习 Docker 提供的几种原生网络,以及如何创建自定义网络.然后探讨容器之间如何通信,以及容器与外界如何交互. Docker 网络从覆盖范围可分为单个 ...

  9. XAML: 获取元素的位置

    在之前讨论 ListView 滚动相关需求的文章中(UWP: ListView 中与滚动有关的两个需求的实现)曾经提到了获取元素相对位置的方法,即某元素相对另一元素的位置.现将所有相关方法再作整理,并 ...

  10. UML简要

    一 概述 1.什么是UML? Unified Modeling Language,统一建模语言,用图形化的语言展示事物的结构,为交流与开发提供了便利. 2.UML分类 UML图形主要有用例图.类图.顺 ...