Merge changes from topic "merge-input-config-feature-tm" into tm-dev am: d7a879e665
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/17050822 Change-Id: I569d13e950298a8fd9c35c664d39ac6814f6fd3c
This commit is contained in:
@@ -16,20 +16,57 @@
|
|||||||
|
|
||||||
package android.view;
|
package android.view;
|
||||||
|
|
||||||
|
import android.annotation.IntDef;
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
import android.graphics.Region;
|
import android.graphics.Region;
|
||||||
import android.gui.TouchOcclusionMode;
|
import android.gui.TouchOcclusionMode;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.InputConfig;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
import java.lang.ref.WeakReference;
|
import java.lang.ref.WeakReference;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Functions as a handle for a window that can receive input.
|
* Functions as a handle for a window that can receive input, and allows for the behavior of the
|
||||||
* Enables the native input dispatcher to refer indirectly to the window manager's window state.
|
* input window to be configured.
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public final class InputWindowHandle {
|
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.
|
// Pointer to the native input window handle.
|
||||||
// This field is lazily initialized via JNI.
|
// This field is lazily initialized via JNI.
|
||||||
@SuppressWarnings("unused")
|
@SuppressWarnings("unused")
|
||||||
@@ -56,7 +93,8 @@ public final class InputWindowHandle {
|
|||||||
// The window name.
|
// The window name.
|
||||||
public String name;
|
public String name;
|
||||||
|
|
||||||
// Window layout params attributes. (WindowManager.LayoutParams)
|
// Window layout params attributes. (WindowManager.LayoutParams)
|
||||||
|
// These values do not affect any input configurations. Use {@link #inputConfig} instead.
|
||||||
public int layoutParamsFlags;
|
public int layoutParamsFlags;
|
||||||
public int layoutParamsType;
|
public int layoutParamsType;
|
||||||
|
|
||||||
@@ -78,20 +116,9 @@ public final class InputWindowHandle {
|
|||||||
// Window touchable region.
|
// Window touchable region.
|
||||||
public final Region touchableRegion = new Region();
|
public final Region touchableRegion = new Region();
|
||||||
|
|
||||||
// Window is visible.
|
// Flags that specify the behavior of this input window. See {@link #InputConfigFlags}.
|
||||||
public boolean visible;
|
@InputConfigFlags
|
||||||
|
public int inputConfig;
|
||||||
// Window can be focused.
|
|
||||||
public boolean focusable;
|
|
||||||
|
|
||||||
// Window has wallpaper. (window is the current wallpaper target)
|
|
||||||
public boolean hasWallpaper;
|
|
||||||
|
|
||||||
// Input event dispatching is paused.
|
|
||||||
public boolean paused;
|
|
||||||
|
|
||||||
// Window is trusted overlay.
|
|
||||||
public boolean trustedOverlay;
|
|
||||||
|
|
||||||
// What effect this window has on touch occlusion if it lets touches pass through
|
// 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
|
// By default windows will block touches if they are untrusted and from a different UID due to
|
||||||
@@ -105,25 +132,21 @@ public final class InputWindowHandle {
|
|||||||
// Owner package of the window
|
// Owner package of the window
|
||||||
public String packageName;
|
public String packageName;
|
||||||
|
|
||||||
// Window input features.
|
// Display this input window is on.
|
||||||
public int inputFeatures;
|
|
||||||
|
|
||||||
// Display this input is on.
|
|
||||||
public int displayId;
|
public int displayId;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Crops the touchable region to the bounds of the surface provided.
|
* Crops the {@link #touchableRegion} to the bounds of the surface provided.
|
||||||
*
|
*
|
||||||
* This can be used in cases where the window is not
|
* This can be used in cases where the window should be constrained to the bounds of a parent
|
||||||
* {@link android.view.WindowManager#FLAG_NOT_TOUCH_MODAL} but should be constrained to the
|
* window. That is, the window should receive touch events outside its window frame, but be
|
||||||
* bounds of a parent window. That is the window should receive touch events outside its
|
* limited to its stack bounds, such as in the case of split screen.
|
||||||
* window but be limited to its stack bounds, such as in the case of split screen.
|
|
||||||
*/
|
*/
|
||||||
public WeakReference<SurfaceControl> touchableRegionSurfaceControl = new WeakReference<>(null);
|
public WeakReference<SurfaceControl> touchableRegionSurfaceControl = new WeakReference<>(null);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace {@link touchableRegion} with the bounds of {@link touchableRegionSurfaceControl}. If
|
* Replace {@link #touchableRegion} with the bounds of {@link #touchableRegionSurfaceControl}.
|
||||||
* the handle is {@code null}, the bounds of the surface associated with this window is used
|
* If the handle is {@code null}, the bounds of the surface associated with this window is used
|
||||||
* as the touchable region.
|
* as the touchable region.
|
||||||
*/
|
*/
|
||||||
public boolean replaceTouchableRegionWithCrop;
|
public boolean replaceTouchableRegionWithCrop;
|
||||||
@@ -147,7 +170,6 @@ public final class InputWindowHandle {
|
|||||||
.append(", frame=[").append(frameLeft).append(",").append(frameTop).append(",")
|
.append(", frame=[").append(frameLeft).append(",").append(frameTop).append(",")
|
||||||
.append(frameRight).append(",").append(frameBottom).append("]")
|
.append(frameRight).append(",").append(frameBottom).append("]")
|
||||||
.append(", touchableRegion=").append(touchableRegion)
|
.append(", touchableRegion=").append(touchableRegion)
|
||||||
.append(", visible=").append(visible)
|
|
||||||
.append(", scaleFactor=").append(scaleFactor)
|
.append(", scaleFactor=").append(scaleFactor)
|
||||||
.append(", transform=").append(transform)
|
.append(", transform=").append(transform)
|
||||||
.append(", windowToken=").append(windowToken)
|
.append(", windowToken=").append(windowToken)
|
||||||
@@ -165,11 +187,11 @@ public final class InputWindowHandle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the window touchable region to the bounds of {@link touchableRegionBounds} ignoring any
|
* Set the window's touchable region to the bounds of {@link #touchableRegionSurfaceControl}
|
||||||
* touchable region provided.
|
* and ignore the value of {@link #touchableRegion}.
|
||||||
*
|
*
|
||||||
* @param bounds surface to set the touchable region to. Set to {@code null} to set the bounds
|
* @param bounds surface to set the touchable region to. Set to {@code null} to set the
|
||||||
* to the current surface.
|
* touchable region as the current surface bounds.
|
||||||
*/
|
*/
|
||||||
public void replaceTouchableRegionWithCrop(@Nullable SurfaceControl bounds) {
|
public void replaceTouchableRegionWithCrop(@Nullable SurfaceControl bounds) {
|
||||||
setTouchableRegionCrop(bounds);
|
setTouchableRegionCrop(bounds);
|
||||||
@@ -195,4 +217,17 @@ public final class InputWindowHandle {
|
|||||||
window = IWindow.Stub.asInterface(windowToken);
|
window = IWindow.Stub.asInterface(windowToken);
|
||||||
return window;
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,7 +106,6 @@ import android.graphics.Region;
|
|||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.IInputConstants;
|
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
import android.os.Parcelable;
|
import android.os.Parcelable;
|
||||||
import android.text.TextUtils;
|
import android.text.TextUtils;
|
||||||
@@ -3360,8 +3359,7 @@ public interface WindowManager extends ViewManager {
|
|||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int INPUT_FEATURE_NO_INPUT_CHANNEL =
|
public static final int INPUT_FEATURE_NO_INPUT_CHANNEL = 1 << 0;
|
||||||
IInputConstants.InputFeature.NO_INPUT_CHANNEL;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* When this window has focus, does not call user activity for all input events so
|
* When this window has focus, does not call user activity for all input events so
|
||||||
@@ -3374,58 +3372,43 @@ public interface WindowManager extends ViewManager {
|
|||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
|
||||||
public static final int INPUT_FEATURE_DISABLE_USER_ACTIVITY =
|
public static final int INPUT_FEATURE_DISABLE_USER_ACTIVITY = 1 << 1;
|
||||||
IInputConstants.InputFeature.DISABLE_USER_ACTIVITY;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An input spy window. This window will receive all pointer events within its touchable
|
* An input spy window. This window will receive all pointer events within its touchable
|
||||||
* area, but will will not stop events from being sent to other windows below it in z-order.
|
* area, but will not stop events from being sent to other windows below it in z-order.
|
||||||
* An input event will be dispatched to all spy windows above the top non-spy window at the
|
* An input event will be dispatched to all spy windows above the top non-spy window at the
|
||||||
* event's coordinates.
|
* event's coordinates.
|
||||||
* @hide
|
|
||||||
*/
|
|
||||||
public static final int INPUT_FEATURE_SPY =
|
|
||||||
IInputConstants.InputFeature.SPY;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* When used with the window flag {@link #FLAG_NOT_TOUCHABLE}, this window will continue
|
|
||||||
* to receive events from a stylus device within its touchable region. All other pointer
|
|
||||||
* events, such as from a mouse or touchscreen, will be dispatched to the windows behind it.
|
|
||||||
*
|
|
||||||
* This input feature has no effect when the window flag {@link #FLAG_NOT_TOUCHABLE} is
|
|
||||||
* not set.
|
|
||||||
*
|
|
||||||
* The window must be a trusted overlay to use this input feature.
|
|
||||||
*
|
|
||||||
* @see #FLAG_NOT_TOUCHABLE
|
|
||||||
*
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
public static final int INPUT_FEATURE_INTERCEPTS_STYLUS =
|
@RequiresPermission(permission.MONITOR_INPUT)
|
||||||
IInputConstants.InputFeature.INTERCEPTS_STYLUS;
|
public static final int INPUT_FEATURE_SPY = 1 << 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An internal annotation for flags that can be specified to {@link #inputFeatures}.
|
* An internal annotation for flags that can be specified to {@link #inputFeatures}.
|
||||||
*
|
*
|
||||||
|
* NOTE: These are not the same as {@link android.os.InputConfig} flags.
|
||||||
|
*
|
||||||
* @hide
|
* @hide
|
||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.SOURCE)
|
@Retention(RetentionPolicy.SOURCE)
|
||||||
@IntDef(flag = true, prefix = { "INPUT_FEATURE_" }, value = {
|
@IntDef(flag = true, prefix = {"INPUT_FEATURE_"}, value = {
|
||||||
INPUT_FEATURE_NO_INPUT_CHANNEL,
|
INPUT_FEATURE_NO_INPUT_CHANNEL,
|
||||||
INPUT_FEATURE_DISABLE_USER_ACTIVITY,
|
INPUT_FEATURE_DISABLE_USER_ACTIVITY,
|
||||||
INPUT_FEATURE_SPY,
|
INPUT_FEATURE_SPY,
|
||||||
INPUT_FEATURE_INTERCEPTS_STYLUS,
|
|
||||||
})
|
})
|
||||||
public @interface InputFeatureFlags {}
|
public @interface InputFeatureFlags {
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Control special features of the input subsystem.
|
* Control a set of features of the input subsystem that are exposed to the app process.
|
||||||
|
*
|
||||||
|
* WARNING: Do NOT use {@link android.os.InputConfig} flags! This must be set to flag values
|
||||||
|
* included in {@link InputFeatureFlags}.
|
||||||
*
|
*
|
||||||
* @see #INPUT_FEATURE_NO_INPUT_CHANNEL
|
|
||||||
* @see #INPUT_FEATURE_DISABLE_USER_ACTIVITY
|
|
||||||
* @see #INPUT_FEATURE_SPY
|
|
||||||
* @see #INPUT_FEATURE_INTERCEPTS_STYLUS
|
|
||||||
* @hide
|
* @hide
|
||||||
|
* @see InputFeatureFlags
|
||||||
*/
|
*/
|
||||||
@InputFeatureFlags
|
@InputFeatureFlags
|
||||||
@UnsupportedAppUsage
|
@UnsupportedAppUsage
|
||||||
@@ -4845,10 +4828,6 @@ public interface WindowManager extends ViewManager {
|
|||||||
inputFeatures &= ~INPUT_FEATURE_SPY;
|
inputFeatures &= ~INPUT_FEATURE_SPY;
|
||||||
features.add("INPUT_FEATURE_SPY");
|
features.add("INPUT_FEATURE_SPY");
|
||||||
}
|
}
|
||||||
if ((inputFeatures & INPUT_FEATURE_INTERCEPTS_STYLUS) != 0) {
|
|
||||||
inputFeatures &= ~INPUT_FEATURE_INTERCEPTS_STYLUS;
|
|
||||||
features.add("INPUT_FEATURE_INTERCEPTS_STYLUS");
|
|
||||||
}
|
|
||||||
if (inputFeatures != 0) {
|
if (inputFeatures != 0) {
|
||||||
features.add(Integer.toHexString(inputFeatures));
|
features.add(Integer.toHexString(inputFeatures));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
#include <android_runtime/AndroidRuntime.h>
|
#include <android_runtime/AndroidRuntime.h>
|
||||||
#include <android_runtime/Log.h>
|
#include <android_runtime/Log.h>
|
||||||
#include <binder/IPCThreadState.h>
|
#include <binder/IPCThreadState.h>
|
||||||
|
#include <ftl/cast.h>
|
||||||
#include <gui/SurfaceControl.h>
|
#include <gui/SurfaceControl.h>
|
||||||
#include <gui/WindowInfo.h>
|
#include <gui/WindowInfo.h>
|
||||||
#include <nativehelper/JNIHelp.h>
|
#include <nativehelper/JNIHelp.h>
|
||||||
@@ -63,16 +64,11 @@ static struct {
|
|||||||
jfieldID surfaceInset;
|
jfieldID surfaceInset;
|
||||||
jfieldID scaleFactor;
|
jfieldID scaleFactor;
|
||||||
jfieldID touchableRegion;
|
jfieldID touchableRegion;
|
||||||
jfieldID visible;
|
|
||||||
jfieldID focusable;
|
|
||||||
jfieldID hasWallpaper;
|
|
||||||
jfieldID paused;
|
|
||||||
jfieldID trustedOverlay;
|
|
||||||
jfieldID touchOcclusionMode;
|
jfieldID touchOcclusionMode;
|
||||||
jfieldID ownerPid;
|
jfieldID ownerPid;
|
||||||
jfieldID ownerUid;
|
jfieldID ownerUid;
|
||||||
jfieldID packageName;
|
jfieldID packageName;
|
||||||
jfieldID inputFeatures;
|
jfieldID inputConfig;
|
||||||
jfieldID displayId;
|
jfieldID displayId;
|
||||||
jfieldID replaceTouchableRegionWithCrop;
|
jfieldID replaceTouchableRegionWithCrop;
|
||||||
WeakRefHandleField touchableRegionSurfaceControl;
|
WeakRefHandleField touchableRegionSurfaceControl;
|
||||||
@@ -162,64 +158,8 @@ bool NativeInputWindowHandle::updateInfo() {
|
|||||||
mInfo.layoutParamsFlags = flags;
|
mInfo.layoutParamsFlags = flags;
|
||||||
mInfo.layoutParamsType = type;
|
mInfo.layoutParamsType = type;
|
||||||
|
|
||||||
using InputConfig = gui::WindowInfo::InputConfig;
|
mInfo.inputConfig = static_cast<gui::WindowInfo::InputConfig>(
|
||||||
// Determine the value for each of the InputConfig flags. We rely on a switch statement and
|
env->GetIntField(obj, gInputWindowHandleClassInfo.inputConfig));
|
||||||
// -Wswitch-enum to give us a build error if we forget to explicitly handle an InputConfig flag.
|
|
||||||
mInfo.inputConfig = InputConfig::NONE;
|
|
||||||
InputConfig enumerationStart = InputConfig::NONE;
|
|
||||||
switch (enumerationStart) {
|
|
||||||
case InputConfig::NONE:
|
|
||||||
FALLTHROUGH_INTENDED;
|
|
||||||
case InputConfig::NOT_VISIBLE:
|
|
||||||
if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.visible) == JNI_FALSE) {
|
|
||||||
mInfo.inputConfig |= InputConfig::NOT_VISIBLE;
|
|
||||||
}
|
|
||||||
FALLTHROUGH_INTENDED;
|
|
||||||
case InputConfig::NOT_FOCUSABLE:
|
|
||||||
if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.focusable) == JNI_FALSE) {
|
|
||||||
mInfo.inputConfig |= InputConfig::NOT_FOCUSABLE;
|
|
||||||
}
|
|
||||||
FALLTHROUGH_INTENDED;
|
|
||||||
case InputConfig::NOT_TOUCHABLE:
|
|
||||||
if (flags.test(WindowInfo::Flag::NOT_TOUCHABLE)) {
|
|
||||||
mInfo.inputConfig |= InputConfig::NOT_TOUCHABLE;
|
|
||||||
}
|
|
||||||
FALLTHROUGH_INTENDED;
|
|
||||||
case InputConfig::PREVENT_SPLITTING:
|
|
||||||
if (!flags.test(WindowInfo::Flag::SPLIT_TOUCH)) {
|
|
||||||
mInfo.inputConfig |= InputConfig::PREVENT_SPLITTING;
|
|
||||||
}
|
|
||||||
FALLTHROUGH_INTENDED;
|
|
||||||
case InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER:
|
|
||||||
if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.hasWallpaper) == JNI_TRUE) {
|
|
||||||
mInfo.inputConfig |= InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER;
|
|
||||||
}
|
|
||||||
FALLTHROUGH_INTENDED;
|
|
||||||
case InputConfig::IS_WALLPAPER:
|
|
||||||
if (type == WindowInfo::Type::WALLPAPER) {
|
|
||||||
mInfo.inputConfig |= InputConfig::IS_WALLPAPER;
|
|
||||||
}
|
|
||||||
FALLTHROUGH_INTENDED;
|
|
||||||
case InputConfig::PAUSE_DISPATCHING:
|
|
||||||
if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.paused) == JNI_TRUE) {
|
|
||||||
mInfo.inputConfig |= InputConfig::PAUSE_DISPATCHING;
|
|
||||||
}
|
|
||||||
FALLTHROUGH_INTENDED;
|
|
||||||
case InputConfig::TRUSTED_OVERLAY:
|
|
||||||
if (env->GetBooleanField(obj, gInputWindowHandleClassInfo.trustedOverlay) == JNI_TRUE) {
|
|
||||||
mInfo.inputConfig |= InputConfig::TRUSTED_OVERLAY;
|
|
||||||
}
|
|
||||||
FALLTHROUGH_INTENDED;
|
|
||||||
case InputConfig::WATCH_OUTSIDE_TOUCH:
|
|
||||||
if (flags.test(WindowInfo::Flag::WATCH_OUTSIDE_TOUCH)) {
|
|
||||||
mInfo.inputConfig |= InputConfig::WATCH_OUTSIDE_TOUCH;
|
|
||||||
}
|
|
||||||
FALLTHROUGH_INTENDED;
|
|
||||||
case InputConfig::SLIPPERY:
|
|
||||||
if (flags.test(WindowInfo::Flag::SLIPPERY)) {
|
|
||||||
mInfo.inputConfig |= InputConfig::SLIPPERY;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mInfo.touchOcclusionMode = static_cast<TouchOcclusionMode>(
|
mInfo.touchOcclusionMode = static_cast<TouchOcclusionMode>(
|
||||||
env->GetIntField(obj, gInputWindowHandleClassInfo.touchOcclusionMode));
|
env->GetIntField(obj, gInputWindowHandleClassInfo.touchOcclusionMode));
|
||||||
@@ -228,8 +168,6 @@ bool NativeInputWindowHandle::updateInfo() {
|
|||||||
mInfo.ownerUid = env->GetIntField(obj,
|
mInfo.ownerUid = env->GetIntField(obj,
|
||||||
gInputWindowHandleClassInfo.ownerUid);
|
gInputWindowHandleClassInfo.ownerUid);
|
||||||
mInfo.packageName = getStringField(env, obj, gInputWindowHandleClassInfo.packageName, "<null>");
|
mInfo.packageName = getStringField(env, obj, gInputWindowHandleClassInfo.packageName, "<null>");
|
||||||
mInfo.inputFeatures = static_cast<WindowInfo::Feature>(
|
|
||||||
env->GetIntField(obj, gInputWindowHandleClassInfo.inputFeatures));
|
|
||||||
mInfo.displayId = env->GetIntField(obj,
|
mInfo.displayId = env->GetIntField(obj,
|
||||||
gInputWindowHandleClassInfo.displayId);
|
gInputWindowHandleClassInfo.displayId);
|
||||||
|
|
||||||
@@ -359,17 +297,6 @@ jobject android_view_InputWindowHandle_fromWindowInfo(JNIEnv* env, gui::WindowIn
|
|||||||
env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.touchableRegion,
|
env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.touchableRegion,
|
||||||
regionObj.get());
|
regionObj.get());
|
||||||
|
|
||||||
using InputConfig = gui::WindowInfo::InputConfig;
|
|
||||||
env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.visible,
|
|
||||||
!windowInfo.inputConfig.test(InputConfig::NOT_VISIBLE));
|
|
||||||
env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.focusable,
|
|
||||||
!windowInfo.inputConfig.test(gui::WindowInfo::InputConfig::NOT_FOCUSABLE));
|
|
||||||
env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.hasWallpaper,
|
|
||||||
windowInfo.inputConfig.test(InputConfig::DUPLICATE_TOUCH_TO_WALLPAPER));
|
|
||||||
env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.paused,
|
|
||||||
windowInfo.inputConfig.test(InputConfig::PAUSE_DISPATCHING));
|
|
||||||
env->SetBooleanField(inputWindowHandle, gInputWindowHandleClassInfo.trustedOverlay,
|
|
||||||
windowInfo.inputConfig.test(InputConfig::TRUSTED_OVERLAY));
|
|
||||||
env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.touchOcclusionMode,
|
env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.touchOcclusionMode,
|
||||||
static_cast<int32_t>(windowInfo.touchOcclusionMode));
|
static_cast<int32_t>(windowInfo.touchOcclusionMode));
|
||||||
env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.ownerPid, windowInfo.ownerPid);
|
env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.ownerPid, windowInfo.ownerPid);
|
||||||
@@ -377,8 +304,11 @@ jobject android_view_InputWindowHandle_fromWindowInfo(JNIEnv* env, gui::WindowIn
|
|||||||
ScopedLocalRef<jstring> packageName(env, env->NewStringUTF(windowInfo.packageName.data()));
|
ScopedLocalRef<jstring> packageName(env, env->NewStringUTF(windowInfo.packageName.data()));
|
||||||
env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.packageName,
|
env->SetObjectField(inputWindowHandle, gInputWindowHandleClassInfo.packageName,
|
||||||
packageName.get());
|
packageName.get());
|
||||||
env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.inputFeatures,
|
|
||||||
static_cast<int32_t>(windowInfo.inputFeatures.get()));
|
const auto inputConfig = windowInfo.inputConfig.get();
|
||||||
|
static_assert(sizeof(inputConfig) == sizeof(int32_t));
|
||||||
|
env->SetIntField(inputWindowHandle, gInputWindowHandleClassInfo.inputConfig,
|
||||||
|
static_cast<int32_t>(inputConfig));
|
||||||
|
|
||||||
float transformVals[9];
|
float transformVals[9];
|
||||||
for (int i = 0; i < 9; i++) {
|
for (int i = 0; i < 9; i++) {
|
||||||
@@ -481,19 +411,6 @@ int register_android_view_InputWindowHandle(JNIEnv* env) {
|
|||||||
GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegion, clazz,
|
GET_FIELD_ID(gInputWindowHandleClassInfo.touchableRegion, clazz,
|
||||||
"touchableRegion", "Landroid/graphics/Region;");
|
"touchableRegion", "Landroid/graphics/Region;");
|
||||||
|
|
||||||
GET_FIELD_ID(gInputWindowHandleClassInfo.visible, clazz,
|
|
||||||
"visible", "Z");
|
|
||||||
|
|
||||||
GET_FIELD_ID(gInputWindowHandleClassInfo.focusable, clazz, "focusable", "Z");
|
|
||||||
|
|
||||||
GET_FIELD_ID(gInputWindowHandleClassInfo.hasWallpaper, clazz,
|
|
||||||
"hasWallpaper", "Z");
|
|
||||||
|
|
||||||
GET_FIELD_ID(gInputWindowHandleClassInfo.paused, clazz,
|
|
||||||
"paused", "Z");
|
|
||||||
|
|
||||||
GET_FIELD_ID(gInputWindowHandleClassInfo.trustedOverlay, clazz, "trustedOverlay", "Z");
|
|
||||||
|
|
||||||
GET_FIELD_ID(gInputWindowHandleClassInfo.touchOcclusionMode, clazz, "touchOcclusionMode", "I");
|
GET_FIELD_ID(gInputWindowHandleClassInfo.touchOcclusionMode, clazz, "touchOcclusionMode", "I");
|
||||||
|
|
||||||
GET_FIELD_ID(gInputWindowHandleClassInfo.ownerPid, clazz,
|
GET_FIELD_ID(gInputWindowHandleClassInfo.ownerPid, clazz,
|
||||||
@@ -505,8 +422,7 @@ int register_android_view_InputWindowHandle(JNIEnv* env) {
|
|||||||
GET_FIELD_ID(gInputWindowHandleClassInfo.packageName, clazz, "packageName",
|
GET_FIELD_ID(gInputWindowHandleClassInfo.packageName, clazz, "packageName",
|
||||||
"Ljava/lang/String;");
|
"Ljava/lang/String;");
|
||||||
|
|
||||||
GET_FIELD_ID(gInputWindowHandleClassInfo.inputFeatures, clazz,
|
GET_FIELD_ID(gInputWindowHandleClassInfo.inputConfig, clazz, "inputConfig", "I");
|
||||||
"inputFeatures", "I");
|
|
||||||
|
|
||||||
GET_FIELD_ID(gInputWindowHandleClassInfo.displayId, clazz,
|
GET_FIELD_ID(gInputWindowHandleClassInfo.displayId, clazz,
|
||||||
"displayId", "I");
|
"displayId", "I");
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package com.android.server.input;
|
|||||||
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
||||||
|
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.InputConfig;
|
||||||
import android.view.InputApplicationHandle;
|
import android.view.InputApplicationHandle;
|
||||||
import android.view.InputChannel;
|
import android.view.InputChannel;
|
||||||
import android.view.InputMonitor;
|
import android.view.InputMonitor;
|
||||||
@@ -56,18 +57,13 @@ class GestureMonitorSpyWindow {
|
|||||||
mWindowHandle.name = name;
|
mWindowHandle.name = name;
|
||||||
mWindowHandle.token = mClientChannel.getToken();
|
mWindowHandle.token = mClientChannel.getToken();
|
||||||
mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
|
mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
|
||||||
mWindowHandle.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
|
|
||||||
mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
||||||
mWindowHandle.visible = true;
|
|
||||||
mWindowHandle.focusable = false;
|
|
||||||
mWindowHandle.hasWallpaper = false;
|
|
||||||
mWindowHandle.paused = false;
|
|
||||||
mWindowHandle.ownerPid = pid;
|
mWindowHandle.ownerPid = pid;
|
||||||
mWindowHandle.ownerUid = uid;
|
mWindowHandle.ownerUid = uid;
|
||||||
mWindowHandle.inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY;
|
|
||||||
mWindowHandle.scaleFactor = 1.0f;
|
mWindowHandle.scaleFactor = 1.0f;
|
||||||
mWindowHandle.trustedOverlay = true;
|
|
||||||
mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
|
mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
|
||||||
|
mWindowHandle.inputConfig =
|
||||||
|
InputConfig.NOT_FOCUSABLE | InputConfig.SPY | InputConfig.TRUSTED_OVERLAY;
|
||||||
|
|
||||||
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
|
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
|
||||||
t.setInputWindowInfo(mInputSurface, mWindowHandle);
|
t.setInputWindowInfo(mInputSurface, mWindowHandle);
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package com.android.server.inputmethod;
|
|||||||
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
import android.os.InputConfig;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.view.InputApplicationHandle;
|
import android.view.InputApplicationHandle;
|
||||||
import android.view.InputChannel;
|
import android.view.InputChannel;
|
||||||
@@ -56,20 +57,17 @@ final class HandwritingEventReceiverSurface {
|
|||||||
mWindowHandle.name = name;
|
mWindowHandle.name = name;
|
||||||
mWindowHandle.token = mClientChannel.getToken();
|
mWindowHandle.token = mClientChannel.getToken();
|
||||||
mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
|
mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
|
||||||
mWindowHandle.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
|
||||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
|
|
||||||
mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
||||||
mWindowHandle.visible = true;
|
|
||||||
mWindowHandle.focusable = false;
|
|
||||||
mWindowHandle.hasWallpaper = false;
|
|
||||||
mWindowHandle.paused = false;
|
|
||||||
mWindowHandle.ownerPid = Process.myPid();
|
mWindowHandle.ownerPid = Process.myPid();
|
||||||
mWindowHandle.ownerUid = Process.myUid();
|
mWindowHandle.ownerUid = Process.myUid();
|
||||||
mWindowHandle.inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_SPY
|
|
||||||
| WindowManager.LayoutParams.INPUT_FEATURE_INTERCEPTS_STYLUS;
|
|
||||||
mWindowHandle.scaleFactor = 1.0f;
|
mWindowHandle.scaleFactor = 1.0f;
|
||||||
mWindowHandle.trustedOverlay = true;
|
|
||||||
mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
|
mWindowHandle.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
|
||||||
|
mWindowHandle.inputConfig =
|
||||||
|
InputConfig.NOT_FOCUSABLE
|
||||||
|
| InputConfig.NOT_TOUCHABLE
|
||||||
|
| InputConfig.SPY
|
||||||
|
| InputConfig.INTERCEPTS_STYLUS
|
||||||
|
| InputConfig.TRUSTED_OVERLAY;
|
||||||
|
|
||||||
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
|
final SurfaceControl.Transaction t = new SurfaceControl.Transaction();
|
||||||
t.setInputWindowInfo(mInputSurface, mWindowHandle);
|
t.setInputWindowInfo(mInputSurface, mWindowHandle);
|
||||||
@@ -85,7 +83,7 @@ final class HandwritingEventReceiverSurface {
|
|||||||
void startIntercepting(int imePid, int imeUid) {
|
void startIntercepting(int imePid, int imeUid) {
|
||||||
mWindowHandle.ownerPid = imePid;
|
mWindowHandle.ownerPid = imePid;
|
||||||
mWindowHandle.ownerUid = imeUid;
|
mWindowHandle.ownerUid = imeUid;
|
||||||
mWindowHandle.inputFeatures &= ~WindowManager.LayoutParams.INPUT_FEATURE_SPY;
|
mWindowHandle.inputConfig &= ~InputConfig.SPY;
|
||||||
|
|
||||||
new SurfaceControl.Transaction()
|
new SurfaceControl.Transaction()
|
||||||
.setInputWindowInfo(mInputSurface, mWindowHandle)
|
.setInputWindowInfo(mInputSurface, mWindowHandle)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import android.graphics.RectF;
|
|||||||
import android.graphics.Region;
|
import android.graphics.Region;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.InputConfig;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.util.Slog;
|
import android.util.Slog;
|
||||||
@@ -153,7 +154,8 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
|
|||||||
final List<InputWindowHandle> tempVisibleWindows = new ArrayList<>();
|
final List<InputWindowHandle> tempVisibleWindows = new ArrayList<>();
|
||||||
|
|
||||||
for (InputWindowHandle window : windowHandles) {
|
for (InputWindowHandle window : windowHandles) {
|
||||||
if (window.visible && window.getWindow() != null) {
|
final boolean visible = (window.inputConfig & InputConfig.NOT_VISIBLE) == 0;
|
||||||
|
if (visible && window.getWindow() != null) {
|
||||||
tempVisibleWindows.add(window);
|
tempVisibleWindows.add(window);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -641,7 +643,8 @@ public final class AccessibilityWindowsPopulator extends WindowInfosListener {
|
|||||||
final RecentsAnimationController controller = service.getRecentsAnimationController();
|
final RecentsAnimationController controller = service.getRecentsAnimationController();
|
||||||
instance.mIgnoreDuetoRecentsAnimation = windowState != null && controller != null
|
instance.mIgnoreDuetoRecentsAnimation = windowState != null && controller != null
|
||||||
&& controller.shouldIgnoreForAccessibility(windowState);
|
&& controller.shouldIgnoreForAccessibility(windowState);
|
||||||
instance.mIsTrustedOverlay = inputWindowHandle.trustedOverlay;
|
instance.mIsTrustedOverlay =
|
||||||
|
(inputWindowHandle.inputConfig & InputConfig.TRUSTED_OVERLAY) != 0;
|
||||||
|
|
||||||
// TODO (b/199358388) : gets the letterbox bounds of the window from other way.
|
// TODO (b/199358388) : gets the letterbox bounds of the window from other way.
|
||||||
if (windowState != null && windowState.areAppWindowBoundsLetterboxed()) {
|
if (windowState != null && windowState.areAppWindowBoundsLetterboxed()) {
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package com.android.server.wm;
|
|||||||
import android.app.compat.CompatChanges;
|
import android.app.compat.CompatChanges;
|
||||||
import android.compat.annotation.ChangeId;
|
import android.compat.annotation.ChangeId;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.InputConfig;
|
||||||
import android.os.InputConstants;
|
import android.os.InputConstants;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
@@ -111,13 +112,12 @@ class ActivityRecordInputSink {
|
|||||||
mActivityRecord.getDisplayId());
|
mActivityRecord.getDisplayId());
|
||||||
inputWindowHandle.replaceTouchableRegionWithCrop = true;
|
inputWindowHandle.replaceTouchableRegionWithCrop = true;
|
||||||
inputWindowHandle.name = mName;
|
inputWindowHandle.name = mName;
|
||||||
|
inputWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
|
||||||
inputWindowHandle.ownerUid = Process.myUid();
|
inputWindowHandle.ownerUid = Process.myUid();
|
||||||
inputWindowHandle.ownerPid = Process.myPid();
|
inputWindowHandle.ownerPid = Process.myPid();
|
||||||
inputWindowHandle.layoutParamsFlags =
|
|
||||||
WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
|
||||||
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
|
|
||||||
inputWindowHandle.dispatchingTimeoutMillis =
|
inputWindowHandle.dispatchingTimeoutMillis =
|
||||||
InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
||||||
|
inputWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE;
|
||||||
return inputWindowHandle;
|
return inputWindowHandle;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -169,5 +169,4 @@ class ActivityRecordInputSink {
|
|||||||
finishInputEvent(event, true);
|
finishInputEvent(event, true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -44,6 +44,7 @@ import android.hardware.input.InputManager;
|
|||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.InputConfig;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
@@ -127,7 +128,7 @@ class DragState {
|
|||||||
|
|
||||||
@Nullable private ValueAnimator mAnimator;
|
@Nullable private ValueAnimator mAnimator;
|
||||||
private final Interpolator mCubicEaseOutInterpolator = new DecelerateInterpolator(1.5f);
|
private final Interpolator mCubicEaseOutInterpolator = new DecelerateInterpolator(1.5f);
|
||||||
private Point mDisplaySize = new Point();
|
private final Point mDisplaySize = new Point();
|
||||||
|
|
||||||
// A surface used to catch input events for the drag-and-drop operation.
|
// A surface used to catch input events for the drag-and-drop operation.
|
||||||
SurfaceControl mInputSurface;
|
SurfaceControl mInputSurface;
|
||||||
@@ -160,8 +161,7 @@ class DragState {
|
|||||||
|
|
||||||
private void showInputSurface() {
|
private void showInputSurface() {
|
||||||
if (mInputSurface == null) {
|
if (mInputSurface == null) {
|
||||||
mInputSurface = mService.makeSurfaceBuilder(
|
mInputSurface = mService.makeSurfaceBuilder(mDisplayContent.getSession())
|
||||||
mService.mRoot.getDisplayContent(mDisplayContent.getDisplayId()).getSession())
|
|
||||||
.setContainerLayer()
|
.setContainerLayer()
|
||||||
.setName("Drag and Drop Input Consumer")
|
.setName("Drag and Drop Input Consumer")
|
||||||
.setCallsite("DragState.showInputSurface")
|
.setCallsite("DragState.showInputSurface")
|
||||||
@@ -174,17 +174,18 @@ class DragState {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mTransaction.show(mInputSurface);
|
// Crop the input surface to the display size.
|
||||||
mTransaction.setInputWindowInfo(mInputSurface, h);
|
|
||||||
mTransaction.setLayer(mInputSurface, Integer.MAX_VALUE);
|
|
||||||
|
|
||||||
mTmpClipRect.set(0, 0, mDisplaySize.x, mDisplaySize.y);
|
mTmpClipRect.set(0, 0, mDisplaySize.x, mDisplaySize.y);
|
||||||
mTransaction.setWindowCrop(mInputSurface, mTmpClipRect);
|
|
||||||
|
mTransaction.show(mInputSurface)
|
||||||
|
.setInputWindowInfo(mInputSurface, h)
|
||||||
|
.setLayer(mInputSurface, Integer.MAX_VALUE)
|
||||||
|
.setCrop(mInputSurface, mTmpClipRect);
|
||||||
|
|
||||||
// syncInputWindows here to ensure the input window info is sent before the
|
// syncInputWindows here to ensure the input window info is sent before the
|
||||||
// transferTouchFocus is called.
|
// transferTouchFocus is called.
|
||||||
mTransaction.syncInputWindows();
|
mTransaction.syncInputWindows()
|
||||||
mTransaction.apply(true);
|
.apply(true /*sync*/);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -361,29 +362,20 @@ class DragState {
|
|||||||
display.getDisplayId());
|
display.getDisplayId());
|
||||||
mDragWindowHandle.name = "drag";
|
mDragWindowHandle.name = "drag";
|
||||||
mDragWindowHandle.token = mClientChannel.getToken();
|
mDragWindowHandle.token = mClientChannel.getToken();
|
||||||
mDragWindowHandle.layoutParamsFlags = 0;
|
|
||||||
mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
|
mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
|
||||||
mDragWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
mDragWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
||||||
mDragWindowHandle.visible = true;
|
|
||||||
// Allows the system to consume keys when dragging is active. This can also be used to
|
|
||||||
// modify the drag state on key press. Example, cancel drag on escape key.
|
|
||||||
mDragWindowHandle.focusable = true;
|
|
||||||
mDragWindowHandle.hasWallpaper = false;
|
|
||||||
mDragWindowHandle.paused = false;
|
|
||||||
mDragWindowHandle.ownerPid = Process.myPid();
|
mDragWindowHandle.ownerPid = Process.myPid();
|
||||||
mDragWindowHandle.ownerUid = Process.myUid();
|
mDragWindowHandle.ownerUid = Process.myUid();
|
||||||
mDragWindowHandle.inputFeatures = 0;
|
|
||||||
mDragWindowHandle.scaleFactor = 1.0f;
|
mDragWindowHandle.scaleFactor = 1.0f;
|
||||||
|
|
||||||
|
// Keep the default behavior of this window to be focusable, which allows the system
|
||||||
|
// to consume keys when dragging is active. This can also be used to modify the drag
|
||||||
|
// state on key press. For example, cancel drag on escape key.
|
||||||
|
mDragWindowHandle.inputConfig = InputConfig.PREVENT_SPLITTING;
|
||||||
|
|
||||||
// The drag window cannot receive new touches.
|
// The drag window cannot receive new touches.
|
||||||
mDragWindowHandle.touchableRegion.setEmpty();
|
mDragWindowHandle.touchableRegion.setEmpty();
|
||||||
|
|
||||||
// The drag window covers the entire display
|
|
||||||
mDragWindowHandle.frameLeft = 0;
|
|
||||||
mDragWindowHandle.frameTop = 0;
|
|
||||||
mDragWindowHandle.frameRight = mDisplaySize.x;
|
|
||||||
mDragWindowHandle.frameBottom = mDisplaySize.y;
|
|
||||||
|
|
||||||
// Pause rotations before a drag.
|
// Pause rotations before a drag.
|
||||||
ProtoLog.d(WM_DEBUG_ORIENTATION, "Pausing rotation during drag");
|
ProtoLog.d(WM_DEBUG_ORIENTATION, "Pausing rotation during drag");
|
||||||
mService.mRoot.forAllDisplays(dc -> {
|
mService.mRoot.forAllDisplays(dc -> {
|
||||||
|
|||||||
138
services/core/java/com/android/server/wm/InputConfigAdapter.java
Normal file
138
services/core/java/com/android/server/wm/InputConfigAdapter.java
Normal file
@@ -0,0 +1,138 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2022 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 com.android.server.wm;
|
||||||
|
|
||||||
|
import android.os.InputConfig;
|
||||||
|
import android.view.InputWindowHandle.InputConfigFlags;
|
||||||
|
import android.view.WindowManager.LayoutParams;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A helper to determine the {@link InputConfigFlags} that control the behavior of an input window
|
||||||
|
* from several WM attributes.
|
||||||
|
*/
|
||||||
|
class InputConfigAdapter {
|
||||||
|
private InputConfigAdapter() {}
|
||||||
|
|
||||||
|
/** Describes a mapping from a flag value to a {@link InputConfigFlags} value. */
|
||||||
|
private static class FlagMapping {
|
||||||
|
final int mFlag;
|
||||||
|
final int mInputConfig;
|
||||||
|
final boolean mInverted;
|
||||||
|
|
||||||
|
FlagMapping(int flag, int inputConfig, boolean inverted) {
|
||||||
|
mFlag = flag;
|
||||||
|
mInputConfig = inputConfig;
|
||||||
|
mInverted = inverted;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A mapping from {@link LayoutParams.InputFeatureFlags} to {@link InputConfigFlags} for
|
||||||
|
* input configurations that can be mapped directly from a corresponding LayoutParams input
|
||||||
|
* feature.
|
||||||
|
*/
|
||||||
|
private static final List<FlagMapping> INPUT_FEATURE_TO_CONFIG_MAP = List.of(
|
||||||
|
new FlagMapping(
|
||||||
|
LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL,
|
||||||
|
InputConfig.NO_INPUT_CHANNEL, false /* inverted */),
|
||||||
|
new FlagMapping(
|
||||||
|
LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY,
|
||||||
|
InputConfig.DISABLE_USER_ACTIVITY, false /* inverted */),
|
||||||
|
new FlagMapping(
|
||||||
|
LayoutParams.INPUT_FEATURE_SPY,
|
||||||
|
InputConfig.SPY, false /* inverted */));
|
||||||
|
|
||||||
|
@InputConfigFlags
|
||||||
|
private static final int INPUT_FEATURE_TO_CONFIG_MASK =
|
||||||
|
computeMask(INPUT_FEATURE_TO_CONFIG_MAP);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A mapping from {@link LayoutParams.Flags} to {@link InputConfigFlags} for input
|
||||||
|
* configurations that can be mapped directly from a corresponding LayoutParams flag.
|
||||||
|
*
|
||||||
|
* NOTE: The layout params flag {@link LayoutParams#FLAG_NOT_FOCUSABLE} is not handled by this
|
||||||
|
* adapter, and must be handled explicitly.
|
||||||
|
*/
|
||||||
|
private static final List<FlagMapping> LAYOUT_PARAM_FLAG_TO_CONFIG_MAP = List.of(
|
||||||
|
new FlagMapping(
|
||||||
|
LayoutParams.FLAG_NOT_TOUCHABLE,
|
||||||
|
InputConfig.NOT_TOUCHABLE, false /* inverted */),
|
||||||
|
new FlagMapping(
|
||||||
|
LayoutParams.FLAG_SPLIT_TOUCH,
|
||||||
|
InputConfig.PREVENT_SPLITTING, true /* inverted */),
|
||||||
|
new FlagMapping(
|
||||||
|
LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH,
|
||||||
|
InputConfig.WATCH_OUTSIDE_TOUCH, false /* inverted */),
|
||||||
|
new FlagMapping(
|
||||||
|
LayoutParams.FLAG_SLIPPERY,
|
||||||
|
InputConfig.SLIPPERY, false /* inverted */));
|
||||||
|
|
||||||
|
@InputConfigFlags
|
||||||
|
private static final int LAYOUT_PARAM_FLAG_TO_CONFIG_MASK =
|
||||||
|
computeMask(LAYOUT_PARAM_FLAG_TO_CONFIG_MAP);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a mask of all the input config flags configured by
|
||||||
|
* {@link #getInputConfigFromWindowParams(int, int, int)}.
|
||||||
|
*/
|
||||||
|
@InputConfigFlags
|
||||||
|
static int getMask() {
|
||||||
|
return LAYOUT_PARAM_FLAG_TO_CONFIG_MASK | INPUT_FEATURE_TO_CONFIG_MASK
|
||||||
|
| InputConfig.IS_WALLPAPER;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the {@link InputConfigFlags} value that provides the input window behavior specified by
|
||||||
|
* the given WindowManager attributes.
|
||||||
|
*
|
||||||
|
* Use {@link #getMask()} to get the mask of all the input config flags set by this method.
|
||||||
|
*
|
||||||
|
* @param type the window type
|
||||||
|
* @param flags the window flags
|
||||||
|
* @param inputFeatures the input feature flags
|
||||||
|
*/
|
||||||
|
@InputConfigFlags
|
||||||
|
static int getInputConfigFromWindowParams(@LayoutParams.WindowType int type,
|
||||||
|
@LayoutParams.Flags int flags, @LayoutParams.InputFeatureFlags int inputFeatures) {
|
||||||
|
return (type == LayoutParams.TYPE_WALLPAPER ? InputConfig.IS_WALLPAPER : 0)
|
||||||
|
| applyMapping(flags, LAYOUT_PARAM_FLAG_TO_CONFIG_MAP)
|
||||||
|
| applyMapping(inputFeatures, INPUT_FEATURE_TO_CONFIG_MAP);
|
||||||
|
}
|
||||||
|
|
||||||
|
@InputConfigFlags
|
||||||
|
private static int applyMapping(int flags, List<FlagMapping> flagToConfigMap) {
|
||||||
|
int inputConfig = 0;
|
||||||
|
for (final FlagMapping mapping : flagToConfigMap) {
|
||||||
|
final boolean flagSet = (flags & mapping.mFlag) != 0;
|
||||||
|
if (flagSet != mapping.mInverted) {
|
||||||
|
inputConfig |= mapping.mInputConfig;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return inputConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
@InputConfigFlags
|
||||||
|
private static int computeMask(List<FlagMapping> flagToConfigMap) {
|
||||||
|
int mask = 0;
|
||||||
|
for (final FlagMapping mapping : flagToConfigMap) {
|
||||||
|
mask |= mapping.mInputConfig;
|
||||||
|
}
|
||||||
|
return mask;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -22,6 +22,7 @@ import android.graphics.Point;
|
|||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.InputConfig;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
@@ -70,19 +71,14 @@ class InputConsumerImpl implements IBinder.DeathRecipient {
|
|||||||
mWindowHandle.name = name;
|
mWindowHandle.name = name;
|
||||||
mWindowHandle.token = mClientChannel.getToken();
|
mWindowHandle.token = mClientChannel.getToken();
|
||||||
mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
|
mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
|
||||||
mWindowHandle.layoutParamsFlags = 0;
|
|
||||||
mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
||||||
mWindowHandle.visible = true;
|
|
||||||
mWindowHandle.focusable = false;
|
|
||||||
mWindowHandle.hasWallpaper = false;
|
|
||||||
mWindowHandle.paused = false;
|
|
||||||
mWindowHandle.ownerPid = Process.myPid();
|
mWindowHandle.ownerPid = Process.myPid();
|
||||||
mWindowHandle.ownerUid = Process.myUid();
|
mWindowHandle.ownerUid = Process.myUid();
|
||||||
mWindowHandle.inputFeatures = 0;
|
|
||||||
mWindowHandle.scaleFactor = 1.0f;
|
mWindowHandle.scaleFactor = 1.0f;
|
||||||
mWindowHandle.trustedOverlay = true;
|
mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE | InputConfig.TRUSTED_OVERLAY;
|
||||||
|
|
||||||
mInputSurface = mService.makeSurfaceBuilder(mService.mRoot.getDisplayContent(displayId).getSession())
|
mInputSurface = mService.makeSurfaceBuilder(
|
||||||
|
mService.mRoot.getDisplayContent(displayId).getSession())
|
||||||
.setContainerLayer()
|
.setContainerLayer()
|
||||||
.setName("Input Consumer " + name)
|
.setName("Input Consumer " + name)
|
||||||
.setCallsite("InputConsumerImpl")
|
.setCallsite("InputConsumerImpl")
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
|
|||||||
import static android.view.WindowManager.INPUT_CONSUMER_PIP;
|
import static android.view.WindowManager.INPUT_CONSUMER_PIP;
|
||||||
import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
|
import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
|
||||||
import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER;
|
import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER;
|
||||||
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
|
||||||
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
|
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
|
||||||
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
|
import static android.view.WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL;
|
||||||
import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
|
import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL;
|
||||||
@@ -53,6 +52,7 @@ import android.annotation.Nullable;
|
|||||||
import android.graphics.Region;
|
import android.graphics.Region;
|
||||||
import android.os.Handler;
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.InputConfig;
|
||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
import android.os.UserHandle;
|
import android.os.UserHandle;
|
||||||
import android.util.ArrayMap;
|
import android.util.ArrayMap;
|
||||||
@@ -61,6 +61,7 @@ import android.util.Slog;
|
|||||||
import android.view.InputChannel;
|
import android.view.InputChannel;
|
||||||
import android.view.InputWindowHandle;
|
import android.view.InputWindowHandle;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.protolog.common.ProtoLog;
|
import com.android.internal.protolog.common.ProtoLog;
|
||||||
@@ -221,15 +222,13 @@ final class InputMonitor {
|
|||||||
inputChannel, clientPid, clientUser, mDisplayId);
|
inputChannel, clientPid, clientUser, mDisplayId);
|
||||||
switch (name) {
|
switch (name) {
|
||||||
case INPUT_CONSUMER_WALLPAPER:
|
case INPUT_CONSUMER_WALLPAPER:
|
||||||
consumer.mWindowHandle.hasWallpaper = true;
|
consumer.mWindowHandle.inputConfig |= InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER;
|
||||||
break;
|
break;
|
||||||
case INPUT_CONSUMER_PIP:
|
case INPUT_CONSUMER_PIP:
|
||||||
// The touchable region of the Pip input window is cropped to the bounds of the
|
// This is a valid consumer type, but we don't need any additional configurations.
|
||||||
// stack, and we need FLAG_NOT_TOUCH_MODAL to ensure other events fall through
|
|
||||||
consumer.mWindowHandle.layoutParamsFlags |= FLAG_NOT_TOUCH_MODAL;
|
|
||||||
break;
|
break;
|
||||||
case INPUT_CONSUMER_RECENTS_ANIMATION:
|
case INPUT_CONSUMER_RECENTS_ANIMATION:
|
||||||
consumer.mWindowHandle.focusable = true;
|
consumer.mWindowHandle.inputConfig &= ~InputConfig.NOT_FOCUSABLE;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
throw new IllegalArgumentException("Illegal input consumer : " + name
|
throw new IllegalArgumentException("Illegal input consumer : " + name
|
||||||
@@ -247,11 +246,24 @@ final class InputMonitor {
|
|||||||
inputWindowHandle.setToken(w.mInputChannelToken);
|
inputWindowHandle.setToken(w.mInputChannelToken);
|
||||||
inputWindowHandle.setDispatchingTimeoutMillis(w.getInputDispatchingTimeoutMillis());
|
inputWindowHandle.setDispatchingTimeoutMillis(w.getInputDispatchingTimeoutMillis());
|
||||||
inputWindowHandle.setTouchOcclusionMode(w.getTouchOcclusionMode());
|
inputWindowHandle.setTouchOcclusionMode(w.getTouchOcclusionMode());
|
||||||
inputWindowHandle.setInputFeatures(w.mAttrs.inputFeatures);
|
|
||||||
inputWindowHandle.setPaused(w.mActivityRecord != null && w.mActivityRecord.paused);
|
inputWindowHandle.setPaused(w.mActivityRecord != null && w.mActivityRecord.paused);
|
||||||
inputWindowHandle.setVisible(w.isVisible());
|
|
||||||
inputWindowHandle.setWindowToken(w.mClient);
|
inputWindowHandle.setWindowToken(w.mClient);
|
||||||
|
|
||||||
|
// Update layout params flags to force the window to be not touch modal. We do this to
|
||||||
|
// restrict the window's touchable region to the task even if it requests touches outside
|
||||||
|
// its window bounds. An example is a dialog in primary split should get touches outside its
|
||||||
|
// window within the primary task but should not get any touches going to the secondary
|
||||||
|
// task.
|
||||||
|
int flags = w.mAttrs.flags;
|
||||||
|
if (w.mAttrs.isModal()) {
|
||||||
|
flags = flags | FLAG_NOT_TOUCH_MODAL;
|
||||||
|
}
|
||||||
|
inputWindowHandle.setLayoutParamsFlags(flags);
|
||||||
|
inputWindowHandle.setInputConfigMasked(
|
||||||
|
InputConfigAdapter.getInputConfigFromWindowParams(
|
||||||
|
w.mAttrs.type, flags, w.mAttrs.inputFeatures),
|
||||||
|
InputConfigAdapter.getMask());
|
||||||
|
|
||||||
final boolean focusable = w.canReceiveKeys()
|
final boolean focusable = w.canReceiveKeys()
|
||||||
&& (mService.mPerDisplayFocusEnabled || mDisplayContent.isOnTop());
|
&& (mService.mPerDisplayFocusEnabled || mDisplayContent.isOnTop());
|
||||||
inputWindowHandle.setFocusable(focusable);
|
inputWindowHandle.setFocusable(focusable);
|
||||||
@@ -270,17 +282,6 @@ final class InputMonitor {
|
|||||||
// what is on screen to what is actually being touched in the UI.
|
// what is on screen to what is actually being touched in the UI.
|
||||||
inputWindowHandle.setScaleFactor(w.mGlobalScale != 1f ? (1f / w.mGlobalScale) : 1f);
|
inputWindowHandle.setScaleFactor(w.mGlobalScale != 1f ? (1f / w.mGlobalScale) : 1f);
|
||||||
|
|
||||||
// Update layout params flags to force the window to be not touch modal. We do this to
|
|
||||||
// restrict the window's touchable region to the task even if it request touches outside its
|
|
||||||
// window bounds. An example is a dialog in primary split should get touches outside its
|
|
||||||
// window within the primary task but should not get any touches going to the secondary
|
|
||||||
// task.
|
|
||||||
int flags = w.mAttrs.flags;
|
|
||||||
if (w.mAttrs.isModal()) {
|
|
||||||
flags = flags | FLAG_NOT_TOUCH_MODAL;
|
|
||||||
}
|
|
||||||
inputWindowHandle.setLayoutParamsFlags(flags);
|
|
||||||
|
|
||||||
boolean useSurfaceBoundsAsTouchRegion = false;
|
boolean useSurfaceBoundsAsTouchRegion = false;
|
||||||
SurfaceControl touchableRegionCrop = null;
|
SurfaceControl touchableRegionCrop = null;
|
||||||
final Task task = w.getTask();
|
final Task task = w.getTask();
|
||||||
@@ -590,6 +591,8 @@ final class InputMonitor {
|
|||||||
|
|
||||||
if (mAddWallpaperInputConsumerHandle) {
|
if (mAddWallpaperInputConsumerHandle) {
|
||||||
if (w.mAttrs.type == TYPE_WALLPAPER && w.isVisible()) {
|
if (w.mAttrs.type == TYPE_WALLPAPER && w.isVisible()) {
|
||||||
|
mWallpaperInputConsumer.mWindowHandle
|
||||||
|
.replaceTouchableRegionWithCrop(null /* use this surface's bounds */);
|
||||||
// Add the wallpaper input consumer above the first visible wallpaper.
|
// Add the wallpaper input consumer above the first visible wallpaper.
|
||||||
mWallpaperInputConsumer.show(mInputTransaction, w);
|
mWallpaperInputConsumer.show(mInputTransaction, w);
|
||||||
mAddWallpaperInputConsumerHandle = false;
|
mAddWallpaperInputConsumerHandle = false;
|
||||||
@@ -631,24 +634,27 @@ final class InputMonitor {
|
|||||||
|
|
||||||
static void populateOverlayInputInfo(InputWindowHandleWrapper inputWindowHandle,
|
static void populateOverlayInputInfo(InputWindowHandleWrapper inputWindowHandle,
|
||||||
WindowState w) {
|
WindowState w) {
|
||||||
populateOverlayInputInfo(inputWindowHandle, w.isVisible());
|
populateOverlayInputInfo(inputWindowHandle);
|
||||||
inputWindowHandle.setTouchOcclusionMode(w.getTouchOcclusionMode());
|
inputWindowHandle.setTouchOcclusionMode(w.getTouchOcclusionMode());
|
||||||
}
|
}
|
||||||
|
|
||||||
// This would reset InputWindowHandle fields to prevent it could be found by input event.
|
// This would reset InputWindowHandle fields to prevent it could be found by input event.
|
||||||
// We need to check if any new field of InputWindowHandle could impact the result.
|
// We need to check if any new field of InputWindowHandle could impact the result.
|
||||||
@VisibleForTesting
|
@VisibleForTesting
|
||||||
static void populateOverlayInputInfo(InputWindowHandleWrapper inputWindowHandle,
|
static void populateOverlayInputInfo(InputWindowHandleWrapper inputWindowHandle) {
|
||||||
boolean isVisible) {
|
|
||||||
inputWindowHandle.setDispatchingTimeoutMillis(0); // It should never receive input.
|
inputWindowHandle.setDispatchingTimeoutMillis(0); // It should never receive input.
|
||||||
inputWindowHandle.setVisible(isVisible);
|
|
||||||
inputWindowHandle.setFocusable(false);
|
inputWindowHandle.setFocusable(false);
|
||||||
inputWindowHandle.setInputFeatures(INPUT_FEATURE_NO_INPUT_CHANNEL);
|
|
||||||
// The input window handle without input channel must not have a token.
|
// The input window handle without input channel must not have a token.
|
||||||
inputWindowHandle.setToken(null);
|
inputWindowHandle.setToken(null);
|
||||||
inputWindowHandle.setScaleFactor(1f);
|
inputWindowHandle.setScaleFactor(1f);
|
||||||
inputWindowHandle.setLayoutParamsFlags(
|
final int defaultType = WindowManager.LayoutParams.TYPE_APPLICATION;
|
||||||
FLAG_NOT_TOUCH_MODAL | FLAG_NOT_TOUCHABLE | FLAG_NOT_FOCUSABLE);
|
inputWindowHandle.setLayoutParamsType(defaultType);
|
||||||
|
inputWindowHandle.setInputConfigMasked(
|
||||||
|
InputConfigAdapter.getInputConfigFromWindowParams(
|
||||||
|
defaultType,
|
||||||
|
FLAG_NOT_TOUCHABLE,
|
||||||
|
INPUT_FEATURE_NO_INPUT_CHANNEL),
|
||||||
|
InputConfigAdapter.getMask());
|
||||||
inputWindowHandle.clearTouchableRegion();
|
inputWindowHandle.clearTouchableRegion();
|
||||||
inputWindowHandle.setTouchableRegionCrop(null);
|
inputWindowHandle.setTouchableRegionCrop(null);
|
||||||
}
|
}
|
||||||
@@ -666,7 +672,7 @@ final class InputMonitor {
|
|||||||
inputWindowHandle.setName(name);
|
inputWindowHandle.setName(name);
|
||||||
inputWindowHandle.setLayoutParamsType(TYPE_SECURE_SYSTEM_OVERLAY);
|
inputWindowHandle.setLayoutParamsType(TYPE_SECURE_SYSTEM_OVERLAY);
|
||||||
inputWindowHandle.setTrustedOverlay(true);
|
inputWindowHandle.setTrustedOverlay(true);
|
||||||
populateOverlayInputInfo(inputWindowHandle, true /* isVisible */);
|
populateOverlayInputInfo(inputWindowHandle);
|
||||||
setInputWindowInfoIfNeeded(t, sc, inputWindowHandle);
|
setInputWindowInfoIfNeeded(t, sc, inputWindowHandle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -20,10 +20,13 @@ import android.annotation.NonNull;
|
|||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
import android.graphics.Region;
|
import android.graphics.Region;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.InputConfig;
|
||||||
import android.view.IWindow;
|
import android.view.IWindow;
|
||||||
import android.view.InputApplicationHandle;
|
import android.view.InputApplicationHandle;
|
||||||
import android.view.InputWindowHandle;
|
import android.view.InputWindowHandle;
|
||||||
|
import android.view.InputWindowHandle.InputConfigFlags;
|
||||||
import android.view.SurfaceControl;
|
import android.view.SurfaceControl;
|
||||||
|
import android.view.WindowManager;
|
||||||
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@@ -31,8 +34,10 @@ import java.util.Objects;
|
|||||||
* The wrapper of {@link InputWindowHandle} with field change detection to reduce unnecessary
|
* The wrapper of {@link InputWindowHandle} with field change detection to reduce unnecessary
|
||||||
* updates to surface, e.g. if there are no changes, then skip invocation of
|
* updates to surface, e.g. if there are no changes, then skip invocation of
|
||||||
* {@link SurfaceControl.Transaction#setInputWindowInfo(SurfaceControl, InputWindowHandle)}.
|
* {@link SurfaceControl.Transaction#setInputWindowInfo(SurfaceControl, InputWindowHandle)}.
|
||||||
|
* It also sets the {@link InputConfigFlags} values for the input window.
|
||||||
*/
|
*/
|
||||||
class InputWindowHandleWrapper {
|
class InputWindowHandleWrapper {
|
||||||
|
|
||||||
/** The wrapped handle should not be directly exposed to avoid untracked changes. */
|
/** The wrapped handle should not be directly exposed to avoid untracked changes. */
|
||||||
private final @NonNull InputWindowHandle mHandle;
|
private final @NonNull InputWindowHandle mHandle;
|
||||||
|
|
||||||
@@ -65,7 +70,20 @@ class InputWindowHandleWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
boolean isFocusable() {
|
boolean isFocusable() {
|
||||||
return mHandle.focusable;
|
return (mHandle.inputConfig & InputConfig.NOT_FOCUSABLE) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isPaused() {
|
||||||
|
return (mHandle.inputConfig & InputConfig.PAUSE_DISPATCHING) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean isTrustedOverlay() {
|
||||||
|
return (mHandle.inputConfig & InputConfig.TRUSTED_OVERLAY) != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
boolean hasWallpaper() {
|
||||||
|
return (mHandle.inputConfig & InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER)
|
||||||
|
!= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
InputApplicationHandle getInputApplicationHandle() {
|
InputApplicationHandle getInputApplicationHandle() {
|
||||||
@@ -96,7 +114,7 @@ class InputWindowHandleWrapper {
|
|||||||
mChanged = true;
|
mChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setLayoutParamsFlags(int flags) {
|
void setLayoutParamsFlags(@WindowManager.LayoutParams.Flags int flags) {
|
||||||
if (mHandle.layoutParamsFlags == flags) {
|
if (mHandle.layoutParamsFlags == flags) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -136,19 +154,11 @@ class InputWindowHandleWrapper {
|
|||||||
mChanged = true;
|
mChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setVisible(boolean visible) {
|
|
||||||
if (mHandle.visible == visible) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mHandle.visible = visible;
|
|
||||||
mChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setFocusable(boolean focusable) {
|
void setFocusable(boolean focusable) {
|
||||||
if (mHandle.focusable == focusable) {
|
if (isFocusable() == focusable) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mHandle.focusable = focusable;
|
mHandle.setInputConfig(InputConfig.NOT_FOCUSABLE, !focusable);
|
||||||
mChanged = true;
|
mChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -161,26 +171,27 @@ class InputWindowHandleWrapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setHasWallpaper(boolean hasWallpaper) {
|
void setHasWallpaper(boolean hasWallpaper) {
|
||||||
if (mHandle.hasWallpaper == hasWallpaper) {
|
if (this.hasWallpaper() == hasWallpaper) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mHandle.hasWallpaper = hasWallpaper;
|
mHandle.setInputConfig(InputConfig.DUPLICATE_TOUCH_TO_WALLPAPER,
|
||||||
|
hasWallpaper);
|
||||||
mChanged = true;
|
mChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setPaused(boolean paused) {
|
void setPaused(boolean paused) {
|
||||||
if (mHandle.paused == paused) {
|
if (isPaused() == paused) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mHandle.paused = paused;
|
mHandle.setInputConfig(InputConfig.PAUSE_DISPATCHING, paused);
|
||||||
mChanged = true;
|
mChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setTrustedOverlay(boolean trustedOverlay) {
|
void setTrustedOverlay(boolean trustedOverlay) {
|
||||||
if (mHandle.trustedOverlay == trustedOverlay) {
|
if (isTrustedOverlay() == trustedOverlay) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
mHandle.trustedOverlay = trustedOverlay;
|
mHandle.setInputConfig(InputConfig.TRUSTED_OVERLAY, trustedOverlay);
|
||||||
mChanged = true;
|
mChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -208,14 +219,6 @@ class InputWindowHandleWrapper {
|
|||||||
mChanged = true;
|
mChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setInputFeatures(int features) {
|
|
||||||
if (mHandle.inputFeatures == features) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
mHandle.inputFeatures = features;
|
|
||||||
mChanged = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setDisplayId(int displayId) {
|
void setDisplayId(int displayId) {
|
||||||
if (mHandle.displayId == displayId) {
|
if (mHandle.displayId == displayId) {
|
||||||
return;
|
return;
|
||||||
@@ -276,8 +279,14 @@ class InputWindowHandleWrapper {
|
|||||||
mChanged = true;
|
mChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean isTrustedOverlay() {
|
void setInputConfigMasked(@InputConfigFlags int inputConfig, @InputConfigFlags int mask) {
|
||||||
return mHandle.trustedOverlay;
|
final int inputConfigMasked = inputConfig & mask;
|
||||||
|
if (inputConfigMasked == (mHandle.inputConfig & mask)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
mHandle.inputConfig &= ~mask;
|
||||||
|
mHandle.inputConfig |= inputConfigMasked;
|
||||||
|
mChanged = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ import android.graphics.Color;
|
|||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.InputConfig;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.view.GestureDetector;
|
import android.view.GestureDetector;
|
||||||
import android.view.InputChannel;
|
import android.view.InputChannel;
|
||||||
@@ -290,16 +291,12 @@ public class Letterbox {
|
|||||||
win.getDisplayId());
|
win.getDisplayId());
|
||||||
mWindowHandle.name = name;
|
mWindowHandle.name = name;
|
||||||
mWindowHandle.token = mToken;
|
mWindowHandle.token = mToken;
|
||||||
mWindowHandle.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
|
|
||||||
| WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL
|
|
||||||
| WindowManager.LayoutParams.FLAG_SPLIT_TOUCH
|
|
||||||
| WindowManager.LayoutParams.FLAG_SLIPPERY;
|
|
||||||
mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
|
mWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_INPUT_CONSUMER;
|
||||||
mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
mWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
||||||
mWindowHandle.visible = true;
|
|
||||||
mWindowHandle.ownerPid = Process.myPid();
|
mWindowHandle.ownerPid = Process.myPid();
|
||||||
mWindowHandle.ownerUid = Process.myUid();
|
mWindowHandle.ownerUid = Process.myUid();
|
||||||
mWindowHandle.scaleFactor = 1.0f;
|
mWindowHandle.scaleFactor = 1.0f;
|
||||||
|
mWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE | InputConfig.SLIPPERY;
|
||||||
}
|
}
|
||||||
|
|
||||||
void updateTouchableRegion(Rect frame) {
|
void updateTouchableRegion(Rect frame) {
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ import android.graphics.Point;
|
|||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.Binder;
|
import android.os.Binder;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.InputConfig;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.os.Trace;
|
import android.os.Trace;
|
||||||
@@ -219,30 +220,17 @@ class TaskPositioner implements IBinder.DeathRecipient {
|
|||||||
displayContent.getDisplayId());
|
displayContent.getDisplayId());
|
||||||
mDragWindowHandle.name = TAG;
|
mDragWindowHandle.name = TAG;
|
||||||
mDragWindowHandle.token = mClientChannel.getToken();
|
mDragWindowHandle.token = mClientChannel.getToken();
|
||||||
mDragWindowHandle.layoutParamsFlags = 0;
|
|
||||||
mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
|
mDragWindowHandle.layoutParamsType = WindowManager.LayoutParams.TYPE_DRAG;
|
||||||
mDragWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
mDragWindowHandle.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
||||||
mDragWindowHandle.visible = true;
|
|
||||||
// When dragging the window around, we do not want to steal focus for the window.
|
|
||||||
mDragWindowHandle.focusable = false;
|
|
||||||
mDragWindowHandle.hasWallpaper = false;
|
|
||||||
mDragWindowHandle.paused = false;
|
|
||||||
mDragWindowHandle.ownerPid = Process.myPid();
|
mDragWindowHandle.ownerPid = Process.myPid();
|
||||||
mDragWindowHandle.ownerUid = Process.myUid();
|
mDragWindowHandle.ownerUid = Process.myUid();
|
||||||
mDragWindowHandle.inputFeatures = 0;
|
|
||||||
mDragWindowHandle.scaleFactor = 1.0f;
|
mDragWindowHandle.scaleFactor = 1.0f;
|
||||||
|
// When dragging the window around, we do not want to steal focus for the window.
|
||||||
|
mDragWindowHandle.inputConfig = InputConfig.NOT_FOCUSABLE;
|
||||||
|
|
||||||
// The drag window cannot receive new touches.
|
// The drag window cannot receive new touches.
|
||||||
mDragWindowHandle.touchableRegion.setEmpty();
|
mDragWindowHandle.touchableRegion.setEmpty();
|
||||||
|
|
||||||
// The drag window covers the entire display.
|
|
||||||
final Rect displayBounds = mTmpRect;
|
|
||||||
displayContent.getBounds(mTmpRect);
|
|
||||||
mDragWindowHandle.frameLeft = displayBounds.left;
|
|
||||||
mDragWindowHandle.frameTop = displayBounds.top;
|
|
||||||
mDragWindowHandle.frameRight = displayBounds.right;
|
|
||||||
mDragWindowHandle.frameBottom = displayBounds.bottom;
|
|
||||||
|
|
||||||
// Pause rotations before a drag.
|
// Pause rotations before a drag.
|
||||||
ProtoLog.d(WM_DEBUG_ORIENTATION, "Pausing rotation during re-position");
|
ProtoLog.d(WM_DEBUG_ORIENTATION, "Pausing rotation during re-position");
|
||||||
mDisplayContent.getDisplayRotation().pause();
|
mDisplayContent.getDisplayRotation().pause();
|
||||||
@@ -250,6 +238,8 @@ class TaskPositioner implements IBinder.DeathRecipient {
|
|||||||
// Notify InputMonitor to take mDragWindowHandle.
|
// Notify InputMonitor to take mDragWindowHandle.
|
||||||
mService.mTaskPositioningController.showInputSurface(win.getDisplayId());
|
mService.mTaskPositioningController.showInputSurface(win.getDisplayId());
|
||||||
|
|
||||||
|
final Rect displayBounds = mTmpRect;
|
||||||
|
displayContent.getBounds(displayBounds);
|
||||||
final DisplayMetrics displayMetrics = displayContent.getDisplayMetrics();
|
final DisplayMetrics displayMetrics = displayContent.getDisplayMetrics();
|
||||||
mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics);
|
mMinVisibleWidth = dipToPixel(MINIMUM_VISIBLE_WIDTH_IN_DP, displayMetrics);
|
||||||
mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, displayMetrics);
|
mMinVisibleHeight = dipToPixel(MINIMUM_VISIBLE_HEIGHT_IN_DP, displayMetrics);
|
||||||
|
|||||||
@@ -83,17 +83,18 @@ class TaskPositioningController {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
mTransaction.show(mInputSurface);
|
|
||||||
mTransaction.setInputWindowInfo(mInputSurface, h);
|
|
||||||
mTransaction.setLayer(mInputSurface, Integer.MAX_VALUE);
|
|
||||||
|
|
||||||
final Display display = dc.getDisplay();
|
final Display display = dc.getDisplay();
|
||||||
final Point p = new Point();
|
final Point p = new Point();
|
||||||
display.getRealSize(p);
|
display.getRealSize(p);
|
||||||
|
|
||||||
mTmpClipRect.set(0, 0, p.x, p.y);
|
mTmpClipRect.set(0, 0, p.x, p.y);
|
||||||
mTransaction.setWindowCrop(mInputSurface, mTmpClipRect);
|
|
||||||
mTransaction.syncInputWindows().apply();
|
mTransaction.show(mInputSurface)
|
||||||
|
.setInputWindowInfo(mInputSurface, h)
|
||||||
|
.setLayer(mInputSurface, Integer.MAX_VALUE)
|
||||||
|
.setPosition(mInputSurface, 0, 0)
|
||||||
|
.setCrop(mInputSurface, mTmpClipRect)
|
||||||
|
.syncInputWindows()
|
||||||
|
.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
boolean startMovingTask(IWindow window, float startX, float startY) {
|
boolean startMovingTask(IWindow window, float startX, float startY) {
|
||||||
|
|||||||
@@ -192,6 +192,7 @@ import android.os.Handler;
|
|||||||
import android.os.HandlerExecutor;
|
import android.os.HandlerExecutor;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.IRemoteCallback;
|
import android.os.IRemoteCallback;
|
||||||
|
import android.os.InputConfig;
|
||||||
import android.os.Looper;
|
import android.os.Looper;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.Parcel;
|
import android.os.Parcel;
|
||||||
@@ -8452,43 +8453,48 @@ public class WindowManagerService extends IWindowManager.Stub
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid,
|
private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid,
|
||||||
int displayId, SurfaceControl surface, String name,
|
int displayId, SurfaceControl surface, String name,
|
||||||
InputApplicationHandle applicationHandle, int flags,
|
InputApplicationHandle applicationHandle, int flags,
|
||||||
int privateFlags, int type, Region region, IWindow window) {
|
int privateFlags, int type, Region region, IWindow window) {
|
||||||
InputWindowHandle h = new InputWindowHandle(applicationHandle, displayId);
|
final InputWindowHandle h = new InputWindowHandle(applicationHandle, displayId);
|
||||||
h.token = channelToken;
|
h.token = channelToken;
|
||||||
h.setWindowToken(window);
|
h.setWindowToken(window);
|
||||||
h.name = name;
|
h.name = name;
|
||||||
|
|
||||||
flags = sanitizeFlagSlippery(flags, name, callingUid, callingPid);
|
flags = sanitizeFlagSlippery(flags, name, callingUid, callingPid);
|
||||||
|
|
||||||
final int sanitizedFlags = flags & (FLAG_NOT_TOUCHABLE
|
final int sanitizedLpFlags =
|
||||||
| FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE);
|
(flags & (FLAG_NOT_TOUCHABLE | FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE))
|
||||||
h.layoutParamsFlags = WindowManager.LayoutParams.FLAG_NOT_TOUCH_MODAL | sanitizedFlags;
|
| LayoutParams.FLAG_NOT_TOUCH_MODAL;
|
||||||
h.layoutParamsType = type;
|
h.layoutParamsType = type;
|
||||||
h.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
h.layoutParamsFlags = sanitizedLpFlags;
|
||||||
h.focusable = (flags & LayoutParams.FLAG_NOT_FOCUSABLE) == 0;
|
|
||||||
h.hasWallpaper = false;
|
|
||||||
h.paused = false;
|
|
||||||
|
|
||||||
h.ownerUid = callingUid;
|
|
||||||
h.ownerPid = callingPid;
|
|
||||||
|
|
||||||
// Do not allow any input features to be set without sanitizing them first.
|
// Do not allow any input features to be set without sanitizing them first.
|
||||||
h.inputFeatures = 0;
|
h.inputConfig = InputConfigAdapter.getInputConfigFromWindowParams(
|
||||||
|
type, sanitizedLpFlags, 0 /*inputFeatures*/);
|
||||||
|
|
||||||
if (region == null) {
|
|
||||||
h.replaceTouchableRegionWithCrop(null);
|
if ((flags & LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
|
||||||
} else {
|
h.inputConfig |= InputConfig.NOT_FOCUSABLE;
|
||||||
h.touchableRegion.set(region);
|
|
||||||
h.replaceTouchableRegionWithCrop = false;
|
|
||||||
h.setTouchableRegionCrop(surface);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check private trusted overlay flag to set trustedOverlay field of input window handle.
|
// Check private trusted overlay flag to set trustedOverlay field of input window handle.
|
||||||
h.trustedOverlay = (privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0;
|
if ((privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) != 0) {
|
||||||
|
h.inputConfig |= InputConfig.TRUSTED_OVERLAY;
|
||||||
|
}
|
||||||
|
|
||||||
SurfaceControl.Transaction t = mTransactionFactory.get();
|
h.dispatchingTimeoutMillis = DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
|
||||||
|
h.ownerUid = callingUid;
|
||||||
|
h.ownerPid = callingPid;
|
||||||
|
|
||||||
|
if (region == null) {
|
||||||
|
h.replaceTouchableRegionWithCrop = true;
|
||||||
|
} else {
|
||||||
|
h.touchableRegion.set(region);
|
||||||
|
}
|
||||||
|
h.setTouchableRegionCrop(null /* use the input surface's bounds */);
|
||||||
|
|
||||||
|
final SurfaceControl.Transaction t = mTransactionFactory.get();
|
||||||
t.setInputWindowInfo(surface, h);
|
t.setInputWindowInfo(surface, h);
|
||||||
t.apply();
|
t.apply();
|
||||||
t.close();
|
t.close();
|
||||||
|
|||||||
@@ -1190,6 +1190,7 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP
|
|||||||
mActivityRecord != null
|
mActivityRecord != null
|
||||||
? mActivityRecord.getInputApplicationHandle(false /* update */) : null,
|
? mActivityRecord.getInputApplicationHandle(false /* update */) : null,
|
||||||
getDisplayId()));
|
getDisplayId()));
|
||||||
|
mInputWindowHandle.setFocusable(false);
|
||||||
mInputWindowHandle.setOwnerPid(s.mPid);
|
mInputWindowHandle.setOwnerPid(s.mPid);
|
||||||
mInputWindowHandle.setOwnerUid(s.mUid);
|
mInputWindowHandle.setOwnerUid(s.mUid);
|
||||||
mInputWindowHandle.setName(getName());
|
mInputWindowHandle.setName(getName());
|
||||||
|
|||||||
@@ -17,6 +17,7 @@
|
|||||||
package com.android.server.wm;
|
package com.android.server.wm;
|
||||||
|
|
||||||
import android.annotation.NonNull;
|
import android.annotation.NonNull;
|
||||||
|
import android.annotation.Nullable;
|
||||||
import android.graphics.ColorSpace;
|
import android.graphics.ColorSpace;
|
||||||
import android.graphics.GraphicBuffer;
|
import android.graphics.GraphicBuffer;
|
||||||
import android.graphics.Matrix;
|
import android.graphics.Matrix;
|
||||||
@@ -134,6 +135,12 @@ public class StubTransaction extends SurfaceControl.Transaction {
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@NonNull
|
||||||
|
public SurfaceControl.Transaction setCrop(@NonNull SurfaceControl sc, @Nullable Rect crop) {
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public SurfaceControl.Transaction setCornerRadius(SurfaceControl sc, float cornerRadius) {
|
public SurfaceControl.Transaction setCornerRadius(SurfaceControl sc, float cornerRadius) {
|
||||||
return this;
|
return this;
|
||||||
|
|||||||
@@ -29,6 +29,8 @@ import static android.view.Surface.ROTATION_90;
|
|||||||
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
|
import static android.view.WindowManager.LayoutParams.FIRST_SUB_WINDOW;
|
||||||
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
|
import static android.view.WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM;
|
||||||
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
|
||||||
|
import static android.view.WindowManager.LayoutParams.FLAG_SPLIT_TOUCH;
|
||||||
|
import static android.view.WindowManager.LayoutParams.FLAG_WATCH_OUTSIDE_TOUCH;
|
||||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
|
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
|
||||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
|
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ABOVE_SUB_PANEL;
|
||||||
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
|
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
|
||||||
@@ -81,6 +83,7 @@ import android.graphics.Matrix;
|
|||||||
import android.graphics.Point;
|
import android.graphics.Point;
|
||||||
import android.graphics.Rect;
|
import android.graphics.Rect;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
|
import android.os.InputConfig;
|
||||||
import android.os.RemoteException;
|
import android.os.RemoteException;
|
||||||
import android.platform.test.annotations.Presubmit;
|
import android.platform.test.annotations.Presubmit;
|
||||||
import android.util.ArraySet;
|
import android.util.ArraySet;
|
||||||
@@ -754,10 +757,15 @@ public class WindowStateTests extends WindowTestsBase {
|
|||||||
assertFalse(win0.canReceiveTouchInput());
|
assertFalse(win0.canReceiveTouchInput());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private boolean testFlag(int flags, int test) {
|
||||||
|
return (flags & test) == test;
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testUpdateInputWindowHandle() {
|
public void testUpdateInputWindowHandle() {
|
||||||
final WindowState win = createWindow(null, TYPE_APPLICATION, "win");
|
final WindowState win = createWindow(null, TYPE_APPLICATION, "win");
|
||||||
win.mAttrs.inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
|
win.mAttrs.inputFeatures = WindowManager.LayoutParams.INPUT_FEATURE_DISABLE_USER_ACTIVITY;
|
||||||
|
win.mAttrs.flags = FLAG_WATCH_OUTSIDE_TOUCH | FLAG_SPLIT_TOUCH;
|
||||||
final InputWindowHandle handle = new InputWindowHandle(
|
final InputWindowHandle handle = new InputWindowHandle(
|
||||||
win.mInputWindowHandle.getInputApplicationHandle(), win.getDisplayId());
|
win.mInputWindowHandle.getInputApplicationHandle(), win.getDisplayId());
|
||||||
final InputWindowHandleWrapper handleWrapper = new InputWindowHandleWrapper(handle);
|
final InputWindowHandleWrapper handleWrapper = new InputWindowHandleWrapper(handle);
|
||||||
@@ -767,13 +775,14 @@ public class WindowStateTests extends WindowTestsBase {
|
|||||||
mDisplayContent.getInputMonitor().populateInputWindowHandle(handleWrapper, win);
|
mDisplayContent.getInputMonitor().populateInputWindowHandle(handleWrapper, win);
|
||||||
|
|
||||||
assertTrue(handleWrapper.isChanged());
|
assertTrue(handleWrapper.isChanged());
|
||||||
|
assertTrue(testFlag(handle.inputConfig, InputConfig.WATCH_OUTSIDE_TOUCH));
|
||||||
|
assertFalse(testFlag(handle.inputConfig, InputConfig.PREVENT_SPLITTING));
|
||||||
|
assertTrue(testFlag(handle.inputConfig, InputConfig.DISABLE_USER_ACTIVITY));
|
||||||
// The window of standard resizable task should not use surface crop as touchable region.
|
// The window of standard resizable task should not use surface crop as touchable region.
|
||||||
assertFalse(handle.replaceTouchableRegionWithCrop);
|
assertFalse(handle.replaceTouchableRegionWithCrop);
|
||||||
assertEquals(inputChannelToken, handle.token);
|
assertEquals(inputChannelToken, handle.token);
|
||||||
assertEquals(win.mActivityRecord.getInputApplicationHandle(false /* update */),
|
assertEquals(win.mActivityRecord.getInputApplicationHandle(false /* update */),
|
||||||
handle.inputApplicationHandle);
|
handle.inputApplicationHandle);
|
||||||
assertEquals(win.mAttrs.inputFeatures, handle.inputFeatures);
|
|
||||||
assertEquals(win.isVisible(), handle.visible);
|
|
||||||
|
|
||||||
final SurfaceControl sc = mock(SurfaceControl.class);
|
final SurfaceControl sc = mock(SurfaceControl.class);
|
||||||
final SurfaceControl.Transaction transaction = mSystemServicesTestRule.mTransaction;
|
final SurfaceControl.Transaction transaction = mSystemServicesTestRule.mTransaction;
|
||||||
@@ -799,15 +808,13 @@ public class WindowStateTests extends WindowTestsBase {
|
|||||||
assertEquals(rotatedBounds, handle.touchableRegion.getBounds());
|
assertEquals(rotatedBounds, handle.touchableRegion.getBounds());
|
||||||
|
|
||||||
// Populate as an overlay to disable the input of window.
|
// Populate as an overlay to disable the input of window.
|
||||||
InputMonitor.populateOverlayInputInfo(handleWrapper, false /* isVisible */);
|
InputMonitor.populateOverlayInputInfo(handleWrapper);
|
||||||
// The overlay attributes should be set.
|
// The overlay attributes should be set.
|
||||||
assertTrue(handleWrapper.isChanged());
|
assertTrue(handleWrapper.isChanged());
|
||||||
assertFalse(handle.focusable);
|
assertFalse(handleWrapper.isFocusable());
|
||||||
assertFalse(handle.visible);
|
|
||||||
assertNull(handle.token);
|
assertNull(handle.token);
|
||||||
assertEquals(0L, handle.dispatchingTimeoutMillis);
|
assertEquals(0L, handle.dispatchingTimeoutMillis);
|
||||||
assertEquals(WindowManager.LayoutParams.INPUT_FEATURE_NO_INPUT_CHANNEL,
|
assertTrue(testFlag(handle.inputConfig, InputConfig.NO_INPUT_CHANNEL));
|
||||||
handle.inputFeatures);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|||||||
Reference in New Issue
Block a user