InputMethodManager input method window why dumpsys is full screen? Qianlima helps you solve problems related to input methods

background:

Hi, fans and friends:
Hello everyone! Recently, some fans and friends have been discussing input methods in the group. In fact, Brother Ma has studied this part before, so he is relatively familiar with it. In fact, the idea of ​​designing input methods for Android is exactly the same as wallpapers. The general design drawing is as follows:
Insert image description here

The generally seen input method interface is the input method process, which generally implements a subclass of InputMethodService, in which a corresponding input method window display will be created, so here it is necessary to explain that the input method is not an Activity, it is just a global window. , the same as the status bar or something.

A classmate just happened to ask a question about the input method. Why does it appear that the input method is full screen when using dumpsys window windows and dumpsys SurfaceFlinger? What's going on?

1. Dumpsys related SurfaceFlinger and window to see the full screen situation

The following is the SurfaceFlinger layer situation of winsocpe.
Insert image description hereIndeed, the activebuffer of the windowstate of the corresponding InputMethod in SurfaceFlinger seen here is indeed full screen:

activeBuffer : w:1440, h:2876, stride:2816, format:1

Take a look at the corresponding window-related information:
Insert image description herethe size also displayed is
frame: (0, 84) - (1440, 2960), which
are also full screen.

2. Question point: Since the input method is full screen, why can the activity still respond to events?

First show partially obscured understanding:

This part is relatively easy to understand, because although the window occupies the whole screen, it can be partially transparent and see through to the window at the bottom.

Second touch part:

Judging from the hierarchical structure, the input method should be covered on the Activity window, and the input method is full-screen, so theoretically all touch events should go to the input method window, not the Activity window.
But the actual situation is as shown below:
Insert image description here

That is, only the part displayed by the input method can be touched by the input method. If you touch the part of the activity, the activity will respond to the corresponding touch event.

To answer this question, you need to use the knowledge of our input course:
If you want to try the course, you can click here: https://www.bilibili.com/video/BV1YS4y1K7rj/
You can also +w: androidframework007 Find me
Insert image description here
to learn and view dumpsys input Output information:


