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

Commit 35cf0e98 authored by Jeff Brown's avatar Jeff Brown
Browse files

Make secure views tolerate IME overlays.

Change-Id: I3cf09b9d91045f4d9c558b4aace482a7b0bbd3d8
parent f39ed4b5
Loading
Loading
Loading
Loading
+9 −2
Original line number Original line Diff line number Diff line
@@ -212,8 +212,15 @@ struct InputWindow {
    int32_t ownerPid;
    int32_t ownerPid;
    int32_t ownerUid;
    int32_t ownerUid;


    bool visibleFrameIntersects(const InputWindow* other) const;
    bool touchableAreaContainsPoint(int32_t x, int32_t y) const;
    bool touchableAreaContainsPoint(int32_t x, int32_t y) const;
    bool frameContainsPoint(int32_t x, int32_t y) const;

    /* Returns true if the window is of a trusted type that is allowed to silently
     * overlay other windows for the purpose of implementing the secure views feature.
     * Trusted overlays, such as IME windows, can partly obscure other windows without causing
     * motion events to be delivered to them with AMOTION_EVENT_FLAG_WINDOW_IS_OBSCURED.
     */
    bool isTrustedOverlay() const;
};
};




@@ -962,7 +969,7 @@ private:
    bool shouldPokeUserActivityForCurrentInputTargetsLocked();
    bool shouldPokeUserActivityForCurrentInputTargetsLocked();
    void pokeUserActivityLocked(nsecs_t eventTime, int32_t eventType);
    void pokeUserActivityLocked(nsecs_t eventTime, int32_t eventType);
    bool checkInjectionPermission(const InputWindow* window, const InjectionState* injectionState);
    bool checkInjectionPermission(const InputWindow* window, const InjectionState* injectionState);
    bool isWindowObscuredLocked(const InputWindow* window);
    bool isWindowObscuredAtPointLocked(const InputWindow* window, int32_t x, int32_t y) const;
    bool isWindowFinishedWithPreviousInputLocked(const InputWindow* window);
    bool isWindowFinishedWithPreviousInputLocked(const InputWindow* window);
    String8 getApplicationWindowLabelLocked(const InputApplication* application,
    String8 getApplicationWindowLabelLocked(const InputApplication* application,
            const InputWindow* window);
            const InputWindow* window);
+30 −27
Original line number Original line Diff line number Diff line
@@ -134,18 +134,21 @@ static bool validateMotionEvent(int32_t action, size_t pointerCount,


// --- InputWindow ---
// --- InputWindow ---


bool InputWindow::visibleFrameIntersects(const InputWindow* other) const {
    return visibleFrameRight > other->visibleFrameLeft
        && visibleFrameLeft < other->visibleFrameRight
        && visibleFrameBottom > other->visibleFrameTop
        && visibleFrameTop < other->visibleFrameBottom;
}

bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
bool InputWindow::touchableAreaContainsPoint(int32_t x, int32_t y) const {
    return x >= touchableAreaLeft && x <= touchableAreaRight
    return x >= touchableAreaLeft && x <= touchableAreaRight
            && y >= touchableAreaTop && y <= touchableAreaBottom;
            && y >= touchableAreaTop && y <= touchableAreaBottom;
}
}


bool InputWindow::frameContainsPoint(int32_t x, int32_t y) const {
    return x >= frameLeft && x <= frameRight
            && y >= frameTop && y <= frameBottom;
}

bool InputWindow::isTrustedOverlay() const {
    return layoutParamsType == TYPE_INPUT_METHOD
            || layoutParamsType == TYPE_INPUT_METHOD_DIALOG;
}



// --- InputDispatcher ---
// --- InputDispatcher ---


