ActivityRecordInputSink深入剖析全网独家分析

背景:

学员粉丝朋友们在学习马哥的android framework实战高级课程时候,有一些细心的学员提出了一个无问题,那就是再看dumpsys SurfaceFlinger的图层或者是dumpsys input相关信息时候发现了一个叫做ActivityRecordInputSink的图层。

如下图所示:
dumpsys input可以看到一个ActivityRecordInputSink在Activity的下面
在这里插入图片描述
再看看sf的相关:

在这里插入图片描述以上都看到了一个ActivityRecordInputSink的图层,那么这个图层到底有啥作用呢?其实网络上基本上也没有资料,我这边blog算是一个开疆扩土的探索。。。

线索寻找1:

找到这个类看看有没有相关注释:
在这里插入图片描述
个人翻译理解:

* Creates a InputWindowHandle that catches all touches that would otherwise pass through an
 * Activity.

字面翻译就是ActivityRecordInputSink会捕获所有本身会穿透Activity的触摸,即ActivityRecordInputSink就相当于一张大网,Activity有点相当于大网上面有一张小网。
即正常情况下Activity这个小网和手机屏幕都是一样大小,所以这个时候其实ActivityRecordInputSink就没啥存在感,因为本身Activity的任何事件都会捕获,根本不会有漏网之鱼事件到ActivityRecordInputSink。
在这里插入图片描述
上图展示的Activity大小和手机屏幕大小一样,所以手机触摸事件根本到达不了ActivityRecordInputSink这个地方。
其实这个也就是ActivityRecordInputSink为啥没引起大家重视原因,因为我们大部分情况下都遇不到它。
可以看看正常情况下两者的dumpsys input的touch区域:

      5: name='8bdb43d com.android.messaging/com.android.messaging.ui.conversationlist.ConversationListActivity', id=567, displayId=0, inputConfig=0x0, alpha=1.00, frame=[0,0][1080,2160], globalScale=1.000000, applicationInfo.name=ActivityRecord{4e0ab6e u0 com.android.messaging/.ui.conversationlist.ConversationListActivity} t201}, applicationInfo.token=0x792c4556f0, touchableRegion=[0,0][1080,2160], ownerPid=3580, ownerUid=10127, dispatchingTimeout=5000ms, hasToken=true, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      6: name='a06edb3 ActivityRecordInputSink com.android.messaging/.ui.conversationlist.ConversationListActivity', id=210, displayId=0, inputConfig=NO_INPUT_CHANNEL | NOT_FOCUSABLE, alpha=1.00, frame=[0,0][0,0], globalScale=0.000000, applicationInfo.name=, applicationInfo.token=<null>, touchableRegion=[-10799,-21599][10800,21600], ownerPid=1887, ownerUid=1000, dispatchingTimeout=0ms, hasToken=false, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)

可以看到Activity的窗口显示大小就是touchableRegion=[0,0][1080,2160]即和屏幕大小一样,而ActivityRecordInputSink大小是touchableRegion=[-10799,-21599][10800,21600]明显比手机屏幕大很多,这种Activity大小和手机手机屏幕一样,触摸事件正常都不可能到这里。

线索寻找2

那么什么情况下下这个ActivityRecordInputSink才会有相关的作用的呢?
继续寻找一下ActivityRecordInputSink这个类提交log线索:

git log提交

commit 1bc541e8950824f223dc2aba43f09c20f96189a9
Author: Linus Tufvesson <lus@google.com>
Date:   Wed Nov 3 13:56:24 2021 +0000

    Block touches from passing through activities
    
    By setting an InputWindowHandle for ActivityRecord it is no longer
    possible for Activities to shrink their own window size to allow touches
    to pass through to activities behind. The touchable region is cropped by
    the parent, meaning that it will occupy all availble space.
    
    Feature is disabled by default and can be enabled per package using adb
    shell am compat enable ENABLE_TOUCH_OPAQUE_ACTIVITIES <package>
    
    Test: Manually enabled appcompat feature and verified with sample from
    b/194480991 that touches are blocked.