Input Dispatcher State:
  DispatchEnabled: true
  DispatchFrozen: false
  InputFilterEnabled: false
  FocusedDisplayId: 0
  FocusedApplications:
    displayId=0, name='ActivityRecord{49e3140 u0 com.android.quicksearchbox/.SearchActivity} t439}', dispatchingTimeout=5000ms
  FocusedWindows:
    displayId=0, name='313a198 com.android.quicksearchbox/com.android.quicksearchbox.SearchActivity'
  FocusRequests:
    displayId=0, name='313a198 com.android.quicksearchbox/com.android.quicksearchbox.SearchActivity' result='OK'
  Pointer Capture Requested: false
  Current Window with Pointer Capture: None
  TouchStates: <no displays touched>
  Display: 0
    logicalSize=1440x2960
        transform (ROT_0) (IDENTITY)
    Windows:
      0: name='[Gesture Monitor] swipe-up', id=106, displayId=0, inputConfig=NOT_FOCUSABLE | TRUSTED_OVERLAY | SPY, alpha=1.00, frame=[0,0][0,0], globalScale=1.000000, applicationInfo.name=[Gesture Monitor] swipe-up, applicationInfo.token=<null>, touchableRegion=[-14399,-29599][14400,29600], ownerPid=1047, ownerUid=10097, dispatchingTimeout=5000ms, hasToken=true, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      1: name='[Gesture Monitor] edge-swipe', id=81, displayId=0, inputConfig=NOT_FOCUSABLE | TRUSTED_OVERLAY | SPY, alpha=1.00, frame=[0,0][0,0], globalScale=1.000000, applicationInfo.name=[Gesture Monitor] edge-swipe, applicationInfo.token=<null>, touchableRegion=[-14399,-29599][14400,29600], ownerPid=762, ownerUid=10099, dispatchingTimeout=5000ms, hasToken=true, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      2: name='StrictModeFlash', id=93, displayId=0, inputConfig=NO_INPUT_CHANNEL | NOT_VISIBLE | NOT_FOCUSABLE | NOT_TOUCHABLE | PREVENT_SPLITTING | TRUSTED_OVERLAY, alpha=1.00, frame=[0,0][1440,2960], globalScale=1.000000, applicationInfo.name=, applicationInfo.token=<null>, touchableRegion=<empty>, ownerPid=0, ownerUid=0, dispatchingTimeout=0ms, hasToken=false, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      3: name='4b4d6f1 PointerLocation - display 0', id=49, displayId=0, inputConfig=NO_INPUT_CHANNEL | NOT_FOCUSABLE | NOT_TOUCHABLE | PREVENT_SPLITTING | TRUSTED_OVERLAY, alpha=1.00, frame=[0,0][1440,2960], globalScale=1.000000, applicationInfo.name=, applicationInfo.token=<null>, touchableRegion=<empty>, ownerPid=572, ownerUid=1000, dispatchingTimeout=0ms, hasToken=false, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      4: name='6f6f2e3 NavigationBar0', id=86, displayId=0, inputConfig=NOT_FOCUSABLE | TRUSTED_OVERLAY | WATCH_OUTSIDE_TOUCH, alpha=1.00, frame=[0,2792][1440,2960], globalScale=1.000000, applicationInfo.name=, applicationInfo.token=<null>, touchableRegion=<empty>, ownerPid=762, ownerUid=10099, dispatchingTimeout=5000ms, hasToken=true, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (TRANSLATE)
            1.0000  0.0000  -0.0000
            0.0000  1.0000  -2792.0000
            0.0000  0.0000  1.0000
      5: name='1afd988 StatusBar', id=87, displayId=0, inputConfig=NOT_FOCUSABLE | TRUSTED_OVERLAY, alpha=1.00, frame=[0,0][1440,84], globalScale=1.000000, applicationInfo.name=, applicationInfo.token=<null>, touchableRegion=[0,0][1440,84], ownerPid=762, ownerUid=10099, dispatchingTimeout=5000ms, hasToken=true, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      6: name='recents_animation_input_consumer', id=101, displayId=0, inputConfig=NOT_VISIBLE | TRUSTED_OVERLAY, alpha=1.00, frame=[0,0][1440,2960], globalScale=1.000000, applicationInfo.name=recents_animation_input_consumer, applicationInfo.token=0x77cb0493d7d0, touchableRegion=[0,0][1440,2960], ownerPid=572, ownerUid=1000, dispatchingTimeout=5000ms, hasToken=true, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      7: name='99d71b InputMethod', id=278, displayId=0, inputConfig=NOT_FOCUSABLE | TRUSTED_OVERLAY, alpha=1.00, frame=[0,84][1440,2960], globalScale=1.000000, applicationInfo.name=, applicationInfo.token=<null>, touchableRegion=[0,1759][1440,2960], ownerPid=1194, ownerUid=10081, dispatchingTimeout=5000ms, hasToken=true, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (TRANSLATE)
            1.0000  -0.0000  0.0000
            -0.0000  1.0000  -84.0000
            0.0000  0.0000  1.0000
      8: name='313a198 com.android.quicksearchbox/com.android.quicksearchbox.SearchActivity', id=273, displayId=0, inputConfig=0x0, alpha=1.00, frame=[0,0][1440,2960], globalScale=1.000000, applicationInfo.name=ActivityRecord{
    
    49e3140 u0 com.android.quicksearchbox/.SearchActivity} t439}, applicationInfo.token=0x77cb04980b50, touchableRegion=[0,0][1440,2960], ownerPid=1441, ownerUid=10084, dispatchingTimeout=5000ms, hasToken=true, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      9: name='c6a010e ActivityRecordInputSink com.android.quicksearchbox/.SearchActivity', id=120, 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=[-14399,-29599][14400,29600], ownerPid=572, ownerUid=1000, dispatchingTimeout=0ms, hasToken=false, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      10: name='efb17ce ActivityRecordInputSink com.android.camera2/com.android.camera.CameraActivity', id=141, displayId=0, inputConfig=NO_INPUT_CHANNEL | NOT_VISIBLE | NOT_FOCUSABLE | NOT_TOUCHABLE, alpha=1.00, frame=[0,0][0,0], globalScale=0.000000, applicationInfo.name=, applicationInfo.token=<null>, touchableRegion=[-14399,-29599][14400,29600], ownerPid=572, ownerUid=1000, dispatchingTimeout=0ms, hasToken=false, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      11: name='8dd0f70 ActivityRecordInputSink com.android.settings/.SubSettings', id=213, displayId=0, inputConfig=NO_INPUT_CHANNEL | NOT_VISIBLE | NOT_FOCUSABLE | NOT_TOUCHABLE, alpha=1.00, frame=[0,0][0,0], globalScale=0.000000, applicationInfo.name=, applicationInfo.token=<null>, touchableRegion=[0,0][1440,2960], ownerPid=572, ownerUid=1000, dispatchingTimeout=0ms, hasToken=false, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      12: name='214bf5f ActivityRecordInputSink com.android.settings/.SubSettings', id=196, displayId=0, inputConfig=NO_INPUT_CHANNEL | NOT_VISIBLE | NOT_FOCUSABLE | NOT_TOUCHABLE, alpha=1.00, frame=[0,0][0,0], globalScale=0.000000, applicationInfo.name=, applicationInfo.token=<null>, touchableRegion=[0,0][1440,2960], ownerPid=572, ownerUid=1000, dispatchingTimeout=0ms, hasToken=false, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      13: name='2001b8f ActivityRecordInputSink com.android.settings/.homepage.SettingsHomepageActivity', id=178, displayId=0, inputConfig=NO_INPUT_CHANNEL | NOT_VISIBLE | NOT_FOCUSABLE | NOT_TOUCHABLE, alpha=1.00, frame=[0,0][0,0], globalScale=0.000000, applicationInfo.name=, applicationInfo.token=<null>, touchableRegion=[0,0][1440,2960], ownerPid=572, ownerUid=1000, dispatchingTimeout=0ms, hasToken=false, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      14: name='edb3266 com.android.launcher3/com.android.launcher3.uioverrides.QuickstepLauncher', id=266, displayId=0, inputConfig=DUPLICATE_TOUCH_TO_WALLPAPER, alpha=1.00, frame=[0,0][1440,2960], globalScale=1.000000, applicationInfo.name=ActivityRecord{
    
    c22322a u0 com.android.launcher3/.uioverrides.QuickstepLauncher} t437}, applicationInfo.token=0x77cb049417f0, touchableRegion=[0,0][1440,2960], ownerPid=1047, ownerUid=10097, dispatchingTimeout=5000ms, hasToken=true, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      15: name='91a1ad2 ActivityRecordInputSink com.android.launcher3/.uioverrides.QuickstepLauncher', id=109, 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=[-14399,-29599][14400,29600], ownerPid=572, ownerUid=1000, dispatchingTimeout=0ms, hasToken=false, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (IDENTITY)
      16: name='Wallpaper BBQ wrapper#79', id=79, displayId=0, inputConfig=NO_INPUT_CHANNEL, alpha=1.00, frame=[-71,-147][1760,3108], globalScale=1.000000, applicationInfo.name=, applicationInfo.token=<null>, touchableRegion=<empty>, ownerPid=762, ownerUid=10099, dispatchingTimeout=5000ms, hasToken=false, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (SCALE TRANSLATE)
            0.5160  -0.0000  37.1499
            -0.0000  0.5160  76.3636
            0.0000  0.0000  1.0000
      17: name='b2dd605 com.android.systemui.ImageWallpaper', id=78, displayId=0, inputConfig=NOT_FOCUSABLE | NOT_TOUCHABLE | PREVENT_SPLITTING | IS_WALLPAPER, alpha=1.00, frame=[-71,-147][-71,-147], globalScale=1.000000, applicationInfo.name=, applicationInfo.token=<null>, touchableRegion=<empty>, ownerPid=762, ownerUid=10099, dispatchingTimeout=5000ms, hasToken=true, touchOcclusionMode=BLOCK_UNTRUSTED
        transform (ROT_0) (SCALE TRANSLATE)
            0.5160  -0.0000  37.1499
            -0.0000  0.5160  76.3636
            0.0000  0.0000  1.0000


