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