1 /* 2 * Copyright (C) 2011 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 android.view; 18 19 import android.annotation.IntDef; 20 import android.annotation.Nullable; 21 import android.graphics.Matrix; 22 import android.graphics.Region; 23 import android.gui.TouchOcclusionMode; 24 import android.os.IBinder; 25 import android.os.InputConfig; 26 27 import java.lang.annotation.Retention; 28 import java.lang.annotation.RetentionPolicy; 29 import java.lang.ref.WeakReference; 30 31 /** 32 * Functions as a handle for a window that can receive input, and allows for the behavior of the 33 * input window to be configured. 34 * @hide 35 */ 36 public final class InputWindowHandle { 37 38 /** 39 * An internal annotation for all the {@link android.os.InputConfig} flags that can be 40 * specified to {@link #inputConfig} to control the behavior of an input window. Only the 41 * flags listed here are valid for use in Java. 42 * 43 * The default flag value is 0, which is what we expect for a normal application window. Adding 44 * a flag indicates that the window's behavior deviates from that of a normal application 45 * window. 46 * 47 * The flags are defined as an AIDL enum to keep it in sync with native code. 48 * {@link android.os.InputConfig} flags that are not listed here should not be used in Java, and 49 * are only meant to be used in native code. 50 */ 51 @Retention(RetentionPolicy.SOURCE) 52 @IntDef(flag = true, value = { 53 InputConfig.DEFAULT, 54 InputConfig.NO_INPUT_CHANNEL, 55 InputConfig.NOT_FOCUSABLE, 56 InputConfig.NOT_TOUCHABLE, 57 InputConfig.PREVENT_SPLITTING, 58 InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER, 59 InputConfig.IS_WALLPAPER, 60 InputConfig.PAUSE_DISPATCHING, 61 InputConfig.TRUSTED_OVERLAY, 62 InputConfig.WATCH_OUTSIDE_TOUCH, 63 InputConfig.SLIPPERY, 64 InputConfig.DISABLE_USER_ACTIVITY, 65 InputConfig.SPY, 66 InputConfig.INTERCEPTS_STYLUS, 67 InputConfig.CLONE, 68 }) 69 public @interface InputConfigFlags {} 70 71 // Pointer to the native input window handle. 72 // This field is lazily initialized via JNI. 73 @SuppressWarnings("unused") 74 private long ptr; 75 76 // The input application handle. 77 public InputApplicationHandle inputApplicationHandle; 78 79 // The token associates input data with a window and its input channel. The client input 80 // channel and the server input channel will both contain this token. 81 public IBinder token; 82 83 /** 84 * The {@link IWindow} handle if InputWindowHandle is associated with a window, null otherwise. 85 */ 86 @Nullable 87 private IBinder windowToken; 88 /** 89 * Used to cache IWindow from the windowToken so we don't need to convert every time getWindow 90 * is called. 91 */ 92 private IWindow window; 93 94 // The window name. 95 public String name; 96 97 // Window layout params attributes. (WindowManager.LayoutParams) 98 // These values do not affect any input configurations. Use {@link #inputConfig} instead. 99 public int layoutParamsFlags; 100 public int layoutParamsType; 101 102 // Dispatching timeout. 103 public long dispatchingTimeoutMillis; 104 105 // Window frame. 106 public int frameLeft; 107 public int frameTop; 108 public int frameRight; 109 public int frameBottom; 110 111 public int surfaceInset; 112 113 // Global scaling factor applied to touch events when they are dispatched 114 // to the window 115 public float scaleFactor; 116 117 // Window touchable region. 118 public final Region touchableRegion = new Region(); 119 120 // Flags that specify the behavior of this input window. See {@link #InputConfigFlags}. 121 @InputConfigFlags 122 public int inputConfig; 123 124 // What effect this window has on touch occlusion if it lets touches pass through 125 // By default windows will block touches if they are untrusted and from a different UID due to 126 // security concerns 127 public int touchOcclusionMode = TouchOcclusionMode.BLOCK_UNTRUSTED; 128 129 // Id of process and user that owns the window. 130 public int ownerPid; 131 public int ownerUid; 132 133 // Owner package of the window 134 public String packageName; 135 136 // Display this input window is on. 137 public int displayId; 138 139 /** 140 * Crops the {@link #touchableRegion} to the bounds of the surface provided. 141 * 142 * This can be used in cases where the window should be constrained to the bounds of a parent 143 * window. That is, the window should receive touch events outside its window frame, but be 144 * limited to its stack bounds, such as in the case of split screen. 145 */ 146 public WeakReference<SurfaceControl> touchableRegionSurfaceControl = new WeakReference<>(null); 147 148 /** 149 * Replace {@link #touchableRegion} with the bounds of {@link #touchableRegionSurfaceControl}. 150 * If the handle is {@code null}, the bounds of the surface associated with this window is used 151 * as the touchable region. 152 */ 153 public boolean replaceTouchableRegionWithCrop; 154 155 /** 156 * The transform that should be applied to the Window to get it from screen coordinates to 157 * window coordinates 158 */ 159 public Matrix transform; 160 161 /** 162 * The input token for the window to which focus should be transferred when this input window 163 * can be successfully focused. If null, this input window will not transfer its focus to 164 * any other window. 165 */ 166 @Nullable 167 public IBinder focusTransferTarget; 168 nativeDispose()169 private native void nativeDispose(); 170 InputWindowHandle(InputApplicationHandle inputApplicationHandle, int displayId)171 public InputWindowHandle(InputApplicationHandle inputApplicationHandle, int displayId) { 172 this.inputApplicationHandle = inputApplicationHandle; 173 this.displayId = displayId; 174 } 175 InputWindowHandle(InputWindowHandle other)176 public InputWindowHandle(InputWindowHandle other) { 177 // Do not copy ptr to prevent this copy from sharing the same native object. 178 ptr = 0; 179 inputApplicationHandle = new InputApplicationHandle(other.inputApplicationHandle); 180 token = other.token; 181 windowToken = other.windowToken; 182 window = other.window; 183 name = other.name; 184 layoutParamsFlags = other.layoutParamsFlags; 185 layoutParamsType = other.layoutParamsType; 186 dispatchingTimeoutMillis = other.dispatchingTimeoutMillis; 187 frameLeft = other.frameLeft; 188 frameTop = other.frameTop; 189 frameRight = other.frameRight; 190 frameBottom = other.frameBottom; 191 surfaceInset = other.surfaceInset; 192 scaleFactor = other.scaleFactor; 193 touchableRegion.set(other.touchableRegion); 194 inputConfig = other.inputConfig; 195 touchOcclusionMode = other.touchOcclusionMode; 196 ownerPid = other.ownerPid; 197 ownerUid = other.ownerUid; 198 packageName = other.packageName; 199 displayId = other.displayId; 200 touchableRegionSurfaceControl = other.touchableRegionSurfaceControl; 201 replaceTouchableRegionWithCrop = other.replaceTouchableRegionWithCrop; 202 if (other.transform != null) { 203 transform = new Matrix(); 204 transform.set(other.transform); 205 } 206 focusTransferTarget = other.focusTransferTarget; 207 } 208 209 @Override toString()210 public String toString() { 211 return new StringBuilder(name != null ? name : "") 212 .append(", frame=[").append(frameLeft).append(",").append(frameTop).append(",") 213 .append(frameRight).append(",").append(frameBottom).append("]") 214 .append(", touchableRegion=").append(touchableRegion) 215 .append(", scaleFactor=").append(scaleFactor) 216 .append(", transform=").append(transform) 217 .append(", windowToken=").append(windowToken) 218 .append(", displayId=").append(displayId) 219 .append(", isClone=").append((inputConfig & InputConfig.CLONE) != 0) 220 .toString(); 221 222 } 223 224 @Override finalize()225 protected void finalize() throws Throwable { 226 try { 227 nativeDispose(); 228 } finally { 229 super.finalize(); 230 } 231 } 232 233 /** 234 * Set the window's touchable region to the bounds of {@link #touchableRegionSurfaceControl} 235 * and ignore the value of {@link #touchableRegion}. 236 * 237 * @param bounds surface to set the touchable region to. Set to {@code null} to set the 238 * touchable region as the current surface bounds. 239 */ replaceTouchableRegionWithCrop(@ullable SurfaceControl bounds)240 public void replaceTouchableRegionWithCrop(@Nullable SurfaceControl bounds) { 241 setTouchableRegionCrop(bounds); 242 replaceTouchableRegionWithCrop = true; 243 } 244 245 /** 246 * Crop the window touchable region to the bounds of the surface provided. 247 */ setTouchableRegionCrop(@ullable SurfaceControl bounds)248 public void setTouchableRegionCrop(@Nullable SurfaceControl bounds) { 249 touchableRegionSurfaceControl = new WeakReference<>(bounds); 250 } 251 setWindowToken(IWindow iwindow)252 public void setWindowToken(IWindow iwindow) { 253 windowToken = iwindow.asBinder(); 254 window = iwindow; 255 } 256 getWindowToken()257 public @Nullable IBinder getWindowToken() { 258 return windowToken; 259 } 260 getWindow()261 public IWindow getWindow() { 262 if (window != null) { 263 return window; 264 } 265 window = IWindow.Stub.asInterface(windowToken); 266 return window; 267 } 268 269 /** 270 * Set the provided inputConfig flag values. 271 * @param inputConfig the flag values to change 272 * @param value the provided flag values are set when true, and cleared when false 273 */ setInputConfig(@nputConfigFlags int inputConfig, boolean value)274 public void setInputConfig(@InputConfigFlags int inputConfig, boolean value) { 275 if (value) { 276 this.inputConfig |= inputConfig; 277 return; 278 } 279 this.inputConfig &= ~inputConfig; 280 } 281 } 282