293 lines
10 KiB
Java
293 lines
10 KiB
Java
![]() |
/*
|
||
|
* 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 static com.android.window.flags.Flags.surfaceTrustedOverlay;
|
||
|
|
||
|
import android.annotation.IntDef;
|
||
|
import android.annotation.Nullable;
|
||
|
import android.graphics.Matrix;
|
||
|
import android.graphics.Rect;
|
||
|
import android.graphics.Region;
|
||
|
import android.gui.TouchOcclusionMode;
|
||
|
import android.os.IBinder;
|
||
|
import android.os.InputConfig;
|
||
|
import android.util.Size;
|
||
|
|
||
|
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.WATCH_OUTSIDE_TOUCH,
|
||
|
InputConfig.SLIPPERY,
|
||
|
InputConfig.DISABLE_USER_ACTIVITY,
|
||
|
InputConfig.SPY,
|
||
|
InputConfig.INTERCEPTS_STYLUS,
|
||
|
InputConfig.CLONE,
|
||
|
InputConfig.SENSITIVE_FOR_PRIVACY,
|
||
|
})
|
||
|
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 IBinder} handle if InputWindowHandle is associated with a client token,
|
||
|
* normally the IWindow token, null otherwise.
|
||
|
*/
|
||
|
@Nullable
|
||
|
private IBinder windowToken;
|
||
|
|
||
|
// 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 final Rect frame = new Rect();
|
||
|
|
||
|
// The real size of the content, excluding any crop. If no buffer is rendered, this is 0,0
|
||
|
public Size contentSize = new Size(0, 0);
|
||
|
|
||
|
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;
|
||
|
|
||
|
/**
|
||
|
* The alpha value returned from SurfaceFlinger. This will be ignored if passed as input data.
|
||
|
*/
|
||
|
public float alpha;
|
||
|
|
||
|
/**
|
||
|
* Sets a property on this window indicating that its visible region should be considered when
|
||
|
* computing TrustedPresentation Thresholds.
|
||
|
*/
|
||
|
public boolean canOccludePresentation;
|
||
|
|
||
|
/**
|
||
|
* The input token for the window to which focus should be transferred when this input window
|
||
|
* can be successfully focused. If null, this input window will not transfer its focus to
|
||
|
* any other window.
|
||
|
*/
|
||
|
@Nullable
|
||
|
public IBinder focusTransferTarget;
|
||
|
|
||
|
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;
|
||
|
name = other.name;
|
||
|
layoutParamsFlags = other.layoutParamsFlags;
|
||
|
layoutParamsType = other.layoutParamsType;
|
||
|
dispatchingTimeoutMillis = other.dispatchingTimeoutMillis;
|
||
|
frame.set(other.frame);
|
||
|
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);
|
||
|
}
|
||
|
focusTransferTarget = other.focusTransferTarget;
|
||
|
contentSize = new Size(other.contentSize.getWidth(), other.contentSize.getHeight());
|
||
|
alpha = other.alpha;
|
||
|
canOccludePresentation = other.canOccludePresentation;
|
||
|
}
|
||
|
|
||
|
@Override
|
||
|
public String toString() {
|
||
|
return new StringBuilder(name != null ? name : "")
|
||
|
.append(", frame=[").append(frame).append("]")
|
||
|
.append(", touchableRegion=").append(touchableRegion)
|
||
|
.append(", scaleFactor=").append(scaleFactor)
|
||
|
.append(", transform=").append(transform)
|
||
|
.append(", windowToken=").append(windowToken)
|
||
|
.append(", displayId=").append(displayId)
|
||
|
.append(", isClone=").append((inputConfig & InputConfig.CLONE) != 0)
|
||
|
.append(", contentSize=").append(contentSize)
|
||
|
.append(", alpha=").append(alpha)
|
||
|
.append(", canOccludePresentation=").append(canOccludePresentation)
|
||
|
.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(IBinder iwindow) {
|
||
|
windowToken = iwindow;
|
||
|
}
|
||
|
|
||
|
public @Nullable IBinder getWindowToken() {
|
||
|
return windowToken;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* 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;
|
||
|
}
|
||
|
|
||
|
public void setTrustedOverlay(SurfaceControl.Transaction t, SurfaceControl sc,
|
||
|
boolean isTrusted) {
|
||
|
if (surfaceTrustedOverlay()) {
|
||
|
t.setTrustedOverlay(sc, isTrusted);
|
||
|
} else if (isTrusted) {
|
||
|
inputConfig |= InputConfig.TRUSTED_OVERLAY;
|
||
|
}
|
||
|
}
|
||
|
}
|