房地产网站cms,贵阳公司电话号码大全,推广运营平台,西安小程序定制问题背景
hi#xff0c;粉丝朋友们#xff1a; 大家好#xff01;android 10以后TaskView作为替代ActivityView的容器#xff0c;在课程的分屏pip自由窗口专题也进行了相关的详细介绍分析。 这里再补充一下相关的TaskView和桌面内嵌情况下的触摸分析 主要问题点#xff…问题背景
hi粉丝朋友们 大家好android 10以后TaskView作为替代ActivityView的容器在课程的分屏pip自由窗口专题也进行了相关的详细介绍分析。 这里再补充一下相关的TaskView和桌面内嵌情况下的触摸分析 主要问题点 1、明明TaskView属于CarLauncher的一个View凭啥触摸自己的TaskView事件会让TaskView的Activity接收到 2、TaskView的Activity是怎么可以接收事件的呢桌面怎么做到单独只排除TaskView其他地方都可以触摸呢 哈哈简单总结就是要搞清楚TaskView触摸响应原理。
问题分析切入点
一般说道触摸问题分析一想到当然是窗口和input部分的dump信息分析 1、dumpsys activity containers
#1 DefaultTaskDisplayArea typeundefined modefullscreen override-modefullscreen requested-bounds[0,0][0,0] bounds[0,0][1408,792]#2 Task1000011 typestandard modemulti-window override-modemulti-window requested-bounds[404,76][1408,696] bounds[404,76][1408,696]#0 ActivityRecord{38f55a5 u10 com.android.car.mapsplaceholder/.MapsPlaceholderActivity t1000011} typestandard modemulti-window override-modeundefined requested-bounds[0,0][0,0] bounds[404,76][1408,696]#0 60a6fdf com.android.car.mapsplaceholder/com.android.car.mapsplaceholder.MapsPlaceholderActivity typestandard modemulti-window override-modeundefined requested-bounds[0,0][0,0] bounds[404,76][1408,696]#1 Task1 typehome modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][1408,792]#0 Task1000006 typehome modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][1408,792]#0 ActivityRecord{185661 u10 com.android.car.carlauncher/.CarLauncher t1000006} typehome modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][1408,792]#0 6845fdb com.android.car.carlauncher/com.android.car.carlauncher.CarLauncher typehome modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][1408,792]
明显看到地图Activity的Task,windowmode属于multi-window #2 Task1000011 typestandard modemulti-window override-modemulti-window requested-bounds[404,76][1408,696] bounds[404,76][1408,696] 在CarLauncher 的Task windowmode为fullscreen #1 Task1 typehome modefullscreen override-modeundefined requested-bounds[0,0][0,0] bounds[0,0][1408,792]
注意一下地图的Task的bounds区域[404,76][1408,696] ,而CarLauncher的区域属于全屏的 bounds[0,0][1408,792] 这么一看确实桌面的显示bound是包含了地图的Bound
所以这里可以初步理解为
TaskView的地图是可以独立接受触摸时间的因为它本身是独立的bounds区域触摸到了这个区域就行 但是因为和CarLauncher有重叠那么CarLauncher对这个TaskView部分的区域触摸是怎么处理的会接受这一部分的触摸事件吗毕竟这区域又是CarLauncher的一个TaskView区域地图Activity也只是TaskView显示的内容而已 哈哈这里就需要使用我们dumpsys input来解密
adb shell dumpsys input
Input Dispatcher State:DispatchEnabled: trueDispatchFrozen: falseInputFilterEnabled: falseFocusedDisplayId: 0FocusedApplications:displayId0, nameActivityRecord{38f55a5 u10 com.android.car.mapsplaceholder/.MapsPlaceholderActivity t1000011}, dispatchingTimeout5000msFocusedWindows:displayId0, name60a6fdf com.android.car.mapsplaceholder/com.android.car.mapsplaceholder.MapsPlaceholderActivityFocusRequests:displayId0, name60a6fdf com.android.car.mapsplaceholder/com.android.car.mapsplaceholder.MapsPlaceholderActivity resultOKPointer Capture Requested: falseCurrent Window with Pointer Capture: NoneTouchStates: no displays touchedDisplay: 0logicalSize1408x792transform (ROT_0) (IDENTITY)Windows:0: nameaa0d3fc BottomCarSystemBar, id77, displayId0, inputConfigNOT_FOCUSABLE | TRUSTED_OVERLAY | WATCH_OUTSIDE_TOUCH, alpha1.00, frame[0,696][1408,792], globalScale1.000000, applicationInfo.name, applicationInfo.tokennull, touchableRegion[0,696][1408,792], ownerPid1375, ownerUid10150, dispatchingTimeout5000ms, hasToken0x7c04338b1ad0, touchOcclusionModeBLOCK_UNTRUSTEDtransform (ROT_0) (TRANSLATE)1.0000 0.0000 -0.00000.0000 1.0000 -696.00000.0000 0.0000 1.00001: namee8091e TopCarSystemBar, id76, displayId0, inputConfigNOT_FOCUSABLE | TRUSTED_OVERLAY | WATCH_OUTSIDE_TOUCH, alpha1.00, frame[0,0][1408,76], globalScale1.000000, applicationInfo.name, applicationInfo.tokennull, touchableRegion[0,0][1408,76], ownerPid1375, ownerUid10150, dispatchingTimeout5000ms, hasToken0x7c04338d6310, touchOcclusionModeBLOCK_UNTRUSTEDtransform (ROT_0) (IDENTITY)2: nameaff2cfa com.android.car.rotary, id101, displayId0, inputConfigNOT_FOCUSABLE | PREVENT_SPLITTING | TRUSTED_OVERLAY | WATCH_OUTSIDE_TOUCH, alpha1.00, frame[1408,76][1408,76], globalScale1.000000, applicationInfo.name, applicationInfo.tokennull, touchableRegionempty, ownerPid1871, ownerUid1010088, dispatchingTimeout5000ms, hasToken0x7c04338e0bd0, touchOcclusionModeUSE_OPACITYtransform (ROT_0) (TRANSLATE)1.0000 0.0000 -1408.00000.0000 1.0000 -76.00000.0000 0.0000 1.00003: name2cdb9e1 ActivityRecordInputSink com.aospinsight.dummyaidlapp/.MainActivity, id194, displayId0, inputConfigNO_INPUT_CHANNEL | NOT_VISIBLE | NOT_FOCUSABLE | NOT_TOUCHABLE, alpha1.00, frame[0,0][0,0], globalScale0.000000, applicationInfo.name, applicationInfo.tokennull, touchableRegion[-14079,-7919][14080,7920], ownerPid701, ownerUid1000, dispatchingTimeout0ms, hasTokennull, touchOcclusionModeBLOCK_UNTRUSTEDtransform (ROT_0) (IDENTITY)4: name6845fdb com.android.car.carlauncher/com.android.car.carlauncher.CarLauncher, id205, displayId0, inputConfigTRUSTED_OVERLAY, alpha1.00, frame[0,0][1408,792], globalScale1.000000, applicationInfo.nameActivityRecord{185661 u10 com.android.car.carlauncher/.CarLauncher t1000006}, applicationInfo.token0x7c04e3536310, touchableRegion[0,0][1408,76]|[0,76][404,696]|[0,696][1408,792], ownerPid1658, ownerUid1010079, dispatchingTimeout5000ms, hasToken0x7c04338f3cd0, touchOcclusionModeBLOCK_UNTRUSTEDtransform (ROT_0) (IDENTITY)5: name60a6fdf com.android.car.mapsplaceholder/com.android.car.mapsplaceholder.MapsPlaceholderActivity, id223, displayId0, inputConfig0x0, alpha1.00, frame[404,76][1408,696], globalScale1.000000, applicationInfo.nameActivityRecord{38f55a5 u10 com.android.car.mapsplaceholder/.MapsPlaceholderActivity t1000011}, applicationInfo.token0x7c04e355be70, touchableRegion[404,76][1408,696], ownerPid22792, ownerUid1010122, dispatchingTimeout5000ms, hasToken0x7c0433933dd0, touchOcclusionModeBLOCK_UNTRUSTEDtransform (ROT_0) (TRANSLATE)1.0000 0.0000 -404.00000.0000 1.0000 -76.00000.0000 0.0000 1.00006: namea9ab86e ActivityRecordInputSink com.android.car.mapsplaceholder/.MapsPlaceholderActivity, id221, displayId0, inputConfigNO_INPUT_CHANNEL | NOT_FOCUSABLE, alpha1.00, frame[404,76][404,76], globalScale0.000000, applicationInfo.name, applicationInfo.tokennull, touchableRegion[404,76][1408,696], ownerPid701, ownerUid1000, dispatchingTimeout0ms, hasTokennull, touchOcclusionModeBLOCK_UNTRUSTEDtransform (ROT_0) (TRANSLATE)1.0000 0.0000 -404.00000.0000 1.0000 -76.00000.0000 0.0000 1.00007: namec2d4eae ActivityRecordInputSink com.android.car.carlauncher/.CarLauncher, id126, displayId0, inputConfigNO_INPUT_CHANNEL | NOT_FOCUSABLE, alpha1.00, frame[0,0][0,0], globalScale0.000000, applicationInfo.name, applicationInfo.tokennull, touchableRegion[-14079,-7919][14080,7920], ownerPid701, ownerUid1000, dispatchingTimeout0ms, hasTokennull, touchOcclusionModeBLOCK_UNTRUSTED
这里我们只需要重点关注窗口4和窗口5 –桌面Activity 4: name‘6845fdb com.android.car.carlauncher/com.android.car.carlauncher.CarLauncher’, id205, displayId0, inputConfigTRUSTED_OVERLAY, alpha1.00, frame[0,0][1408,792], globalScale1.000000, applicationInfo.nameActivityRecord{185661 u10 com.android.car.carlauncher/.CarLauncher t1000006}, applicationInfo.token0x7c04e3536310, touchableRegion[0,0][1408,76]|[0,76][404,696]|[0,696][1408,792], ownerPid1658, ownerUid1010079, dispatchingTimeout5000ms, hasToken0x7c04338f3cd0, touchOcclusionModeBLOCK_UNTRUSTED transform (ROT_0) (IDENTITY) –地图Activity 5: name‘60a6fdf com.android.car.mapsplaceholder/com.android.car.mapsplaceholder.MapsPlaceholderActivity’, id223, displayId0, inputConfig0x0, alpha1.00, frame[404,76][1408,696], globalScale1.000000, applicationInfo.nameActivityRecord{38f55a5 u10 com.android.car.mapsplaceholder/.MapsPlaceholderActivity t1000011}, applicationInfo.token0x7c04e355be70, touchableRegion[404,76][1408,696], ownerPid22792, ownerUid1010122, dispatchingTimeout5000ms, hasToken0x7c0433933dd0, touchOcclusionModeBLOCK_UNTRUSTED transform (ROT_0) (TRANSLATE) 1.0000 0.0000 -404.0000 0.0000 1.0000 -76.0000 0.0000 0.0000 1.0000
明显发现触摸派发window层级方面还是以桌面为顶部window地图为底下window这样其实也可以理解我们上面的说的情况一样其实整个画面都是CarLauncher的地图Activity也只是CarLauncher的一个View而已。所以当然把桌面作为顶部的派发事件window完全没有问题。 但是问题来了桌面把fullscreen面积占了那么怎么才可以轮到地图Activity
大家注意看看桌面的window的这个属性
touchableRegion[0,0][1408,76]|[0,76][404,696]|[0,696][1408,792], 是不是有个touchableRegion对他就是真相他负责了划定CarLauncher这个window可以响应的触摸区域这里明显看出这个区域划分了看了如下部分
[0,76][404,696]| ----排除TaskView的的地图Activity区域
正常地图Activity的区域是[404,76][1408,696]从404开始到屏幕最右 [0,76][404,696]| 明显是只从0到404就截止了
这里就说明了CarLauncher虽然在顶部但是他的touchRegion根本没有包含地图Activity的区域所以派发事件时候根本不会抢地图Activity的即地图区域的事件不会派发到桌面 总结 问题关键找到了就是靠touchRegion来让CarLauncher不接受地图Activity的Region
哪里设置的TouchRegion呢
这里如果直接寻找比较麻烦可以用dumpsys window windows命令看看window是不是带了
下面就来分析这个桌面的TouchRegion是在哪里设置的呢来看看对应dump代码 frameworks/base/services/core/java/com/android/server/wm/WindowState.java if (dumpAll) {pw.println(prefix mGivenContentInsets mGivenContentInsets.toShortString(sTmpSB) mGivenVisibleInsets mGivenVisibleInsets.toShortString(sTmpSB));if (mTouchableInsets ! 0 || mGivenInsetsPending) {pw.println(prefix mTouchableInsets mTouchableInsets mGivenInsetsPending mGivenInsetsPending);Region region new Region();getTouchableRegion(region);pw.println(prefix touchable region region);}pw.println(prefix mFullConfiguration getConfiguration());pw.println(prefix mLastReportedConfiguration getLastReportedConfiguration());}//再来看看getTouchableRegion方法/** Get the touchable region in global coordinates. */void getTouchableRegion(Region outRegion) {final Rect frame mWindowFrames.mFrame;switch (mTouchableInsets) {default:case TOUCHABLE_INSETS_FRAME:outRegion.set(frame);break;case TOUCHABLE_INSETS_CONTENT:applyInsets(outRegion, frame, mGivenContentInsets);break;case TOUCHABLE_INSETS_VISIBLE:applyInsets(outRegion, frame, mGivenVisibleInsets);break;case TOUCHABLE_INSETS_REGION: {//走的是这里outRegion.set(mGivenTouchableRegion);if (frame.left ! 0 || frame.top ! 0) {outRegion.translate(frame.left, frame.top);}break;}}cropRegionToRootTaskBoundsIfNeeded(outRegion);subtractTouchExcludeRegionIfNeeded(outRegion);}那么这里的mGivenTouchableRegion是哪里设置的呢
frameworks/base/services/core/java/com/android/server/wm/WindowManagerService.java
void setInsetsWindow(Session session, IWindow client, int touchableInsets, Rect contentInsets,Rect visibleInsets, Region touchableRegion) {int uid Binder.getCallingUid();int pid Binder.getCallingPid();final long origId Binder.clearCallingIdentity();try {synchronized (mGlobalLock) {WindowState w windowForClientLocked(session, client, false);if (DEBUG_LAYOUT) Slog.d(TAG, setInsetsWindow w , contentInsets w.mGivenContentInsets - contentInsets , visibleInsets w.mGivenVisibleInsets - visibleInsets , touchableRegion w.mGivenTouchableRegion - touchableRegion , touchableInsets w.mTouchableInsets - touchableInsets);if (w ! null) {w.mGivenInsetsPending false;w.mGivenContentInsets.set(contentInsets);w.mGivenVisibleInsets.set(visibleInsets);w.mGivenTouchableRegion.set(touchableRegion);//这里进行的设置w.mTouchableInsets touchableInsets;if (w.mGlobalScale ! 1) {w.mGivenContentInsets.scale(w.mGlobalScale);w.mGivenVisibleInsets.scale(w.mGlobalScale);w.mGivenTouchableRegion.scale(w.mGlobalScale);}w.setDisplayLayoutNeeded();w.updateSourceFrame(w.getFrame());mWindowPlacerLocked.performSurfacePlacement();w.getDisplayContent().getInputMonitor().updateInputWindowsLw(true);// We need to report touchable region changes to accessibility.if (mAccessibilityController.hasCallbacks()) {mAccessibilityController.onSomeWindowResizedOrMovedWithCallingUid(uid, w.getDisplayContent().getDisplayId());}}}} finally {Binder.restoreCallingIdentity(origId);}}那么接下来再看看谁进行的setInsetsWindow调用 frameworks/base/services/core/java/com/android/server/wm/Session.java Overridepublic void setInsets(IWindow window, int touchableInsets,Rect contentInsets, Rect visibleInsets, Region touchableArea) {mService.setInsetsWindow(this, window, touchableInsets, contentInsets,visibleInsets, touchableArea);}
那么是谁调用了setInsets呢
frameworks/base/libs/WindowManager/Shell/src/com/android/wm/shell/TaskView.java public void onComputeInternalInsets(ViewTreeObserver.InternalInsetsInfo inoutInfo) {// TODO(b/176854108): Consider to move the logic into gatherTransparentRegions since this// is dependent on the order of listener.// If there are multiple TaskViews, well set the touchable area as the root-view, then// subtract each TaskView from it.if (inoutInfo.touchableRegion.isEmpty()) {inoutInfo.setTouchableInsets(ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION);View root getRootView();root.getLocationInWindow(mTmpLocation);mTmpRootRect.set(mTmpLocation[0], mTmpLocation[1], root.getWidth(), root.getHeight());inoutInfo.touchableRegion.set(mTmpRootRect);}getLocationInWindow(mTmpLocation);mTmpRect.set(mTmpLocation[0], mTmpLocation[1],mTmpLocation[0] getWidth(), mTmpLocation[1] getHeight());inoutInfo.touchableRegion.op(mTmpRect, Region.Op.DIFFERENCE);if (mObscuredTouchRegion ! null) {inoutInfo.touchableRegion.op(mObscuredTouchRegion, Region.Op.UNION);}}然后在调用对于的setInsets 在 performTraversals() 中进行相关的调用操作 frameworks/base/core/java/android/view/ViewRootImpl.java
setInsets
更多framework干货课程如下需要的可以私聊马哥 获取优惠 V androidframework007