Block untrusted touches opt-in
The feature is disabled by default and can be in one of 3 modes:
disabled, permissive and block. In permissive we only log but
don't block the touch. This knob is implemented in a global setting
block_untrusted_touches. It can also be disabled per occluding app using
app-compat infrastructure, so if you disable for a certain app, overlays
of that app won't have the chance of blocking touches. More details
on these on go/try-cross-uid-touches.
Each window has 3 modes related to touch occlusion: ALLOW, USE_OPACITY
or BLOCK_UNTRUSTRED. Check code comments for the meaning of each. If the
feature is turned off for the app, then the mode is ALLOW. Else if it's
a SAW, then it's USE_OPACITY. Else it's BLOCK_UNTRUSTED. These states
are passed to InputDispatcher, who then perform the proper checks and
blocks or not the touch.
If input dispatcher deems the touch unsafe, depending on the feature
mode, we filter out such touches and log a message to logcat.
I also introduce a global (secure) setting
MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH which represents the maximum
opacity allowed per UID that's obscuring the touch-consuming window
according to some rules, which are discussed in topic CL for
InputDispatcher code. This maximum is initially set to 0.8, but we'll
be conducting local experiments to determine the final value.
Test: atest WindowUntrustedTouchTest
Test: atest inputflinger_tests inputflinger_benchmarks libinput_tests
Test: go/try-cross-uid-touches for manual testing
Bug: 158002302
Change-Id: I462858ad5f0d11b1261748489385e6409e38e4b1
diff --git a/Android.bp b/Android.bp
index 5af7756..5054f99 100644
--- a/Android.bp
+++ b/Android.bp
@@ -330,6 +330,7 @@
":gatekeeper_aidl",
":gsiservice_aidl",
":incidentcompanion_aidl",
+ ":inputconstants_aidl",
":installd_aidl",
":keystore_aidl",
":libaudioclient_aidl",
diff --git a/api/test-current.txt b/api/test-current.txt
index 4c2aa5a..b659f2d 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1451,6 +1451,18 @@
}
+package android.hardware.input {
+
+ public final class InputManager {
+ method public int getBlockUntrustedTouchesMode(@NonNull android.content.Context);
+ method public float getMaximumObscuringOpacityForTouch(@NonNull android.content.Context);
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setBlockUntrustedTouchesMode(@NonNull android.content.Context, int);
+ method @RequiresPermission(android.Manifest.permission.WRITE_SECURE_SETTINGS) public void setMaximumObscuringOpacityForTouch(@NonNull android.content.Context, float);
+ field public static final long BLOCK_UNTRUSTED_TOUCHES = 158002302L; // 0x96aec7eL
+ }
+
+}
+
package android.hardware.lights {
public final class Light implements android.os.Parcelable {
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index dd820fa..4f46160 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -16,17 +16,22 @@
package android.hardware.input;
+import android.Manifest;
import android.annotation.CallbackExecutor;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
import android.annotation.SdkConstant;
import android.annotation.SdkConstant.SdkConstantType;
import android.annotation.SystemService;
+import android.annotation.TestApi;
+import android.compat.annotation.ChangeId;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.media.AudioAttributes;
import android.os.Binder;
+import android.os.BlockUntrustedTouchesMode;
import android.os.Build;
import android.os.Handler;
import android.os.IBinder;
@@ -48,8 +53,10 @@
import android.view.MotionEvent;
import android.view.PointerIcon;
import android.view.VerifiedInputEvent;
+import android.view.WindowManager.LayoutParams;
import com.android.internal.os.SomeArgs;
+import com.android.internal.util.ArrayUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -69,6 +76,13 @@
private static final int MSG_DEVICE_REMOVED = 2;
private static final int MSG_DEVICE_CHANGED = 3;
+ /** @hide */
+ public static final int[] BLOCK_UNTRUSTED_TOUCHES_MODES = {
+ BlockUntrustedTouchesMode.DISABLED,
+ BlockUntrustedTouchesMode.PERMISSIVE,
+ BlockUntrustedTouchesMode.BLOCK
+ };
+
private static InputManager sInstance;
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
@@ -168,6 +182,32 @@
public static final int DEFAULT_POINTER_SPEED = 0;
/**
+ * The maximum allowed obscuring opacity by UID to propagate touches (0 <= x <= 1).
+ * @hide
+ */
+ public static final float DEFAULT_MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH = .8f;
+
+ /**
+ * Default mode of the block untrusted touches mode feature.
+ * @hide
+ */
+ @BlockUntrustedTouchesMode
+ public static final int DEFAULT_BLOCK_UNTRUSTED_TOUCHES_MODE =
+ BlockUntrustedTouchesMode.DISABLED;
+
+ /**
+ * Prevent touches from being consumed by apps if these touches passed through a non-trusted
+ * window from a different UID and are considered unsafe.
+ *
+ * TODO(b/158002302): Turn the feature on by default
+ *
+ * @hide
+ */
+ @TestApi
+ @ChangeId
+ public static final long BLOCK_UNTRUSTED_TOUCHES = 158002302L;
+
+ /**
* Input Event Injection Synchronization Mode: None.
* Never blocks. Injection is asynchronous and is assumed always to be successful.
* @hide
@@ -832,6 +872,103 @@
}
/**
+ * Returns the maximum allowed obscuring opacity by UID to propagate touches.
+ *
+ * For certain window types (eg. SAWs), the decision of honoring {@link LayoutParams
+ * #FLAG_NOT_TOUCHABLE} or not depends on the combined obscuring opacity of the windows
+ * above the touch-consuming window.
+ *
+ * @see #setMaximumObscuringOpacityForTouch(Context, float)
+ *
+ * @hide
+ */
+ @TestApi
+ public float getMaximumObscuringOpacityForTouch(@NonNull Context context) {
+ return Settings.Global.getFloat(context.getContentResolver(),
+ Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH,
+ DEFAULT_MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH);
+ }
+
+ /**
+ * Sets the maximum allowed obscuring opacity by UID to propagate touches.
+ *
+ * For certain window types (eg. SAWs), the decision of honoring {@link LayoutParams
+ * #FLAG_NOT_TOUCHABLE} or not depends on the combined obscuring opacity of the windows
+ * above the touch-consuming window.
+ *
+ * For a certain UID:
+ * <ul>
+ * <li>If it's the same as the UID of the touch-consuming window, allow it to propagate
+ * the touch.
+ * <li>Otherwise take all its windows of eligible window types above the touch-consuming
+ * window, compute their combined obscuring opacity considering that {@code
+ * opacity(A, B) = 1 - (1 - opacity(A))*(1 - opacity(B))}. If the computed value is
+ * lesser than or equal to this setting and there are no other windows preventing the
+ * touch, allow the UID to propagate the touch.
+ * </ul>
+ *
+ * This value should be between 0 (inclusive) and 1 (inclusive).
+ *
+ * @see #getMaximumObscuringOpacityForTouch(Context)
+ *
+ * @hide
+ */
+ @TestApi
+ @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+ public void setMaximumObscuringOpacityForTouch(@NonNull Context context, float opacity) {
+ if (opacity < 0 || opacity > 1) {
+ throw new IllegalArgumentException(
+ "Maximum obscuring opacity for touch should be >= 0 and <= 1");
+ }
+ Settings.Global.putFloat(context.getContentResolver(),
+ Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH, opacity);
+ }
+
+ /**
+ * Returns the current mode of the block untrusted touches feature, one of:
+ * <ul>
+ * <li>{@link BlockUntrustedTouchesMode#DISABLED}
+ * <li>{@link BlockUntrustedTouchesMode#PERMISSIVE}
+ * <li>{@link BlockUntrustedTouchesMode#BLOCK}
+ * </ul>
+ *
+ * @hide
+ */
+ @TestApi
+ @BlockUntrustedTouchesMode
+ public int getBlockUntrustedTouchesMode(@NonNull Context context) {
+ int mode = Settings.Global.getInt(context.getContentResolver(),
+ Settings.Global.BLOCK_UNTRUSTED_TOUCHES_MODE, DEFAULT_BLOCK_UNTRUSTED_TOUCHES_MODE);
+ if (!ArrayUtils.contains(BLOCK_UNTRUSTED_TOUCHES_MODES, mode)) {
+ Log.w(TAG, "Unknown block untrusted touches feature mode " + mode + ", using "
+ + "default " + DEFAULT_BLOCK_UNTRUSTED_TOUCHES_MODE);
+ return DEFAULT_BLOCK_UNTRUSTED_TOUCHES_MODE;
+ }
+ return mode;
+ }
+
+ /**
+ * Sets the mode of the block untrusted touches feature to one of:
+ * <ul>
+ * <li>{@link BlockUntrustedTouchesMode#DISABLED}
+ * <li>{@link BlockUntrustedTouchesMode#PERMISSIVE}
+ * <li>{@link BlockUntrustedTouchesMode#BLOCK}
+ * </ul>
+ *
+ * @hide
+ */
+ @TestApi
+ @RequiresPermission(Manifest.permission.WRITE_SECURE_SETTINGS)
+ public void setBlockUntrustedTouchesMode(@NonNull Context context,
+ @BlockUntrustedTouchesMode int mode) {
+ if (!ArrayUtils.contains(BLOCK_UNTRUSTED_TOUCHES_MODES, mode)) {
+ throw new IllegalArgumentException("Invalid feature mode " + mode);
+ }
+ Settings.Global.putInt(context.getContentResolver(),
+ Settings.Global.BLOCK_UNTRUSTED_TOUCHES_MODE, mode);
+ }
+
+ /**
* Queries the framework about whether any physical keys exist on the
* any keyboard attached to the device that are capable of producing the given
* array of key codes.
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1dbf95f..f18a84e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -81,6 +81,7 @@
import android.util.Log;
import android.util.MemoryIntArray;
import android.view.Display;
+import android.view.WindowManager.LayoutParams;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.Preconditions;
@@ -14486,6 +14487,48 @@
* @hide
*/
public static final String SHOW_PEOPLE_SPACE = "show_people_space";
+
+ /**
+ * Block untrusted touches mode.
+ *
+ * Can be one of:
+ * <ul>
+ * <li>0 = {@link BlockUntrustedTouchesMode#DISABLED}: Feature is off.
+ * <li>1 = {@link BlockUntrustedTouchesMode#PERMISSIVE}: Untrusted touches are flagged
+ * but not blocked
+ * <li>2 = {@link BlockUntrustedTouchesMode#BLOCK}: Untrusted touches are blocked
+ * </ul>
+ *
+ * @hide
+ */
+ public static final String BLOCK_UNTRUSTED_TOUCHES_MODE = "block_untrusted_touches";
+
+ /**
+ * The maximum allowed obscuring opacity by UID to propagate touches.
+ *
+ * For certain window types (eg. SAWs), the decision of honoring {@link LayoutParams
+ * #FLAG_NOT_TOUCHABLE} or not depends on the combined obscuring opacity of the windows
+ * above the touch-consuming window.
+ *
+ * For a certain UID:
+ * <ul>
+ * <li>If it's the same as the UID of the touch-consuming window, allow it to propagate
+ * the touch.
+ * <li>Otherwise take all its windows of eligible window types above the touch-consuming
+ * window, compute their combined obscuring opacity considering that {@code
+ * opacity(A, B) = 1 - (1 - opacity(A))*(1 - opacity(B))}. If the computed value is
+ * lesser than or equal to this setting and there are no other windows preventing the
+ * touch, allow the UID to propagate the touch.
+ * </ul>
+ *
+ * @see android.hardware.input.InputManager#getMaximumObscuringOpacityForTouch(Context)
+ * @see android.hardware.input.InputManager#setMaximumObscuringOpacityForTouch(Context,
+ * float)
+ *
+ * @hide
+ */
+ public static final String MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH =
+ "maximum_obscuring_opacity_for_touch";
}
/**
diff --git a/core/java/android/view/InputWindowHandle.java b/core/java/android/view/InputWindowHandle.java
index 1ef701f..d1a9a05 100644
--- a/core/java/android/view/InputWindowHandle.java
+++ b/core/java/android/view/InputWindowHandle.java
@@ -21,6 +21,7 @@
import android.annotation.Nullable;
import android.graphics.Region;
import android.os.IBinder;
+import android.os.TouchOcclusionMode;
import java.lang.ref.WeakReference;
@@ -82,10 +83,18 @@
// Window is trusted overlay.
public boolean trustedOverlay;
+ // 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;
+
// Window input features.
public int inputFeatures;
diff --git a/core/jni/android_hardware_input_InputWindowHandle.cpp b/core/jni/android_hardware_input_InputWindowHandle.cpp
index a063820..463d909 100644
--- a/core/jni/android_hardware_input_InputWindowHandle.cpp
+++ b/core/jni/android_hardware_input_InputWindowHandle.cpp
@@ -60,8 +60,10 @@
jfieldID hasWallpaper;
jfieldID paused;
jfieldID trustedOverlay;
+ jfieldID touchOcclusionMode;
jfieldID ownerPid;
jfieldID ownerUid;
+ jfieldID packageName;
jfieldID inputFeatures;
jfieldID displayId;
jfieldID portalToDisplayId;
@@ -150,10 +152,13 @@
mInfo.paused = env->GetBooleanField(obj,
gInputWindowHandleClassInfo.paused);
mInfo.trustedOverlay = env->GetBooleanField(obj, gInputWindowHandleClassInfo.trustedOverlay);
+ mInfo.touchOcclusionMode = static_cast<TouchOcclusionMode>(
+ env->GetIntField(obj, gInputWindowHandleClassInfo.touchOcclusionMode));
mInfo.ownerPid = env->GetIntField(obj,
gInputWindowHandleClassInfo.ownerPid);
mInfo.ownerUid = env->GetIntField(obj,
gInputWindowHandleClassInfo.ownerUid);
+ mInfo.packageName = getStringField(env, obj, gInputWindowHandleClassInfo.packageName, "<null>");
mInfo.inputFeatures = static_cast<InputWindowInfo::Feature>(
env->GetIntField(obj, gInputWindowHandleClassInfo.inputFeatures));
mInfo.displayId = env->GetIntField(obj,
@@ -326,12 +331,17 @@
GET_FIELD_ID(gInputWindowHandleClassInfo.trustedOverlay, clazz, "trustedOverlay", "Z");
+ GET_FIELD_ID(gInputWindowHandleClassInfo.touchOcclusionMode, clazz, "touchOcclusionMode", "I");
+
GET_FIELD_ID(gInputWindowHandleClassInfo.ownerPid, clazz,
"ownerPid", "I");
GET_FIELD_ID(gInputWindowHandleClassInfo.ownerUid, clazz,
"ownerUid", "I");
+ GET_FIELD_ID(gInputWindowHandleClassInfo.packageName, clazz, "packageName",
+ "Ljava/lang/String;");
+
GET_FIELD_ID(gInputWindowHandleClassInfo.inputFeatures, clazz,
"inputFeatures", "I");
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index e027fd3..34b7298 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -159,6 +159,7 @@
Settings.Global.BLE_SCAN_LOW_LATENCY_WINDOW_MS,
Settings.Global.BLE_SCAN_LOW_LATENCY_INTERVAL_MS,
Settings.Global.BLE_SCAN_BACKGROUND_MODE,
+ Settings.Global.BLOCK_UNTRUSTED_TOUCHES_MODE,
Settings.Global.BLOCKED_SLICES,
Settings.Global.BLOCKING_HELPER_DISMISS_TO_VIEW_RATIO_LIMIT,
Settings.Global.BLOCKING_HELPER_STREAK_LIMIT,
@@ -332,6 +333,7 @@
Settings.Global.MAX_ERROR_BYTES_PREFIX,
Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE,
Settings.Global.MAX_SOUND_TRIGGER_DETECTION_SERVICE_OPS_PER_DAY,
+ Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH,
Settings.Global.MDC_INITIAL_MAX_RETRY,
Settings.Global.MHL_INPUT_SWITCHING_ENABLED,
Settings.Global.MHL_POWER_CHARGE_ENABLED,
diff --git a/services/core/java/com/android/server/input/InputManagerService.java b/services/core/java/com/android/server/input/InputManagerService.java
index cc8a330..a2304f4 100644
--- a/services/core/java/com/android/server/input/InputManagerService.java
+++ b/services/core/java/com/android/server/input/InputManagerService.java
@@ -231,6 +231,8 @@
private static native void nativePilferPointers(long ptr, IBinder token);
private static native void nativeSetInputFilterEnabled(long ptr, boolean enable);
private static native void nativeSetInTouchMode(long ptr, boolean inTouchMode);
+ private static native void nativeSetMaximumObscuringOpacityForTouch(long ptr, float opacity);
+ private static native void nativeSetBlockUntrustedTouchesMode(long ptr, int mode);
private static native int nativeInjectInputEvent(long ptr, InputEvent event,
int injectorPid, int injectorUid, int syncMode, int timeoutMillis,
int policyFlags);
@@ -399,6 +401,8 @@
registerShowTouchesSettingObserver();
registerAccessibilityLargePointerSettingObserver();
registerLongPressTimeoutObserver();
+ registerMaximumObscuringOpacityForTouchSettingObserver();
+ registerBlockUntrustedTouchesModeSettingObserver();
mContext.registerReceiver(new BroadcastReceiver() {
@Override
@@ -414,6 +418,8 @@
updateShowTouchesFromSettings();
updateAccessibilityLargePointerFromSettings();
updateDeepPressStatusFromSettings("just booted");
+ updateMaximumObscuringOpacityForTouchFromSettings();
+ updateBlockUntrustedTouchesModeFromSettings();
}
// TODO(BT) Pass in parameter for bluetooth system
@@ -1739,6 +1745,46 @@
}, UserHandle.USER_ALL);
}
+ private void registerBlockUntrustedTouchesModeSettingObserver() {
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.BLOCK_UNTRUSTED_TOUCHES_MODE),
+ /* notifyForDescendants */ true,
+ new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updateBlockUntrustedTouchesModeFromSettings();
+ }
+ }, UserHandle.USER_ALL);
+ }
+
+ private void updateBlockUntrustedTouchesModeFromSettings() {
+ final int mode = InputManager.getInstance().getBlockUntrustedTouchesMode(mContext);
+ nativeSetBlockUntrustedTouchesMode(mPtr, mode);
+ }
+
+ private void registerMaximumObscuringOpacityForTouchSettingObserver() {
+ mContext.getContentResolver().registerContentObserver(
+ Settings.Global.getUriFor(Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH),
+ /* notifyForDescendants */ true,
+ new ContentObserver(mHandler) {
+ @Override
+ public void onChange(boolean selfChange) {
+ updateMaximumObscuringOpacityForTouchFromSettings();
+ }
+ }, UserHandle.USER_ALL);
+ }
+
+ private void updateMaximumObscuringOpacityForTouchFromSettings() {
+ final float opacity = InputManager.getInstance().getMaximumObscuringOpacityForTouch(
+ mContext);
+ if (opacity < 0 || opacity > 1) {
+ Log.e(TAG, "Invalid maximum obscuring opacity " + opacity
+ + ", it should be >= 0 and <= 1, rejecting update.");
+ return;
+ }
+ nativeSetMaximumObscuringOpacityForTouch(mPtr, opacity);
+ }
+
private int getShowTouchesSetting(int defaultValue) {
int result = defaultValue;
try {
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index acf5f75..803a533 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -285,10 +285,12 @@
inputWindowHandle.dispatchingTimeoutMillis = child.getInputDispatchingTimeoutMillis();
inputWindowHandle.visible = isVisible;
inputWindowHandle.focusable = focusable;
+ inputWindowHandle.touchOcclusionMode = child.getTouchOcclusionMode();
inputWindowHandle.hasWallpaper = hasWallpaper;
inputWindowHandle.paused = child.mActivityRecord != null ? child.mActivityRecord.paused : false;
inputWindowHandle.ownerPid = child.mSession.mPid;
inputWindowHandle.ownerUid = child.mSession.mUid;
+ inputWindowHandle.packageName = child.getOwningPackage();
inputWindowHandle.inputFeatures = child.mAttrs.inputFeatures;
inputWindowHandle.displayId = child.getDisplayId();
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index ad28177..8d03e89 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -25,6 +25,7 @@
import static android.app.WindowConfiguration.isSplitScreenWindowingMode;
import static android.content.res.Configuration.ORIENTATION_LANDSCAPE;
import static android.graphics.GraphicsProtos.dumpPointProto;
+import static android.hardware.input.InputManager.BLOCK_UNTRUSTED_TOUCHES;
import static android.os.IInputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
import static android.os.PowerManager.DRAW_WAKE_LOCK;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
@@ -182,6 +183,7 @@
import android.annotation.Nullable;
import android.app.AppOpsManager;
import android.app.admin.DevicePolicyCache;
+import android.app.compat.CompatChanges;
import android.content.Context;
import android.content.res.Configuration;
import android.graphics.Matrix;
@@ -198,6 +200,7 @@
import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.SystemClock;
+import android.os.TouchOcclusionMode;
import android.os.Trace;
import android.os.WorkSource;
import android.provider.Settings;
@@ -958,6 +961,16 @@
: service.mAtmService.getProcessController(s.mPid, s.mUid);
}
+ int getTouchOcclusionMode() {
+ if (!CompatChanges.isChangeEnabled(BLOCK_UNTRUSTED_TOUCHES, mOwnerUid)) {
+ return TouchOcclusionMode.ALLOW;
+ }
+ if (WindowManager.LayoutParams.isSystemAlertWindowType(mAttrs.type)) {
+ return TouchOcclusionMode.USE_OPACITY;
+ }
+ return TouchOcclusionMode.BLOCK_UNTRUSTED;
+ }
+
void attach() {
if (DEBUG) Slog.v(TAG, "Attaching " + this + " token=" + mToken);
mSession.windowAddedLocked(mAttrs.packageName);
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index e39a3d1..d14780e 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -1453,6 +1453,21 @@
im->getInputManager()->getDispatcher()->setInTouchMode(inTouchMode);
}
+static void nativeSetMaximumObscuringOpacityForTouch(JNIEnv* /* env */, jclass /* clazz */,
+ jlong ptr, jfloat opacity) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+ im->getInputManager()->getDispatcher()->setMaximumObscuringOpacityForTouch(opacity);
+}
+
+static void nativeSetBlockUntrustedTouchesMode(JNIEnv* env, jclass /* clazz */, jlong ptr,
+ jint mode) {
+ NativeInputManager* im = reinterpret_cast<NativeInputManager*>(ptr);
+
+ im->getInputManager()->getDispatcher()->setBlockUntrustedTouchesMode(
+ static_cast<BlockUntrustedTouchesMode>(mode));
+}
+
static jint nativeInjectInputEvent(JNIEnv* env, jclass /* clazz */,
jlong ptr, jobject inputEventObj, jint injectorPid, jint injectorUid,
jint syncMode, jint timeoutMillis, jint policyFlags) {
@@ -1790,6 +1805,9 @@
{"nativePilferPointers", "(JLandroid/os/IBinder;)V", (void*)nativePilferPointers},
{"nativeSetInputFilterEnabled", "(JZ)V", (void*)nativeSetInputFilterEnabled},
{"nativeSetInTouchMode", "(JZ)V", (void*)nativeSetInTouchMode},
+ {"nativeSetMaximumObscuringOpacityForTouch", "(JF)V",
+ (void*)nativeSetMaximumObscuringOpacityForTouch},
+ {"nativeSetBlockUntrustedTouchesMode", "(JI)V", (void*)nativeSetBlockUntrustedTouchesMode},
{"nativeInjectInputEvent", "(JLandroid/view/InputEvent;IIIII)I",
(void*)nativeInjectInputEvent},
{"nativeVerifyInputEvent", "(JLandroid/view/InputEvent;)Landroid/view/VerifiedInputEvent;",
diff --git a/services/tests/wmtests/AndroidManifest.xml b/services/tests/wmtests/AndroidManifest.xml
index e3c795d..9099272 100644
--- a/services/tests/wmtests/AndroidManifest.xml
+++ b/services/tests/wmtests/AndroidManifest.xml
@@ -39,6 +39,8 @@
<uses-permission android:name="android.permission.READ_DEVICE_CONFIG" />
<uses-permission android:name="android.permission.STATUS_BAR" />
<uses-permission android:name="android.permission.CAPTURE_VIDEO_OUTPUT" />
+ <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
+ <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE" />
<!-- TODO: Remove largeHeap hack when memory leak is fixed (b/123984854) -->
<application android:debuggable="true"