1 /* 2 * Copyright (C) 2020 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.wm; 18 19 import android.annotation.NonNull; 20 import android.annotation.Nullable; 21 import android.graphics.Region; 22 import android.os.IBinder; 23 import android.os.InputConfig; 24 import android.view.InputApplicationHandle; 25 import android.view.InputWindowHandle; 26 import android.view.InputWindowHandle.InputConfigFlags; 27 import android.view.SurfaceControl; 28 import android.view.WindowManager; 29 30 import java.util.Objects; 31 32 /** 33 * The wrapper of {@link InputWindowHandle} with field change detection to reduce unnecessary 34 * updates to surface, e.g. if there are no changes, then skip invocation of 35 * {@link SurfaceControl.Transaction#setInputWindowInfo(SurfaceControl, InputWindowHandle)}. 36 * It also sets the {@link InputConfigFlags} values for the input window. 37 */ 38 class InputWindowHandleWrapper { 39 40 /** The wrapped handle should not be directly exposed to avoid untracked changes. */ 41 private final @NonNull InputWindowHandle mHandle; 42 43 /** Whether the {@link #mHandle} is changed. */ 44 private boolean mChanged = true; 45 InputWindowHandleWrapper(@onNull InputWindowHandle handle)46 InputWindowHandleWrapper(@NonNull InputWindowHandle handle) { 47 mHandle = handle; 48 } 49 50 /** 51 * Returns {@code true} if the input window handle has changed since the last invocation of 52 * {@link #applyChangesToSurface(SurfaceControl.Transaction, SurfaceControl)}} 53 */ isChanged()54 boolean isChanged() { 55 return mChanged; 56 } 57 forceChange()58 void forceChange() { 59 mChanged = true; 60 } 61 applyChangesToSurface(@onNull SurfaceControl.Transaction t, @NonNull SurfaceControl sc)62 void applyChangesToSurface(@NonNull SurfaceControl.Transaction t, @NonNull SurfaceControl sc) { 63 t.setInputWindowInfo(sc, mHandle); 64 mChanged = false; 65 } 66 getDisplayId()67 int getDisplayId() { 68 return mHandle.displayId; 69 } 70 isFocusable()71 boolean isFocusable() { 72 return (mHandle.inputConfig & InputConfig.NOT_FOCUSABLE) == 0; 73 } 74 isPaused()75 boolean isPaused() { 76 return (mHandle.inputConfig & InputConfig.PAUSE_DISPATCHING) != 0; 77 } 78 isTrustedOverlay()79 boolean isTrustedOverlay() { 80 return (mHandle.inputConfig & InputConfig.TRUSTED_OVERLAY) != 0; 81 } 82 hasWallpaper()83 boolean hasWallpaper() { 84 return (mHandle.inputConfig & InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER) 85 != 0; 86 } 87 getInputApplicationHandle()88 InputApplicationHandle getInputApplicationHandle() { 89 return mHandle.inputApplicationHandle; 90 } 91 setInputApplicationHandle(InputApplicationHandle handle)92 void setInputApplicationHandle(InputApplicationHandle handle) { 93 if (mHandle.inputApplicationHandle == handle) { 94 return; 95 } 96 mHandle.inputApplicationHandle = handle; 97 mChanged = true; 98 } 99 setToken(IBinder token)100 void setToken(IBinder token) { 101 if (mHandle.token == token) { 102 return; 103 } 104 mHandle.token = token; 105 mChanged = true; 106 } 107 setName(String name)108 void setName(String name) { 109 if (Objects.equals(mHandle.name, name)) { 110 return; 111 } 112 mHandle.name = name; 113 mChanged = true; 114 } 115 setLayoutParamsFlags(@indowManager.LayoutParams.Flags int flags)116 void setLayoutParamsFlags(@WindowManager.LayoutParams.Flags int flags) { 117 if (mHandle.layoutParamsFlags == flags) { 118 return; 119 } 120 mHandle.layoutParamsFlags = flags; 121 mChanged = true; 122 } 123 setLayoutParamsType(int type)124 void setLayoutParamsType(int type) { 125 if (mHandle.layoutParamsType == type) { 126 return; 127 } 128 mHandle.layoutParamsType = type; 129 mChanged = true; 130 } 131 setDispatchingTimeoutMillis(long timeout)132 void setDispatchingTimeoutMillis(long timeout) { 133 if (mHandle.dispatchingTimeoutMillis == timeout) { 134 return; 135 } 136 mHandle.dispatchingTimeoutMillis = timeout; 137 mChanged = true; 138 } 139 setTouchableRegion(Region region)140 void setTouchableRegion(Region region) { 141 if (mHandle.touchableRegion.equals(region)) { 142 return; 143 } 144 mHandle.touchableRegion.set(region); 145 mChanged = true; 146 } 147 clearTouchableRegion()148 void clearTouchableRegion() { 149 if (mHandle.touchableRegion.isEmpty()) { 150 return; 151 } 152 mHandle.touchableRegion.setEmpty(); 153 mChanged = true; 154 } 155 setFocusable(boolean focusable)156 void setFocusable(boolean focusable) { 157 if (isFocusable() == focusable) { 158 return; 159 } 160 mHandle.setInputConfig(InputConfig.NOT_FOCUSABLE, !focusable); 161 mChanged = true; 162 } 163 setTouchOcclusionMode(int mode)164 void setTouchOcclusionMode(int mode) { 165 if (mHandle.touchOcclusionMode == mode) { 166 return; 167 } 168 mHandle.touchOcclusionMode = mode; 169 mChanged = true; 170 } 171 setHasWallpaper(boolean hasWallpaper)172 void setHasWallpaper(boolean hasWallpaper) { 173 if (this.hasWallpaper() == hasWallpaper) { 174 return; 175 } 176 mHandle.setInputConfig(InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER, 177 hasWallpaper); 178 mChanged = true; 179 } 180 setPaused(boolean paused)181 void setPaused(boolean paused) { 182 if (isPaused() == paused) { 183 return; 184 } 185 mHandle.setInputConfig(InputConfig.PAUSE_DISPATCHING, paused); 186 mChanged = true; 187 } 188 setTrustedOverlay(boolean trustedOverlay)189 void setTrustedOverlay(boolean trustedOverlay) { 190 if (isTrustedOverlay() == trustedOverlay) { 191 return; 192 } 193 mHandle.setInputConfig(InputConfig.TRUSTED_OVERLAY, trustedOverlay); 194 mChanged = true; 195 } 196 setTrustedOverlay(SurfaceControl.Transaction t, SurfaceControl sc, boolean trustedOverlay)197 void setTrustedOverlay(SurfaceControl.Transaction t, SurfaceControl sc, 198 boolean trustedOverlay) { 199 mHandle.setTrustedOverlay(t, sc, trustedOverlay); 200 } 201 setOwnerPid(int pid)202 void setOwnerPid(int pid) { 203 if (mHandle.ownerPid == pid) { 204 return; 205 } 206 mHandle.ownerPid = pid; 207 mChanged = true; 208 } 209 setOwnerUid(int uid)210 void setOwnerUid(int uid) { 211 if (mHandle.ownerUid == uid) { 212 return; 213 } 214 mHandle.ownerUid = uid; 215 mChanged = true; 216 } 217 setPackageName(String packageName)218 void setPackageName(String packageName) { 219 if (Objects.equals(mHandle.packageName, packageName)) { 220 return; 221 } 222 mHandle.packageName = packageName; 223 mChanged = true; 224 } 225 setDisplayId(int displayId)226 void setDisplayId(int displayId) { 227 if (mHandle.displayId == displayId) { 228 return; 229 } 230 mHandle.displayId = displayId; 231 mChanged = true; 232 } 233 setSurfaceInset(int inset)234 void setSurfaceInset(int inset) { 235 if (mHandle.surfaceInset == inset) { 236 return; 237 } 238 mHandle.surfaceInset = inset; 239 mChanged = true; 240 } 241 setScaleFactor(float scale)242 void setScaleFactor(float scale) { 243 if (mHandle.scaleFactor == scale) { 244 return; 245 } 246 mHandle.scaleFactor = scale; 247 mChanged = true; 248 } 249 setTouchableRegionCrop(@ullable SurfaceControl bounds)250 void setTouchableRegionCrop(@Nullable SurfaceControl bounds) { 251 if (mHandle.touchableRegionSurfaceControl.get() == bounds) { 252 return; 253 } 254 mHandle.setTouchableRegionCrop(bounds); 255 mChanged = true; 256 } 257 setReplaceTouchableRegionWithCrop(boolean replace)258 void setReplaceTouchableRegionWithCrop(boolean replace) { 259 if (mHandle.replaceTouchableRegionWithCrop == replace) { 260 return; 261 } 262 mHandle.replaceTouchableRegionWithCrop = replace; 263 mChanged = true; 264 } 265 setWindowToken(IBinder windowToken)266 void setWindowToken(IBinder windowToken) { 267 if (mHandle.getWindowToken() == windowToken) { 268 return; 269 } 270 mHandle.setWindowToken(windowToken); 271 mChanged = true; 272 } 273 setInputConfigMasked(@nputConfigFlags int inputConfig, @InputConfigFlags int mask)274 void setInputConfigMasked(@InputConfigFlags int inputConfig, @InputConfigFlags int mask) { 275 final int inputConfigMasked = inputConfig & mask; 276 if (inputConfigMasked == (mHandle.inputConfig & mask)) { 277 return; 278 } 279 mHandle.inputConfig &= ~mask; 280 mHandle.inputConfig |= inputConfigMasked; 281 mChanged = true; 282 } 283 setFocusTransferTarget(IBinder toToken)284 void setFocusTransferTarget(IBinder toToken) { 285 if (mHandle.focusTransferTarget == toToken) { 286 return; 287 } 288 mHandle.focusTransferTarget = toToken; 289 mChanged = true; 290 } 291 292 @Override toString()293 public String toString() { 294 return mHandle + ", changed=" + mChanged; 295 } 296 } 297