@@ -1053,8 +1056,12 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,


                if (maskedAction == AMOTION_EVENT_ACTION_DOWN
                if (maskedAction == AMOTION_EVENT_ACTION_DOWN
                        && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
                        && (flags & InputWindow::FLAG_WATCH_OUTSIDE_TOUCH)) {
                    mTempTouchState.addOrUpdateWindow(window,
                    int32_t outsideTargetFlags = InputTarget::FLAG_OUTSIDE;
                            InputTarget::FLAG_OUTSIDE, BitSet32(0));
                    if (isWindowObscuredAtPointLocked(window, x, y)) {
                        outsideTargetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
                    }

                    mTempTouchState.addOrUpdateWindow(window, outsideTargetFlags, BitSet32(0));
                }
                }
            }
            }
        }
        }
@@ -1083,10 +1090,6 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
            // (May be NULL which is why we put this code block before the next check.)
            // (May be NULL which is why we put this code block before the next check.)
            newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
            newTouchedWindow = mTempTouchState.getFirstForegroundWindow();
        }
        }
        int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
        if (isSplit) {
            targetFlags |= InputTarget::FLAG_SPLIT;
        }


        // If we did not find a touched window then fail.
        // If we did not find a touched window then fail.
        if (! newTouchedWindow) {
        if (! newTouchedWindow) {
@@ -1106,6 +1109,15 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
            goto Failed;
            goto Failed;
        }
        }


        // Set target flags.
        int32_t targetFlags = InputTarget::FLAG_FOREGROUND;
        if (isSplit) {
            targetFlags |= InputTarget::FLAG_SPLIT;
        }
        if (isWindowObscuredAtPointLocked(newTouchedWindow, x, y)) {
            targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
        }

        // Update the temporary touch state.
        // Update the temporary touch state.
        BitSet32 pointerIds;
        BitSet32 pointerIds;
        if (isSplit) {
        if (isSplit) {
@@ -1186,19 +1198,9 @@ int32_t InputDispatcher::findTouchedWindowTargetsLocked(nsecs_t currentTime,
            for (size_t i = 0; i < mWindows.size(); i++) {
            for (size_t i = 0; i < mWindows.size(); i++) {
                const InputWindow* window = & mWindows[i];
                const InputWindow* window = & mWindows[i];
                if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
                if (window->layoutParamsType == InputWindow::TYPE_WALLPAPER) {
                    mTempTouchState.addOrUpdateWindow(window, 0, BitSet32(0));
                    mTempTouchState.addOrUpdateWindow(window,
                }
                            InputTarget::FLAG_WINDOW_IS_OBSCURED, BitSet32(0));
            }
        }
                }
                }

    // If a touched window has been obscured at any point during the touch gesture, set
    // the appropriate flag so we remember it for the entire gesture.
    for (size_t i = 0; i < mTempTouchState.windows.size(); i++) {
        TouchedWindow& touchedWindow = mTempTouchState.windows.editItemAt(i);
        if ((touchedWindow.targetFlags & InputTarget::FLAG_WINDOW_IS_OBSCURED) == 0) {
            if (isWindowObscuredLocked(touchedWindow.window)) {
                touchedWindow.targetFlags |= InputTarget::FLAG_WINDOW_IS_OBSCURED;
            }
            }
        }
        }
    }
    }
@@ -1326,14 +1328,15 @@ bool InputDispatcher::checkInjectionPermission(const InputWindow* window,
    return true;
    return true;
}
}


bool InputDispatcher::isWindowObscuredLocked(const InputWindow* window) {
bool InputDispatcher::isWindowObscuredAtPointLocked(
        const InputWindow* window, int32_t x, int32_t y) const {
    size_t numWindows = mWindows.size();
    size_t numWindows = mWindows.size();
    for (size_t i = 0; i < numWindows; i++) {
    for (size_t i = 0; i < numWindows; i++) {
        const InputWindow* other = & mWindows.itemAt(i);
        const InputWindow* other = & mWindows.itemAt(i);
        if (other == window) {
        if (other == window) {
            break;
            break;
        }
        }
        if (other->visible && window->visibleFrameIntersects(other)) {
        if (other->visible && ! other->isTrustedOverlay() && other->frameContainsPoint(x, y)) {
            return true;
            return true;
        }
        }
    }
    }