The above are all the situations where the window is touched in the input. We focus on the InputMethod window:

7: name=‘99d71b InputMethod’, id=278, displayId=0, inputConfig=NOT_FOCUSABLE | TRUSTED_OVERLAY, alpha=1.00, frame=[0,84][1440,2960], globalScale=1.000000, applicationInfo.name=, applicationInfo.token=, touchableRegion=[0,1759][1440,2960], ownerPid=1194, ownerUid=10081, dispatchingTimeout=5000ms, hasToken=true, touchOcclusionMode=BLOCK_UNTRUSTED
transform (ROT_0) (TRANSLATE)
1.0000 -0.0000 0.0000
-0.0000 1.0000 -84.0000
0.0000 0.0000 1.0000

You can see that the screen size is indeed frame=[0,84][1440,2960], but there is a touchableRegion=[0,1759][1440,2960]. This area is the real touch area. Here we You can see the trick here. The y here can only be touched from the 1759 position, which is the keyboard area of ​​the input method we saw above.
That is, this touchableRegion explains why the touch events in the upper area are not sent to the input method window, because the touch area of ​​the input method window does not include that part, so the touch events in the upper area will continue to be passed to the lower window, that is, the Activity window.
So the question is, where is this touchableRegion set up?

3. touchableRegion settings tracking

Here we know that the window in general input is set by InputMonitor: The following similar code was found in
frameworks/base/services/core/java/com/android/server/wm/InputMonitor.java :

            inputWindowHandle.setTouchableRegion(mTmpRegion);

Add the corresponding stack printing
frameworks/base/services/core/java/com/android/server/wm/InputWindowHandleWrapper.java to this method

   void setTouchableRegion(Region region) {
    
    
        if (mHandle.touchableRegion.equals(region)) {
    
    
            return;
        }
      if (region.getBounds().top > 1000) {
    
    
            android.util.Log.i("lsm111","setTouchableRegion " + region + " mHandle = "+mHandle,new Exception());
       }
        mHandle.touchableRegion.set(region);
        mChanged = true;
    }

