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