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 import com.android.server.input.InputManagerService; 31 32 final class HandwritingEventReceiverSurface { 33 34 public static final String TAG = HandwritingEventReceiverSurface.class.getSimpleName(); 35 static final boolean DEBUG = HandwritingModeController.DEBUG; 36 37 private final InputWindowHandle mWindowHandle; 38 private final InputChannel mClientChannel; 39 private final SurfaceControl mInputSurface; 40 private boolean mIsIntercepting; 41 HandwritingEventReceiverSurface(String name, int displayId, @NonNull SurfaceControl sc, @NonNull InputChannel inputChannel)42 HandwritingEventReceiverSurface(String name, int displayId, @NonNull SurfaceControl sc, 43 @NonNull InputChannel inputChannel) { 44 mClientChannel = inputChannel; 45 mInputSurface = sc; 46 47 mWindowHandle = new InputWindowHandle(new InputApplicationHandle(null, name, 48 DEFAULT_DISPATCHING_TIMEOUT_MILLIS), displayId); 49 mWindowHandle.name = name; 50 mWindowHandle.token = mClientChannel.getToken(); 51 mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY; 52 mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS; 53 mWindowHandle.ownerPid = Process.myPid(); 54 mWindowHandle.ownerUid = Process.myUid(); 55 mWindowHandle.scaleFactor = 1.0f; 56 mWindowHandle.inputConfig = 57 InputConfig.NOT_FOCUSABLE 58 | InputConfig.NOT_TOUCHABLE 59 | InputConfig.SPY 60 | InputConfig.INTERCEPTS_STYLUS; 61 62 // Configure the surface to receive stylus events across the entire display. 63 mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */); 64 65 final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); 66 mWindowHandle.setTrustedOverlay(t, mInputSurface, true); 67 t.setInputWindowInfo(mInputSurface, mWindowHandle); 68 t.setLayer(mInputSurface, InputManagerService.INPUT_OVERLAY_LAYER_HANDWRITING_SURFACE); 69 t.setPosition(mInputSurface, 0, 0); 70 t.setCrop(mInputSurface, null /* crop to parent surface */); 71 t.show(mInputSurface); 72 t.apply(); 73 74 mIsIntercepting = false; 75 } 76 startIntercepting(int imePid, int imeUid)77 void startIntercepting(int imePid, int imeUid) { 78 mWindowHandle.ownerPid = imePid; 79 mWindowHandle.ownerUid = imeUid; 80 mWindowHandle.inputConfig &= ~InputConfig.SPY; 81 82 new SurfaceControl.Transaction() 83 .setInputWindowInfo(mInputSurface, mWindowHandle) 84 .apply(); 85 mIsIntercepting = true; 86 } 87 setNotTouchable(boolean notTouchable)88 void setNotTouchable(boolean notTouchable) { 89 if (notTouchable) { 90 mWindowHandle.inputConfig |= InputConfig.NOT_TOUCHABLE; 91 } else { 92 mWindowHandle.inputConfig &= ~InputConfig.NOT_TOUCHABLE; 93 } 94 new SurfaceControl.Transaction() 95 .setInputWindowInfo(mInputSurface, mWindowHandle) 96 .apply(); 97 } 98 isIntercepting()99 boolean isIntercepting() { 100 return mIsIntercepting; 101 } 102 remove()103 void remove() { 104 final SurfaceControl.Transaction t = new SurfaceControl.Transaction(); 105 t.remove(mInputSurface); 106 t.apply(); 107 } 108 getInputChannel()109 InputChannel getInputChannel() { 110 return mClientChannel; 111 } 112 getSurface()113 SurfaceControl getSurface() { 114 return mInputSurface; 115 } 116 getInputWindowHandle()117 InputWindowHandle getInputWindowHandle() { 118 return mWindowHandle; 119 } 120 } 121