核心语句翻译:
By setting an InputWindowHandle for ActivityRecord it is no longer
possible for Activities to shrink their own window size to allow touches
to pass through to activities behind. The touchable region is cropped by
the parent, meaning that it will occupy all availble space.

即一旦有了ActivityRecordInputSink后就没有可能出现Activity自己窗口缩小允许触摸事件传递到Activity底部的窗口情况,所有的触摸都会被ActivityRecordInputSink获取。

在这里插入图片描述
如上图activity可能比屏幕小,但是触摸在activity外的触摸不会被传递给底部的window,因为会被ActivityRecordInputSink收走。

通过实际dumpsys来验证看看是否真的是这么一回事?

      5: name='4d95871 com.example.myapplication11/com.example.myapplication11.MainActivity', id=1974, displayId=0, inputConfig=0x0, alpha=1.00, frame=[0,0][864,1536], globalScale=1.000000, applicationInfo.name=ActivityRecord{596e7da u0 com.example.myapplication11/.MainActivity} t51}, applicationInfo.token=0x6f95368f10, touchableRegion=[0,0][864,1536], ownerPid=12666, ownerUid=10138, dispatchingTimeout=5000ms, hasToken=true, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (SCALE )
            1.2500  -0.0000  0.0000
            -0.0000  1.2500  0.0000
            0.0000  0.0000  1.0000
      6: name='1b027ef ActivityRecordInputSink com.example.myapplication11/.MainActivity', id=1979, displayId=0, inputConfig=NO_INPUT_CHANNEL | NOT_FOCUSABLE, alpha=1.00, frame=[0,0][0,0], globalScale=0.000000, applicationInfo.name=, applicationInfo.token=<null>, touchableRegion=[-10799,-19199][10800,19200], ownerPid=9926, ownerUid=1000, dispatchingTimeout=0ms, hasToken=false, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      7: name='9fe7939 com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher', id=1952, displayId=0, inputConfig=DUPLICATE_TOUCH_TO_WALLPAPER, alpha=1.00, frame=[0,0][1080,1920], globalScale=1.000000, applicationInfo.name=ActivityRecord{228f121 u0 com.android.launcher3/.uioverrides.QuickstepLauncher} t45}, applicationInfo.token=0x6f95359f70, touchableRegion=[0,0][1080,1920], ownerPid=10363, ownerUid=10111, dispatchingTimeout=5000ms, hasToken=true, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      8: name='ada6de9 ActivityRecordInputSink com.android.launcher3/.uioverrides.QuickstepLauncher', id=1851, displayId=0, inputConfig=NO_INPUT_CHANNEL | NOT_FOCUSABLE, alpha=1.00, frame=[0,0][0,0], globalScale=0.000000, applicationInfo.name=, applicationInfo.token=<null>, touchableRegion=[-10799,-19199][10800,19200], ownerPid=9926, ownerUid=1000, dispatchingTimeout=0ms, hasToken=false, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)

上面可以看到4d95871 com.example.myapplication11/com.example.myapplication11.MainActivity 这个Activity触摸大小区域:
touchableRegion=[0,0][864,1536]

屏幕大小是1080x1920
但是底下的ActivityRecordInputSink的大小如下
ActivityRecordInputSink com.example.myapplication11/.MainActivity

touchableRegion=[-10799,-19199][10800,19200],
所以有ActivityRecordInputSink在触摸事件不会传递给下面的Launcher

在这里插入图片描述

本文章更多详细代码和资料需要购买课程获取

七件套专题:在这里插入图片描述
点击这里
https://mp.weixin.qq.com/s/Qv8zjgQ0CkalKmvi8tMGaw

hal+perfetto+surfaceflinger
https://mp.weixin.qq.com/s/LbVLnu1udqExHVKxd74ILg
在这里插入图片描述

私聊作者+v(androidframework007)

视频试看:
https://www.bilibili.com/video/BV1wc41117L4/

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值