diff options
| author | 2020-08-19 14:45:30 +0100 | |
|---|---|---|
| committer | 2020-10-05 11:44:37 +0000 | |
| commit | 64bbd4b1d93a0150b30ebcf84fa21f6d9304ff1c (patch) | |
| tree | 7de99cdd3b45e3da7da4d9ebe5cda061055a3539 | |
| parent | abd78597dfaecf6d2d0815c494fe85ae4005f2de (diff) | |
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
| -rw-r--r-- | Android.bp | 1 | ||||
| -rw-r--r-- | api/test-current.txt | 12 | ||||
| -rw-r--r-- | core/java/android/hardware/input/InputManager.java | 137 | ||||
| -rw-r--r-- | core/java/android/provider/Settings.java | 43 | ||||
| -rw-r--r-- | core/java/android/view/InputWindowHandle.java | 9 | ||||
| -rw-r--r-- | core/jni/android_hardware_input_InputWindowHandle.cpp | 10 | ||||
| -rw-r--r-- | packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java | 2 | ||||
| -rw-r--r-- | services/core/java/com/android/server/input/InputManagerService.java | 46 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/InputMonitor.java | 2 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowState.java | 13 | ||||
| -rw-r--r-- | services/core/jni/com_android_server_input_InputManagerService.cpp | 18 | ||||
| -rw-r--r-- | services/tests/wmtests/AndroidManifest.xml | 2 |
12 files changed, 295 insertions, 0 deletions
diff --git a/Android.bp b/Android.bp index 5af77562de85..5054f990827c 100644 --- a/Android.bp +++ b/Android.bp @@ -330,6 +330,7 @@ filegroup { ":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 4c2aa5a78d69..b659f2dc73c7 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -1451,6 +1451,18 @@ package android.hardware.hdmi { } +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 dd820fae3f2d..4f46160a71e1 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.InputMonitor; 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 @@ public final class InputManager { 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 final class InputManager { 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 @@ public final class InputManager { } /** + * 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 1dbf95f7db86..f18a84e2791d 100644 --- a/core/java/android/provider/Settings.java +++ b/core/java/android/provider/Settings.java @@ -81,6 +81,7 @@ import android.util.ArraySet; 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 @@ public final class Settings { * @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 1ef701f732ff..d1a9a05d5bf1 100644 --- a/core/java/android/view/InputWindowHandle.java +++ b/core/java/android/view/InputWindowHandle.java @@ -21,6 +21,7 @@ import static android.view.Display.INVALID_DISPLAY; 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 @@ public final class InputWindowHandle { // 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 a0638207a841..463d909821b1 100644 --- a/core/jni/android_hardware_input_InputWindowHandle.cpp +++ b/core/jni/android_hardware_input_InputWindowHandle.cpp @@ -60,8 +60,10 @@ static struct { jfieldID hasWallpaper; jfieldID paused; jfieldID trustedOverlay; + jfieldID touchOcclusionMode; jfieldID ownerPid; jfieldID ownerUid; + jfieldID packageName; jfieldID inputFeatures; jfieldID displayId; jfieldID portalToDisplayId; @@ -150,10 +152,13 @@ bool NativeInputWindowHandle::updateInfo() { 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 @@ int register_android_view_InputWindowHandle(JNIEnv* env) { 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 e027fd397cdd..34b7298103b5 100644 --- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java +++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java @@ -159,6 +159,7 @@ public class SettingsBackupTest { 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 @@ public class SettingsBackupTest { 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 cc8a330b5edb..a2304f4ad158 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 @@ public class InputManagerService extends IInputManager.Stub 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 @@ public class InputManagerService extends IInputManager.Stub registerShowTouchesSettingObserver(); registerAccessibilityLargePointerSettingObserver(); registerLongPressTimeoutObserver(); + registerMaximumObscuringOpacityForTouchSettingObserver(); + registerBlockUntrustedTouchesModeSettingObserver(); mContext.registerReceiver(new BroadcastReceiver() { @Override @@ -414,6 +418,8 @@ public class InputManagerService extends IInputManager.Stub updateShowTouchesFromSettings(); updateAccessibilityLargePointerFromSettings(); updateDeepPressStatusFromSettings("just booted"); + updateMaximumObscuringOpacityForTouchFromSettings(); + updateBlockUntrustedTouchesModeFromSettings(); } // TODO(BT) Pass in parameter for bluetooth system @@ -1739,6 +1745,46 @@ public class InputManagerService extends IInputManager.Stub }, 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 acf5f75f7e23..803a5330ecc5 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 @@ final class InputMonitor { 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 ad2817720387..8d03e89a6fd0 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.ACTIVITY_TYPE_HOME; 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.CallSuper; 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.PowerManager.WakeReason; 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 @@ class WindowState extends WindowContainer<WindowState> implements WindowManagerP : 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 e39a3d1e9cb5..d14780e59ab1 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 @@ static void nativeSetInTouchMode(JNIEnv* /* env */, jclass /* clazz */, 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 @@ static const JNINativeMethod gInputManagerMethods[] = { {"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 e3c795d03381..9099272a0fd6 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" |