Related stack setTouchableRegion

* daemon started successfully
--------- beginning of main
09-15 11:59:46.669   572   593 I lsm111  : setTouchableRegion SkRegion((0,1675,1440,2876))
09-15 11:59:46.669   572   593 I lsm111  : java.lang.Exception
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.InputWindowHandleWrapper.setTouchableRegion(InputWindowHandleWrapper.java:146)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.InputMonitor.populateInputWindowHandle(InputMonitor.java:315)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.InputMonitor$UpdateInputForAllWindowsConsumer.accept(InputMonitor.java:636)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.InputMonitor$UpdateInputForAllWindowsConsumer.accept(InputMonitor.java:508)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:2624)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowContainer$ForAllWindowsConsumerWrapper.apply(WindowContainer.java:2614)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowState.applyInOrderWithImeWindows(WindowState.java:4903)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowState.forAllWindows(WindowState.java:4747)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1611)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1611)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.DisplayContent$ImeContainer.forAllWindowForce(DisplayContent.java:5175)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.DisplayContent.forAllImeWindows(DisplayContent.java:2814)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowState.applyImeWindowsIfNeeded(WindowState.java:4896)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowState.applyInOrderWithImeWindows(WindowState.java:4902)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowState.forAllWindows(WindowState.java:4747)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1611)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1611)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1611)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1611)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1611)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1611)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1611)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1611)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.WindowContainer.forAllWindows(WindowContainer.java:1628)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.InputMonitor$UpdateInputForAllWindowsConsumer.updateInputWindows(InputMonitor.java:548)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.InputMonitor$UpdateInputForAllWindowsConsumer.-$$Nest$mupdateInputWindows(Unknown Source:0)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.wm.InputMonitor$UpdateInputWindows.run(InputMonitor.java:134)
09-15 11:59:46.669   572   593 I lsm111  : 	at android.os.Handler.handleCallback(Handler.java:942)
09-15 11:59:46.669   572   593 I lsm111  : 	at android.os.Handler.dispatchMessage(Handler.java:99)
09-15 11:59:46.669   572   593 I lsm111  : 	at android.os.Looper.loopOnce(Looper.java:201)
09-15 11:59:46.669   572   593 I lsm111  : 	at android.os.Looper.loop(Looper.java:288)
09-15 11:59:46.669   572   593 I lsm111  : 	at android.os.HandlerThread.run(HandlerThread.java:67)
09-15 11:59:46.669   572   593 I lsm111  : 	at com.android.server.ServiceThread.run(ServiceThread.java:44)

It can be seen that the setTouchableRegion setting here is triggered by
InputMonitor$UpdateInputForAllWindowsConsumer.updateInputWindows

So where does Region come from?

   if (!useSurfaceBoundsAsTouchRegion) {
    
    
   //实际是调用了WindowState的getSurfaceTouchableRegion方法
            w.getSurfaceTouchableRegion(mTmpRegion, w.mAttrs);
            inputWindowHandle.setTouchableRegion(mTmpRegion);
        }

Here the getTouchableRegion method of WindowState is called back:

    /** Get the touchable region in global coordinates. */
    void getTouchableRegion(Region outRegion) {
    
    
        final Rect frame = mWindowFrames.mFrame;
        switch (mTouchableInsets) {
    
    //关键的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);
    }

The question is where does mGivenTouchableRegion come from? Haha, after searching here, I found that the value is assigned in WindowManagerService. The specific stack is as follows:

09-15 16:09:34.367   551  1330 I lsm111  : Window{
    
    e201e2f u0 InputMethod} touchableRegion = SkRegion((0,1675,1440,2876))
09-15 16:09:34.367   551  1330 I lsm111  : java.lang.Exception
09-15 16:09:34.367   551  1330 I lsm111  : 	at com.android.server.wm.WindowManagerService.setInsetsWindow(WindowManagerService.java:2165)
09-15 16:09:34.367   551  1330 I lsm111  : 	at com.android.server.wm.Session.setInsets(Session.java:279)
09-15 16:09:34.367   551  1330 I lsm111  : 	at android.view.IWindowSession$Stub.onTransact(IWindowSession.java:813)
09-15 16:09:34.367   551  1330 I lsm111  : 	at com.android.server.wm.Session.onTransact(Session.java:175)
09-15 16:09:34.367   551  1330 I lsm111  : 	at android.os.Binder.execTransactInternal(Binder.java:1285)
09-15 16:09:34.367   551  1330 I lsm111  : 	at android.os.Binder.execTransact(Binder.java:1244)

It is the Inset set by the call initiated by the client. This is equivalent to the Inset part. It is the same thing as the status bar and navigation bar. I will not analyze it in depth here.

Guess you like

Origin blog.csdn.net/learnframework/article/details/132899347