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

Commit 774d9375 authored by Arpit Singh's avatar Arpit Singh
Browse files

Revert "[9/n Dispatcher refactor] Move computeTouchOcclusionInfo..."

Revert submission 31063667

Reason for revert: b/389024840

Reverted changes: /q/submissionid:31063667

Change-Id: Id951c02a894911a018743f0eef9476b0a5a57bd2
parent d20a62ad
Loading
Loading
Loading
Loading
+26 −27
Original line number Diff line number Diff line
@@ -918,21 +918,6 @@ InputTarget createInputTarget(const std::shared_ptr<Connection>& connection,
    return inputTarget;
}

std::string dumpWindowForTouchOcclusion(const WindowInfo& info, bool isTouchedWindow) {
    return StringPrintf(INDENT2 "* %spackage=%s/%s, id=%" PRId32 ", mode=%s, alpha=%.2f, "
                                "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
                                "], touchableRegion=%s, window={%s}, inputConfig={%s}, "
                                "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
                        isTouchedWindow ? "[TOUCHED] " : "", info.packageName.c_str(),
                        info.ownerUid.toString().c_str(), info.id,
                        toString(info.touchOcclusionMode).c_str(), info.alpha, info.frame.left,
                        info.frame.top, info.frame.right, info.frame.bottom,
                        dumpRegion(info.touchableRegion).c_str(), info.name.c_str(),
                        info.inputConfig.string().c_str(), toString(info.token != nullptr),
                        info.applicationInfo.name.c_str(),
                        binderToString(info.applicationInfo.token).c_str());
}

} // namespace

