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

Commit a1589108 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Move drag event to InputDispatcher (3/n)" into sc-dev

parents cb36a876 b89ccb0e
Loading
Loading
Loading
Loading
+17 −0
Original line number Diff line number Diff line
@@ -130,6 +130,23 @@ std::string PointerCaptureChangedEntry::getDescription() const {
                        pointerCaptureEnabled ? "true" : "false");
}

// --- DragEntry ---

// Drag notifications always go to apps, so set the flag POLICY_FLAG_PASS_TO_USER for all entries
DragEntry::DragEntry(int32_t id, nsecs_t eventTime, sp<IBinder> connectionToken, bool isExiting,
                     float x, float y)
      : EventEntry(id, Type::DRAG, eventTime, POLICY_FLAG_PASS_TO_USER),
        connectionToken(connectionToken),
        isExiting(isExiting),
        x(x),
        y(y) {}

DragEntry::~DragEntry() {}

std::string DragEntry::getDescription() const {
    return StringPrintf("DragEntry(isExiting=%s, x=%f, y=%f)", isExiting ? "true" : "false", x, y);
}

// --- KeyEntry ---

KeyEntry::KeyEntry(int32_t id, nsecs_t eventTime, int32_t deviceId, uint32_t source,
+13 −0
Original line number Diff line number Diff line
@@ -38,6 +38,7 @@ struct EventEntry {
        MOTION,
        SENSOR,
        POINTER_CAPTURE_CHANGED,
        DRAG,
    };

    int32_t id;
@@ -111,6 +112,18 @@ struct PointerCaptureChangedEntry : EventEntry {
    virtual ~PointerCaptureChangedEntry();
};

struct DragEntry : EventEntry {
    sp<IBinder> connectionToken;
    bool isExiting;
    float x, y;

    DragEntry(int32_t id, nsecs_t eventTime, sp<IBinder> connectionToken, bool isExiting, float x,
              float y);
    std::string getDescription() const override;

    ~DragEntry() override;
};

struct KeyEntry : EventEntry {
    int32_t deviceId;
    uint32_t source;
+117 −10
Original line number Diff line number Diff line
@@ -753,6 +753,14 @@ void InputDispatcher::dispatchOnceInnerLocked(nsecs_t* nextWakeupTime) {
            break;
        }

        case EventEntry::Type::DRAG: {
            std::shared_ptr<DragEntry> typedEntry =
                    std::static_pointer_cast<DragEntry>(mPendingEvent);
            dispatchDragLocked(currentTime, typedEntry);
            done = true;
            break;
        }

        case EventEntry::Type::KEY: {
            std::shared_ptr<KeyEntry> keyEntry = std::static_pointer_cast<KeyEntry>(mPendingEvent);
            if (isAppSwitchDue) {
@@ -921,7 +929,8 @@ bool InputDispatcher::enqueueInboundEventLocked(std::unique_ptr<EventEntry> newE
        case EventEntry::Type::CONFIGURATION_CHANGED:
        case EventEntry::Type::DEVICE_RESET:
        case EventEntry::Type::SENSOR:
        case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
        case EventEntry::Type::POINTER_CAPTURE_CHANGED:
        case EventEntry::Type::DRAG: {
            // nothing to do
            break;
        }
@@ -943,7 +952,8 @@ void InputDispatcher::addRecentEventLocked(std::shared_ptr<EventEntry> entry) {
sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t displayId, int32_t x,
                                                                 int32_t y, TouchState* touchState,
                                                                 bool addOutsideTargets,
                                                                 bool addPortalWindows) {
                                                                 bool addPortalWindows,
                                                                 bool ignoreDragWindow) {
    if ((addPortalWindows || addOutsideTargets) && touchState == nullptr) {
        LOG_ALWAYS_FATAL(
                "Must provide a valid touch state if adding portal windows or outside targets");
@@ -951,6 +961,9 @@ sp<InputWindowHandle> InputDispatcher::findTouchedWindowAtLocked(int32_t display
    // Traverse windows from front to back to find touched window.
    const std::vector<sp<InputWindowHandle>>& windowHandles = getWindowHandlesLocked(displayId);
    for (const sp<InputWindowHandle>& windowHandle : windowHandles) {
        if (ignoreDragWindow && haveSameToken(windowHandle, touchState->dragWindow)) {
            continue;
        }
        const InputWindowInfo* windowInfo = windowHandle->getInfo();
        if (windowInfo->displayId == displayId) {
            auto flags = windowInfo->flags;
@@ -1060,7 +1073,8 @@ void InputDispatcher::dropInboundEventLocked(const EventEntry& entry, DropReason
        case EventEntry::Type::SENSOR: {
            break;
        }
        case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
        case EventEntry::Type::POINTER_CAPTURE_CHANGED:
        case EventEntry::Type::DRAG: {
            break;
        }
        case EventEntry::Type::FOCUS:
@@ -1554,6 +1568,35 @@ bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime, std::shared_ptr<
    return true;
}

void InputDispatcher::enqueueDragEventLocked(const sp<InputWindowHandle>& windowHandle,
                                             bool isExiting, const MotionEntry& motionEntry) {
    // If the window needs enqueue a drag event, the pointerCount should be 1 and the action should
    // be AMOTION_EVENT_ACTION_MOVE, that could guarantee the first pointer is always valid.
    LOG_ALWAYS_FATAL_IF(motionEntry.pointerCount != 1);
    PointerCoords pointerCoords;
    pointerCoords.copyFrom(motionEntry.pointerCoords[0]);
    pointerCoords.transform(windowHandle->getInfo()->transform);

    std::unique_ptr<DragEntry> dragEntry =
            std::make_unique<DragEntry>(mIdGenerator.nextId(), motionEntry.eventTime,
                                        windowHandle->getToken(), isExiting, pointerCoords.getX(),
                                        pointerCoords.getY());

    enqueueInboundEventLocked(std::move(dragEntry));
}

void InputDispatcher::dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) {
    std::shared_ptr<InputChannel> channel = getInputChannelLocked(entry->connectionToken);
    if (channel == nullptr) {
        return; // Window has gone away
    }
    InputTarget target;
    target.inputChannel = channel;
    target.flags = InputTarget::FLAG_DISPATCH_AS_IS;
    entry->dispatchInProgress = true;
    dispatchEventLocked(currentTime, entry, {target});
}

void InputDispatcher::logOutboundMotionDetails(const char* prefix, const MotionEntry& entry) {
#if DEBUG_OUTBOUND_EVENT_DETAILS
    ALOGD("%seventTime=%" PRId64 ", deviceId=%d, source=0x%x, displayId=%" PRId32
@@ -1660,7 +1703,8 @@ int32_t InputDispatcher::getTargetDisplayId(const EventEntry& entry) {
        case EventEntry::Type::FOCUS:
        case EventEntry::Type::CONFIGURATION_CHANGED:
        case EventEntry::Type::DEVICE_RESET:
        case EventEntry::Type::SENSOR: {
        case EventEntry::Type::SENSOR:
        case EventEntry::Type::DRAG: {
            ALOGE("%s events do not have a target display", NamedEnum::string(entry.type).c_str());
            return ADISPLAY_ID_NONE;
        }
@@ -2017,6 +2061,8 @@ InputEventInjectionResult InputDispatcher::findTouchedWindowTargetsLocked(
            goto Failed;
        }

        addDragEventLocked(entry, tempTouchState);

        // Check whether touches should slip outside of the current foreground window.
        if (maskedAction == AMOTION_EVENT_ACTION_MOVE && entry.pointerCount == 1 &&
            tempTouchState.isSlippery()) {
@@ -2272,6 +2318,38 @@ Failed:
    return injectionResult;
}

void InputDispatcher::addDragEventLocked(const MotionEntry& entry, TouchState& state) {
    if (entry.pointerCount != 1 || !state.dragWindow) {
        return;
    }

    int32_t maskedAction = entry.action & AMOTION_EVENT_ACTION_MASK;
    int32_t x = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_X));
    int32_t y = static_cast<int32_t>(entry.pointerCoords[0].getAxisValue(AMOTION_EVENT_AXIS_Y));
    if (maskedAction == AMOTION_EVENT_ACTION_MOVE) {
        const sp<InputWindowHandle> hoverWindowHandle =
                findTouchedWindowAtLocked(entry.displayId, x, y, &state,
                                          false /*addOutsideTargets*/, false /*addPortalWindows*/,
                                          true /*ignoreDragWindow*/);
        // enqueue drag exit if needed.
        if (hoverWindowHandle != state.dragHoverWindowHandle &&
            !haveSameToken(hoverWindowHandle, state.dragHoverWindowHandle)) {
            if (state.dragHoverWindowHandle != nullptr) {
                enqueueDragEventLocked(state.dragHoverWindowHandle, true /*isExiting*/, entry);
            }
            state.dragHoverWindowHandle = hoverWindowHandle;
        }
        // enqueue drag location if needed.
        if (hoverWindowHandle != nullptr) {
            enqueueDragEventLocked(hoverWindowHandle, false /*isExiting*/, entry);
        }
    } else if (maskedAction == AMOTION_EVENT_ACTION_UP ||
               maskedAction == AMOTION_EVENT_ACTION_CANCEL) {
        state.dragWindow = nullptr;
        state.dragHoverWindowHandle = nullptr;
    }
}

void InputDispatcher::addWindowTargetLocked(const sp<InputWindowHandle>& windowHandle,
                                            int32_t targetFlags, BitSet32 pointerIds,
                                            std::vector<InputTarget>& inputTargets) {
@@ -2543,7 +2621,8 @@ std::string InputDispatcher::getApplicationWindowLabel(

void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
    if (eventEntry.type == EventEntry::Type::FOCUS ||
        eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED) {
        eventEntry.type == EventEntry::Type::POINTER_CAPTURE_CHANGED ||
        eventEntry.type == EventEntry::Type::DRAG) {
        // Focus or pointer capture changed events are passed to apps, but do not represent user
        // activity.
        return;
@@ -2585,7 +2664,8 @@ void InputDispatcher::pokeUserActivityLocked(const EventEntry& eventEntry) {
        case EventEntry::Type::CONFIGURATION_CHANGED:
        case EventEntry::Type::DEVICE_RESET:
        case EventEntry::Type::SENSOR:
        case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
        case EventEntry::Type::POINTER_CAPTURE_CHANGED:
        case EventEntry::Type::DRAG: {
            LOG_ALWAYS_FATAL("%s events are not user activity",
                             NamedEnum::string(eventEntry.type).c_str());
            break;
@@ -2799,7 +2879,8 @@ void InputDispatcher::enqueueDispatchEntryLocked(const sp<Connection>& connectio
            break;
        }
        case EventEntry::Type::FOCUS:
        case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
        case EventEntry::Type::POINTER_CAPTURE_CHANGED:
        case EventEntry::Type::DRAG: {
            break;
        }
        case EventEntry::Type::SENSOR: {
@@ -3022,6 +3103,15 @@ void InputDispatcher::startDispatchCycleLocked(nsecs_t currentTime,
                break;
            }

            case EventEntry::Type::DRAG: {
                const DragEntry& dragEntry = static_cast<const DragEntry&>(eventEntry);
                status = connection->inputPublisher.publishDragEvent(dispatchEntry->seq,
                                                                     dragEntry.id, dragEntry.x,
                                                                     dragEntry.y,
                                                                     dragEntry.isExiting);
                break;
            }

            case EventEntry::Type::CONFIGURATION_CHANGED:
            case EventEntry::Type::DEVICE_RESET:
            case EventEntry::Type::SENSOR: {
@@ -3319,7 +3409,8 @@ void InputDispatcher::synthesizeCancelationEventsForConnectionLocked(
                break;
            }
            case EventEntry::Type::FOCUS:
            case EventEntry::Type::POINTER_CAPTURE_CHANGED: {
            case EventEntry::Type::POINTER_CAPTURE_CHANGED:
            case EventEntry::Type::DRAG: {
                LOG_ALWAYS_FATAL("Canceling %s events is not supported",
                                 NamedEnum::string(cancelationEventEntry->type).c_str());
                break;
@@ -3384,7 +3475,8 @@ void InputDispatcher::synthesizePointerDownEventsForConnectionLocked(
            case EventEntry::Type::CONFIGURATION_CHANGED:
            case EventEntry::Type::DEVICE_RESET:
            case EventEntry::Type::POINTER_CAPTURE_CHANGED:
            case EventEntry::Type::SENSOR: {
            case EventEntry::Type::SENSOR:
            case EventEntry::Type::DRAG: {
                LOG_ALWAYS_FATAL("%s event should not be found inside Connections's queue",
                                 NamedEnum::string(downEventEntry->type).c_str());
                break;
@@ -4348,6 +4440,15 @@ void InputDispatcher::setInputWindowsLocked(
                ++i;
            }
        }

        // If drag window is gone, it would receive a cancel event and broadcast the DRAG_END. we
        // could just clear the state here.
        if (state.dragWindow &&
            std::find(windowHandles.begin(), windowHandles.end(), state.dragWindow) ==
                    windowHandles.end()) {
            state.dragWindow = nullptr;
            state.dragHoverWindowHandle = nullptr;
        }
    }

    // Release information for windows that are no longer present.
@@ -4538,7 +4639,8 @@ void InputDispatcher::setBlockUntrustedTouchesMode(BlockUntrustedTouchesMode mod
    mBlockUntrustedTouchesMode = mode;
}

bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken) {
bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
                                         bool isDragDrop) {
    if (fromToken == toToken) {
        if (DEBUG_FOCUS) {
            ALOGD("Trivial transfer to same window.");
@@ -4582,6 +4684,11 @@ bool InputDispatcher::transferTouchFocus(const sp<IBinder>& fromToken, const sp<
                             InputTarget::FLAG_DISPATCH_AS_IS);
                    state.addOrUpdateWindow(toWindowHandle, newTargetFlags, pointerIds);

                    // Store the dragging window.
                    if (isDragDrop) {
                        state.dragWindow = toWindowHandle;
                    }

                    found = true;
                    goto Found;
                }
+11 −4
Original line number Diff line number Diff line
@@ -120,8 +120,8 @@ public:
    virtual void setMaximumObscuringOpacityForTouch(float opacity) override;
    virtual void setBlockUntrustedTouchesMode(android::os::BlockUntrustedTouchesMode mode) override;

    virtual bool transferTouchFocus(const sp<IBinder>& fromToken,
                                    const sp<IBinder>& toToken) override;
    virtual bool transferTouchFocus(const sp<IBinder>& fromToken, const sp<IBinder>& toToken,
                                    bool isDragDrop = false) override;

    virtual base::Result<std::unique_ptr<InputChannel>> createInputChannel(
            const std::string& name) override;
@@ -185,6 +185,9 @@ private:
    // Enqueues a focus event.
    void enqueueFocusEventLocked(const sp<IBinder>& windowToken, bool hasFocus,
                                 const std::string& reason) REQUIRES(mLock);
    // Enqueues a drag event.
    void enqueueDragEventLocked(const sp<InputWindowHandle>& windowToken, bool isExiting,
                                const MotionEntry& motionEntry) REQUIRES(mLock);

    // Adds an event to a queue of recent events for debugging purposes.
    void addRecentEventLocked(std::shared_ptr<EventEntry> entry) REQUIRES(mLock);
@@ -204,7 +207,8 @@ private:
    sp<InputWindowHandle> findTouchedWindowAtLocked(int32_t displayId, int32_t x, int32_t y,
                                                    TouchState* touchState,
                                                    bool addOutsideTargets = false,
                                                    bool addPortalWindows = false) REQUIRES(mLock);
                                                    bool addPortalWindows = false,
                                                    bool ignoreDragWindow = false) REQUIRES(mLock);

    // All registered connections mapped by channel file descriptor.
    std::unordered_map<int, sp<Connection>> mConnectionsByFd GUARDED_BY(mLock);
@@ -387,6 +391,7 @@ private:
                             const std::vector<InputTarget>& inputTargets) REQUIRES(mLock);
    void dispatchSensorLocked(nsecs_t currentTime, std::shared_ptr<SensorEntry> entry,
                              DropReason* dropReason, nsecs_t* nextWakeupTime) REQUIRES(mLock);
    void dispatchDragLocked(nsecs_t currentTime, std::shared_ptr<DragEntry> entry) REQUIRES(mLock);
    void logOutboundKeyDetails(const char* prefix, const KeyEntry& entry);
    void logOutboundMotionDetails(const char* prefix, const MotionEntry& entry);

@@ -489,10 +494,12 @@ private:
                                   std::vector<InputTarget>& inputTargets) REQUIRES(mLock);
    void addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets, int32_t displayId,
                                          float xOffset = 0, float yOffset = 0) REQUIRES(mLock);

    void pokeUserActivityLocked(const EventEntry& eventEntry) REQUIRES(mLock);
    bool checkInjectionPermission(const sp<InputWindowHandle>& windowHandle,
                                  const InjectionState* injectionState);
    // Enqueue a drag event if needed, and update the touch state.
    // Uses findTouchedWindowTargetsLocked to make the decision
    void addDragEventLocked(const MotionEntry& entry, TouchState& state) REQUIRES(mLock);

    struct TouchOcclusionInfo {
        bool hasBlockingOcclusion;
+2 −0
Original line number Diff line number Diff line
@@ -49,6 +49,8 @@ void TouchState::copyFrom(const TouchState& other) {
    windows = other.windows;
    portalWindows = other.portalWindows;
    gestureMonitors = other.gestureMonitors;
    dragHoverWindowHandle = other.dragHoverWindowHandle;
    dragWindow = other.dragWindow;
}

void TouchState::addOrUpdateWindow(const sp<InputWindowHandle>& windowHandle, int32_t targetFlags,
Loading