Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit a451d5ba authored by Bernardo Rufino's avatar Bernardo Rufino
Browse files

Cap alpha to max if SAW + FLAG_NOT_TOUCHABLE

As part of go/untrusted-touches for S, we blocked touches from passing
windows of different UIDs regardless of targetSdk. For SAWs, we applied
an opacity rule where apps would be able to let touches pass through
(usually via FLAG_NOT_TOUCHABLE) as long as their cumulative opacity in
the touch area wasn't greater than 0.8.

This resulted in some overlay apps being broken, which we expected and
saw to some extent in df/dp/beta, but we had reached out and some apps
fixed the issue. But the issue seems to be more widespread and OEM has
escalated the issue, reporting it to be affecting them more severely
(see bug).

So, we automatically make SAW + FLAG_NOT_TOUCHABLE windows have 20%
transparency to try to honor FLAG_NOT_TOUCHABLE and let touches pass
through. Note that if the app has overlapping windows the cumulative
opacity would be taken into consideration and the touch could still be
blocked, but none among the apps I checked did that.

Test: atest -d android.server.wm.WindowUntrustedTouchTest
Test: Install and enable you.in.spark.energy.curved, verify touches work
      in the top part of the screen.
Bug: 218777508
Merged-In: I3a74e1cc43a36171ee10fbf68c4bfff538eee661
Change-Id: I3a74e1cc43a36171ee10fbf68c4bfff538eee661
parent ded7bcc7
Loading
Loading
Loading
Loading
+20 −0
Original line number Diff line number Diff line
@@ -967,6 +967,26 @@ public class DisplayPolicy {
                break;
        }

        if (LayoutParams.isSystemAlertWindowType(attrs.type)) {
            float maxOpacity = mService.mMaximumObscuringOpacityForTouch;
            if (attrs.alpha > maxOpacity
                    && (attrs.flags & FLAG_NOT_TOUCHABLE) != 0
                    && (attrs.privateFlags & PRIVATE_FLAG_TRUSTED_OVERLAY) == 0) {
                // The app is posting a SAW with the intent of letting touches pass through, but
                // they are going to be deemed untrusted and will be blocked. Try to honor the
                // intent of letting touches pass through at the cost of 0.2 opacity for app
                // compatibility reasons. More details on b/218777508.
                Slog.w(TAG, String.format(
                        "App %s has a system alert window (type = %d) with FLAG_NOT_TOUCHABLE and "
                                + "LayoutParams.alpha = %.2f > %.2f, setting alpha to %.2f to "
                                + "let touches pass through (if this is isn't desirable, remove "
                                + "flag FLAG_NOT_TOUCHABLE).",
                        attrs.packageName, attrs.type, attrs.alpha, maxOpacity, maxOpacity));
                attrs.alpha = maxOpacity;
                win.mWinAnimator.mAlpha = maxOpacity;
            }
        }

        // Check if alternate bars positions were updated.
        if (mStatusBarAlt == win) {
            mStatusBarAltPosition = getAltBarPosition(attrs);
+20 −0
Original line number Diff line number Diff line
@@ -769,6 +769,9 @@ public class WindowManagerService extends IWindowManager.Stub

    private final DisplayHashController mDisplayHashController;

    volatile float mMaximumObscuringOpacityForTouch =
            InputManager.DEFAULT_MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH;

    @VisibleForTesting
    final WindowContextListenerController mWindowContextListenerController =
            new WindowContextListenerController();
@@ -801,6 +804,8 @@ public class WindowManagerService extends IWindowManager.Stub
                DEVELOPMENT_RENDER_SHADOWS_IN_COMPOSITOR);
        private final Uri mDisplaySettingsPathUri = Settings.Global.getUriFor(
                DEVELOPMENT_WM_DISPLAY_SETTINGS_PATH);
        private final Uri mMaximumObscuringOpacityForTouchUri = Settings.Global.getUriFor(
                Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH);

        public SettingsObserver() {
            super(new Handler());
@@ -827,6 +832,8 @@ public class WindowManagerService extends IWindowManager.Stub
                    UserHandle.USER_ALL);
            resolver.registerContentObserver(mDisplaySettingsPathUri, false, this,
                    UserHandle.USER_ALL);
            resolver.registerContentObserver(mMaximumObscuringOpacityForTouchUri, false, this,
                    UserHandle.USER_ALL);
        }

        @Override
@@ -875,6 +882,11 @@ public class WindowManagerService extends IWindowManager.Stub
                return;
            }

            if (mMaximumObscuringOpacityForTouchUri.equals(uri)) {
                updateMaximumObscuringOpacityForTouch();
                return;
            }

            @UpdateAnimationScaleMode
            final int mode;
            if (mWindowAnimationScaleUri.equals(uri)) {
@@ -894,6 +906,14 @@ public class WindowManagerService extends IWindowManager.Stub
        void loadSettings() {
            updateSystemUiSettings(false /* handleChange */);
            updatePointerLocation();
            updateMaximumObscuringOpacityForTouch();
        }

        void updateMaximumObscuringOpacityForTouch() {
            ContentResolver resolver = mContext.getContentResolver();
            mMaximumObscuringOpacityForTouch = Settings.Global.getFloat(resolver,
                    Settings.Global.MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH,
                    InputManager.DEFAULT_MAXIMUM_OBSCURING_OPACITY_FOR_TOUCH);
        }

        void updateSystemUiSettings(boolean handleChange) {