// --- InputDispatcher ---
@@ -948,13 +933,13 @@ InputDispatcher::InputDispatcher(InputDispatcherPolicyInterface& policy,
        mLastDropReason(DropReason::NOT_DROPPED),
        mIdGenerator(IdGenerator::Source::INPUT_DISPATCHER),
        mMinTimeBetweenUserActivityPokes(DEFAULT_USER_ACTIVITY_POKE_INTERVAL),
        mConnectionManager(mLooper),
        mNextUnblockedEvent(nullptr),
        mMonitorDispatchingTimeout(DEFAULT_INPUT_DISPATCHING_TIMEOUT),
        mDispatchEnabled(false),
        mDispatchFrozen(false),
        mInputFilterEnabled(false),
        mMaximumObscuringOpacityForTouch(1.0f),
        mConnectionManager(mLooper),
        mFocusedDisplayId(ui::LogicalDisplayId::DEFAULT),
        mWindowTokenWithPointerCapture(nullptr),
        mAwaitedApplicationDisplayId(ui::LogicalDisplayId::INVALID),
@@ -3108,12 +3093,12 @@ static bool canBeObscuredBy(const sp<WindowInfoHandle>& windowHandle,
 *
 * If neither of those is true, then it means the touch can be allowed.
 */
InputDispatcher::DispatcherWindowInfo::TouchOcclusionInfo
InputDispatcher::DispatcherWindowInfo::computeTouchOcclusionInfo(
InputDispatcher::TouchOcclusionInfo InputDispatcher::computeTouchOcclusionInfoLocked(
        const sp<WindowInfoHandle>& windowHandle, float x, float y) const {
    const WindowInfo* windowInfo = windowHandle->getInfo();
    ui::LogicalDisplayId displayId = windowInfo->displayId;
    const std::vector<sp<WindowInfoHandle>>& windowHandles = getWindowHandlesForDisplay(displayId);
    const std::vector<sp<WindowInfoHandle>>& windowHandles =
            mWindowInfos.getWindowHandlesForDisplay(displayId);
    TouchOcclusionInfo info;
    info.hasBlockingOcclusion = false;
    info.obscuringOpacity = 0;
@@ -3125,11 +3110,12 @@ InputDispatcher::DispatcherWindowInfo::computeTouchOcclusionInfo(
        }
        const WindowInfo* otherInfo = otherHandle->getInfo();
        if (canBeObscuredBy(windowHandle, otherHandle) &&
            windowOccludesTouchAt(*otherInfo, displayId, x, y, getDisplayTransform(displayId)) &&
            windowOccludesTouchAt(*otherInfo, displayId, x, y,
                                  mWindowInfos.getDisplayTransform(displayId)) &&
            !haveSameApplicationToken(windowInfo, otherInfo)) {
            if (DEBUG_TOUCH_OCCLUSION) {
                info.debugInfo.push_back(
                        dumpWindowForTouchOcclusion(*otherInfo, /*isTouchedWindow=*/false));
                        dumpWindowForTouchOcclusion(otherInfo, /*isTouchedWindow=*/false));
            }
            // canBeObscuredBy() has returned true above, which means this window is untrusted, so
            // we perform the checks below to see if the touch can be propagated or not based on the
@@ -3157,14 +3143,28 @@ InputDispatcher::DispatcherWindowInfo::computeTouchOcclusionInfo(
        }
    }
    if (DEBUG_TOUCH_OCCLUSION) {
        info.debugInfo.push_back(
                dumpWindowForTouchOcclusion(*windowInfo, /*isTouchedWindow=*/true));
        info.debugInfo.push_back(dumpWindowForTouchOcclusion(windowInfo, /*isTouchedWindow=*/true));
    }
    return info;
}

bool InputDispatcher::isTouchTrustedLocked(
        const DispatcherWindowInfo::TouchOcclusionInfo& occlusionInfo) const {
std::string InputDispatcher::dumpWindowForTouchOcclusion(const WindowInfo* info,
                                                         bool isTouchedWindow) const {
    return StringPrintf(INDENT2 "* %spackage=%s/%s, id=%" PRId32 ", mode=%s, alpha=%.2f, "
                                "frame=[%" PRId32 ",%" PRId32 "][%" PRId32 ",%" PRId32
                                "], touchableRegion=%s, window={%s}, inputConfig={%s}, "
                                "hasToken=%s, applicationInfo.name=%s, applicationInfo.token=%s\n",
                        isTouchedWindow ? "[TOUCHED] " : "", info->packageName.c_str(),
                        info->ownerUid.toString().c_str(), info->id,
                        toString(info->touchOcclusionMode).c_str(), info->alpha, info->frame.left,
                        info->frame.top, info->frame.right, info->frame.bottom,
                        dumpRegion(info->touchableRegion).c_str(), info->name.c_str(),
                        info->inputConfig.string().c_str(), toString(info->token != nullptr),
                        info->applicationInfo.name.c_str(),
                        binderToString(info->applicationInfo.token).c_str());
}

bool InputDispatcher::isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const {
    if (occlusionInfo.hasBlockingOcclusion) {
        ALOGW("Untrusted touch due to occlusion by %s/%s", occlusionInfo.obscuringPackage.c_str(),
              occlusionInfo.obscuringUid.toString().c_str());
@@ -5306,8 +5306,7 @@ bool InputDispatcher::canWindowReceiveMotionLocked(const sp<WindowInfoHandle>& w

    // Drop events that can't be trusted due to occlusion
    const auto [x, y] = resolveTouchedPosition(motionEntry);
    DispatcherWindowInfo::TouchOcclusionInfo occlusionInfo =
            mWindowInfos.computeTouchOcclusionInfo(window, x, y);
    TouchOcclusionInfo occlusionInfo = computeTouchOcclusionInfoLocked(window, x, y);
    if (!isTouchTrustedLocked(occlusionInfo)) {
        if (DEBUG_TOUCH_OCCLUSION) {
            ALOGD("Stack of obscuring windows during untrusted touch (%.1f, %.1f):", x, y);
+115 −115
Original line number Diff line number Diff line
@@ -224,120 +224,6 @@ private:
    /** Stores the latest user-activity poke event times per user activity types. */
    std::array<nsecs_t, USER_ACTIVITY_EVENT_LAST + 1> mLastUserActivityTimes GUARDED_BY(mLock);

    template <typename T>
    struct StrongPointerHash {
        std::size_t operator()(const sp<T>& b) const { return std::hash<T*>{}(b.get()); }
    };

    class ConnectionManager {
    public:
        ConnectionManager(sp<Looper> lopper);
        ~ConnectionManager();

        std::shared_ptr<Connection> getConnection(const sp<IBinder>& inputConnectionToken) const;
        std::string getConnectionName(const sp<IBinder>& connectionToken) const;

        // Find a monitor pid by the provided token.
        std::optional<gui::Pid> findMonitorPidByToken(const sp<IBinder>& token) const;
        void forEachGlobalMonitorConnection(
                std::function<void(const std::shared_ptr<Connection>&)> f) const;
        void forEachGlobalMonitorConnection(
                ui::LogicalDisplayId displayId,
                std::function<void(const std::shared_ptr<Connection>&)> f) const;

        void createGlobalInputMonitor(ui::LogicalDisplayId displayId,
                                      std::unique_ptr<InputChannel>&& inputChannel,
                                      const IdGenerator& idGenerator, gui::Pid pid);

        status_t removeInputChannel(const std::shared_ptr<Connection>& connection);
        void removeConnection(const std::shared_ptr<Connection>& connection);

        void createConnection(std::unique_ptr<InputChannel>&& inputChannel,
                              const IdGenerator& idGenerator);

        std::string dump(nsecs_t currentTime) const;

    private:
        sp<Looper> mLooper;

        // All registered connections mapped by input channel token.
        std::unordered_map<sp<IBinder>, std::shared_ptr<Connection>, StrongPointerHash<IBinder>>
                mConnectionsByToken;

        // Input channels that will receive a copy of all input events sent to the provided display.
        std::unordered_map<ui::LogicalDisplayId, std::vector<Monitor>> mGlobalMonitorsByDisplay;

        void removeMonitorChannel(const sp<IBinder>& connectionToken);
    };

    ConnectionManager mConnectionManager GUARDED_BY(mLock);

    class DispatcherWindowInfo {
    public:
        struct TouchOcclusionInfo {
            bool hasBlockingOcclusion;
            float obscuringOpacity;
            std::string obscuringPackage;
            gui::Uid obscuringUid = gui::Uid::INVALID;
            std::vector<std::string> debugInfo;
        };

        void setWindowHandlesForDisplay(
                ui::LogicalDisplayId displayId,
                std::vector<sp<android::gui::WindowInfoHandle>>&& windowHandles);

        void setDisplayInfos(const std::vector<android::gui::DisplayInfo>& displayInfos);

        void removeDisplay(ui::LogicalDisplayId displayId);

        // Get a reference to window handles by display, return an empty vector if not found.
        const std::vector<sp<android::gui::WindowInfoHandle>>& getWindowHandlesForDisplay(
                ui::LogicalDisplayId displayId) const;

        void forEachWindowHandle(
                std::function<void(const sp<android::gui::WindowInfoHandle>&)> f) const;

        void forEachDisplayId(std::function<void(ui::LogicalDisplayId)> f) const;

        // Get the transform for display, returns Identity-transform if display is missing.
        ui::Transform getDisplayTransform(ui::LogicalDisplayId displayId) const;

        // Get the raw transform to use for motion events going to the given window.
        ui::Transform getRawTransform(const android::gui::WindowInfo&) const;

        // Lookup for WindowInfoHandle from token and optionally a display-id. In cases where
        // display-id is not provided lookup is done for all displays.
        sp<android::gui::WindowInfoHandle> findWindowHandle(
                const sp<IBinder>& windowHandleToken,
                std::optional<ui::LogicalDisplayId> displayId = {}) const;

        bool isWindowPresent(const sp<android::gui::WindowInfoHandle>& windowHandle) const;

        // Returns the touched window at the given location, excluding the ignoreWindow if provided.
        sp<android::gui::WindowInfoHandle> findTouchedWindowAt(
                ui::LogicalDisplayId displayId, float x, float y, bool isStylus = false,
                const sp<android::gui::WindowInfoHandle> ignoreWindow = nullptr) const;

        std::vector<sp<android::gui::WindowInfoHandle>> findTouchedSpyWindowsAt(
                ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId,
                const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay)
                const;

        TouchOcclusionInfo computeTouchOcclusionInfo(
                const sp<android::gui::WindowInfoHandle>& windowHandle, float x, float y) const;

        std::string dumpDisplayAndWindowInfo() const;

    private:
        std::unordered_map<ui::LogicalDisplayId /*displayId*/,
                           std::vector<sp<android::gui::WindowInfoHandle>>>
                mWindowHandlesByDisplay;
        std::unordered_map<ui::LogicalDisplayId /*displayId*/, android::gui::DisplayInfo>
                mDisplayInfos;
    };

    DispatcherWindowInfo mWindowInfos GUARDED_BY(mLock);

    // With each iteration, InputDispatcher nominally processes one queued event,
    // a timeout, or a response from an input consumer.
    // This method should only be called on the input dispatcher's own thread.
@@ -376,6 +262,11 @@ private:

    status_t pilferPointersLocked(const sp<IBinder>& token) REQUIRES(mLock);

    template <typename T>
    struct StrongPointerHash {
        std::size_t operator()(const sp<T>& b) const { return std::hash<T*>{}(b.get()); }
    };

    const HmacKeyManager mHmacKeyManager;
    const std::array<uint8_t, 32> getSignature(const MotionEntry& motionEntry,
                                               const DispatchEntry& dispatchEntry) const;
@@ -453,6 +344,103 @@ private:
    };
    sp<gui::WindowInfosListener> mWindowInfoListener;

    class DispatcherWindowInfo {
    public:
        void setWindowHandlesForDisplay(
                ui::LogicalDisplayId displayId,
                std::vector<sp<android::gui::WindowInfoHandle>>&& windowHandles);

        void setDisplayInfos(const std::vector<android::gui::DisplayInfo>& displayInfos);

        void removeDisplay(ui::LogicalDisplayId displayId);

        // Get a reference to window handles by display, return an empty vector if not found.
        const std::vector<sp<android::gui::WindowInfoHandle>>& getWindowHandlesForDisplay(
                ui::LogicalDisplayId displayId) const;

        void forEachWindowHandle(
                std::function<void(const sp<android::gui::WindowInfoHandle>&)> f) const;

        void forEachDisplayId(std::function<void(ui::LogicalDisplayId)> f) const;

        // Get the transform for display, returns Identity-transform if display is missing.
        ui::Transform getDisplayTransform(ui::LogicalDisplayId displayId) const;

        // Get the raw transform to use for motion events going to the given window.
        ui::Transform getRawTransform(const android::gui::WindowInfo&) const;

        // Lookup for WindowInfoHandle from token and optionally a display-id. In cases where
        // display-id is not provided lookup is done for all displays.
        sp<android::gui::WindowInfoHandle> findWindowHandle(
                const sp<IBinder>& windowHandleToken,
                std::optional<ui::LogicalDisplayId> displayId = {}) const;

        bool isWindowPresent(const sp<android::gui::WindowInfoHandle>& windowHandle) const;

        // Returns the touched window at the given location, excluding the ignoreWindow if provided.
        sp<android::gui::WindowInfoHandle> findTouchedWindowAt(
                ui::LogicalDisplayId displayId, float x, float y, bool isStylus = false,
                const sp<android::gui::WindowInfoHandle> ignoreWindow = nullptr) const;

        std::vector<sp<android::gui::WindowInfoHandle>> findTouchedSpyWindowsAt(
                ui::LogicalDisplayId displayId, float x, float y, bool isStylus, DeviceId deviceId,
                const std::unordered_map<ui::LogicalDisplayId, TouchState>& touchStatesByDisplay)
                const;

        std::string dumpDisplayAndWindowInfo() const;

    private:
        std::unordered_map<ui::LogicalDisplayId /*displayId*/,
                           std::vector<sp<android::gui::WindowInfoHandle>>>
                mWindowHandlesByDisplay;
        std::unordered_map<ui::LogicalDisplayId /*displayId*/, android::gui::DisplayInfo>
                mDisplayInfos;
    };

    DispatcherWindowInfo mWindowInfos GUARDED_BY(mLock);

    class ConnectionManager {
    public:
        ConnectionManager(sp<Looper> lopper);
        ~ConnectionManager();

        std::shared_ptr<Connection> getConnection(const sp<IBinder>& inputConnectionToken) const;

        // Find a monitor pid by the provided token.
        std::optional<gui::Pid> findMonitorPidByToken(const sp<IBinder>& token) const;
        void forEachGlobalMonitorConnection(
                std::function<void(const std::shared_ptr<Connection>&)> f) const;
        void forEachGlobalMonitorConnection(
                ui::LogicalDisplayId displayId,
                std::function<void(const std::shared_ptr<Connection>&)> f) const;

        void createGlobalInputMonitor(ui::LogicalDisplayId displayId,
                                      std::unique_ptr<InputChannel>&& inputChannel,
                                      const IdGenerator& idGenerator, gui::Pid pid);

        status_t removeInputChannel(const std::shared_ptr<Connection>& connection);
        void removeConnection(const std::shared_ptr<Connection>& connection);

        void createConnection(std::unique_ptr<InputChannel>&& inputChannel,
                              const IdGenerator& idGenerator);

        std::string dump(nsecs_t currentTime) const;

    private:
        sp<Looper> mLooper;

        // All registered connections mapped by input channel token.
        std::unordered_map<sp<IBinder>, std::shared_ptr<Connection>, StrongPointerHash<IBinder>>
                mConnectionsByToken;

        // Input channels that will receive a copy of all input events sent to the provided display.
        std::unordered_map<ui::LogicalDisplayId, std::vector<Monitor>> mGlobalMonitorsByDisplay;

        void removeMonitorChannel(const sp<IBinder>& connectionToken);
    };

    ConnectionManager mConnectionManager GUARDED_BY(mLock);

    void setInputWindowsLocked(
            const std::vector<sp<android::gui::WindowInfoHandle>>& inputWindowHandles,
            ui::LogicalDisplayId displayId) REQUIRES(mLock);
@@ -638,12 +626,24 @@ private:
    void addDragEventLocked(const MotionEntry& entry) REQUIRES(mLock);
    void finishDragAndDrop(ui::LogicalDisplayId displayId, float x, float y) REQUIRES(mLock);

    bool isTouchTrustedLocked(const DispatcherWindowInfo::TouchOcclusionInfo& occlusionInfo) const
    struct TouchOcclusionInfo {
        bool hasBlockingOcclusion;
        float obscuringOpacity;
        std::string obscuringPackage;
        gui::Uid obscuringUid = gui::Uid::INVALID;
        std::vector<std::string> debugInfo;
    };

    TouchOcclusionInfo computeTouchOcclusionInfoLocked(
            const sp<android::gui::WindowInfoHandle>& windowHandle, float x, float y) const
            REQUIRES(mLock);
    bool isTouchTrustedLocked(const TouchOcclusionInfo& occlusionInfo) const REQUIRES(mLock);
    bool isWindowObscuredAtPointLocked(const sp<android::gui::WindowInfoHandle>& windowHandle,
                                       float x, float y) const REQUIRES(mLock);
    bool isWindowObscuredLocked(const sp<android::gui::WindowInfoHandle>& windowHandle) const
            REQUIRES(mLock);
    std::string dumpWindowForTouchOcclusion(const android::gui::WindowInfo* info,
                                            bool isTouchWindow) const;
    std::string getApplicationWindowLabel(const InputApplicationHandle* applicationHandle,
                                          const sp<android::gui::WindowInfoHandle>& windowHandle);