• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.android.server.inputmethod;
18 
19 import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
20 
21 import android.annotation.NonNull;
22 import android.os.InputConfig;
23 import android.os.Process;
24 import android.view.InputApplicationHandle;
25 import android.view.InputChannel;
26 import android.view.InputWindowHandle;
27 import android.view.SurfaceControl;
28 import android.view.WindowManager;
29 
30 final class HandwritingEventReceiverSurface {
31 
32     public static final String TAG = HandwritingEventReceiverSurface.class.getSimpleName();
33     static final boolean DEBUG = HandwritingModeController.DEBUG;
34 
35     // Place the layer below the highest layer to place it under gesture monitors. If the surface
36     // is above gesture monitors, then edge-back and swipe-up gestures won't work when this surface
37     // is intercepting.
38     // TODO(b/217538817): Specify the ordering in WM by usage.
39     private static final int HANDWRITING_SURFACE_LAYER = Integer.MAX_VALUE - 1;
40 
41     private final InputWindowHandle mWindowHandle;
42     private final InputChannel mClientChannel;
43     private final SurfaceControl mInputSurface;
44     private boolean mIsIntercepting;
45 
HandwritingEventReceiverSurface(String name, int displayId, @NonNull SurfaceControl sc, @NonNull InputChannel inputChannel)46     HandwritingEventReceiverSurface(String name, int displayId, @NonNull SurfaceControl sc,
47             @NonNull InputChannel inputChannel) {
48         mClientChannel = inputChannel;
49         mInputSurface = sc;
50 
51         mWindowHandle = new InputWindowHandle(new InputApplicationHandle(null, name,
52                 DEFAULT_DISPATCHING_TIMEOUT_MILLIS), displayId);
53         mWindowHandle.name = name;
54         mWindowHandle.token = mClientChannel.getToken();
55         mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
56         mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
57         mWindowHandle.ownerPid = Process.myPid();
58         mWindowHandle.ownerUid = Process.myUid();
59         mWindowHandle.scaleFactor = 1.0f;
60         mWindowHandle.inputConfig =
61                 InputConfig.NOT_FOCUSABLE
62                         | InputConfig.NOT_TOUCHABLE
63                         | InputConfig.SPY
64                         | InputConfig.INTERCEPTS_STYLUS
65                         | InputConfig.TRUSTED_OVERLAY;
66 
67         // Configure the surface to receive stylus events across the entire display.
68         mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
69 
70         final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
71         t.setInputWindowInfo(mInputSurface, mWindowHandle);
72         t.setLayer(mInputSurface, HANDWRITING_SURFACE_LAYER);
73         t.setPosition(mInputSurface, 0, 0);
74         t.setCrop(mInputSurface, null /* crop to parent surface */);
75         t.show(mInputSurface);
76         t.apply();
77 
78         mIsIntercepting = false;
79     }
80 
startIntercepting(int imePid, int imeUid)81     void startIntercepting(int imePid, int imeUid) {
82         mWindowHandle.ownerPid = imePid;
83         mWindowHandle.ownerUid = imeUid;
84         mWindowHandle.inputConfig &= ~InputConfig.SPY;
85 
86         new SurfaceControl.Transaction()
87                 .setInputWindowInfo(mInputSurface, mWindowHandle)
88                 .apply();
89         mIsIntercepting = true;
90     }
91 
isIntercepting()92     boolean isIntercepting() {
93         return mIsIntercepting;
94     }
95 
remove()96     void remove() {
97         final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
98         t.remove(mInputSurface);
99         t.apply();
100     }
101 
getInputChannel()102     InputChannel getInputChannel() {
103         return mClientChannel;
104     }
105 
getSurface()106     SurfaceControl getSurface() {
107         return mInputSurface;
108     }
109 
getInputWindowHandle()110     InputWindowHandle getInputWindowHandle() {
111         return mWindowHandle;
112     }
113 }
114