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

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

Merge changes from topic "global-monitor-to-focus-monitor" into main

* changes:
  InputDispatcher: Add and implement InputConfig::DO_NOT_PILFER
  InputDispatcher: Convert global monitors to focus input monitors
parents bd2dcf34 20c75502
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -180,6 +180,8 @@ struct WindowInfo : public Parcelable {
                static_cast<uint32_t>(os::InputConfig::SENSITIVE_FOR_PRIVACY),
        DISPLAY_TOPOLOGY_AWARE =
                static_cast<uint32_t>(os::InputConfig::DISPLAY_TOPOLOGY_AWARE),
        DO_NOT_PILFER =
                static_cast<uint32_t>(os::InputConfig::DO_NOT_PILFER),
        // clang-format on
    };

+9 −0
Original line number Diff line number Diff line
@@ -173,4 +173,13 @@ enum InputConfig {
     * remain unchanged and coordinate space will extend beyond the logical display space.
     */
     DISPLAY_TOPOLOGY_AWARE       = 1 << 19,

    /**
     * InputConfig used to indicate that any pointer streams targeting this window should not be
     * canceled as part of a pilferPointers request.
     *
     * This is only meant to be used by system components that need to be perpetually be aware of
     * all input streams, such as the PointerLocationView used for debugging.
     */
     DO_NOT_PILFER                = 1 << 20,
}
+75 −62
Original line number Diff line number Diff line
@@ -412,8 +412,8 @@ std::unique_ptr<DispatchEntry> createDispatchEntry(const IdGenerator& idGenerato
    const sp<WindowInfoHandle> win = inputTarget.windowHandle;
    const std::optional<int32_t> windowId =
            win ? std::make_optional(win->getInfo()->id) : std::nullopt;
    // Assume the only targets that are not associated with a window are global monitors, and use
    // the system UID for global monitors for tracing purposes.
    // Assume the only targets that are not associated with a window are focus input monitors, and
    // use the system UID for monitors for tracing purposes.
    const gui::Uid uid = win ? win->getInfo()->ownerUid : gui::Uid(AID_SYSTEM);

    if (inputTarget.useDefaultPointerTransform() && !zeroCoords) {
@@ -1935,7 +1935,7 @@ bool InputDispatcher::dispatchKeyLocked(nsecs_t currentTime, std::shared_ptr<con
                          InputTarget::Flags::FOREGROUND, getDownTime(*entry), inputTargets);

    // Add monitor channels from event's or focused display.
    addGlobalMonitoringTargetsLocked(inputTargets, displayId);
    addFocusInputMonitoringTargetsLocked(inputTargets, displayId);

    if (mTracer) {
        ensureEventTraced(*entry);
@@ -2145,8 +2145,10 @@ bool InputDispatcher::dispatchMotionLocked(nsecs_t currentTime,
        return true;
    }

    if (!isPointerEvent) {
        // Add monitor channels from event's or focused display.
    addGlobalMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
        addFocusInputMonitoringTargetsLocked(inputTargets, getTargetDisplayId(*entry));
    }

    if (mTracer) {
        ensureEventTraced(*entry);
@@ -3042,30 +3044,28 @@ void InputDispatcher::DispatcherTouchState::addPointerWindowTarget(
    }
}

void InputDispatcher::addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
void InputDispatcher::addFocusInputMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
                                                           ui::LogicalDisplayId displayId) {
    mConnectionManager
            .forEachGlobalMonitorConnection(displayId,
            .forEachMonitorConnection(displayId,
                                      [&](const std::shared_ptr<Connection>& connection) {
                                          if (!connection->responsive) {
                                                    ALOGW("Ignoring unrsponsive monitor: %s",
                                                          connection->getInputChannelName()
                                                                  .c_str());
                                              ALOGW("Ignoring unresponsive monitor: %s",
                                                    connection->getInputChannelName().c_str());
                                              return;
                                          }

                                          InputTarget target{connection};
                                          // target.firstDownTimeInTarget is not set for
                                                // global monitors. It is only required in split
                                                // touch and global monitoring works as intended
                                          // monitors. It is only required in split
                                          // touch. Focus event monitoring works as intended
                                          // even without setting firstDownTimeInTarget. Since
                                                // global monitors don't have windows, use the
                                          // monitors don't have windows, use the
                                          // display transform as the raw transform.
                                          base::ScopedLockAssertion assumeLocked(mLock);
                                          target.rawTransform =
                                                  mWindowInfos.getDisplayTransform(displayId);
                                                target.setDefaultPointerTransform(
                                                        target.rawTransform);
                                          target.setDefaultPointerTransform(target.rawTransform);
                                          inputTargets.push_back(target);
                                      });
}
@@ -4112,11 +4112,9 @@ void InputDispatcher::synthesizeCancelationEventsForAllConnectionsLocked(

void InputDispatcher::synthesizeCancelationEventsForMonitorsLocked(
        const CancelationOptions& options) {
    mConnectionManager.forEachGlobalMonitorConnection(
            [&](const std::shared_ptr<Connection>& connection) {
    mConnectionManager.forEachMonitorConnection([&](const std::shared_ptr<Connection>& connection) {
        base::ScopedLockAssertion assumeLocked(mLock);
                synthesizeCancelationEventsForConnectionLocked(connection, options,
                                                               /*window=*/nullptr);
        synthesizeCancelationEventsForConnectionLocked(connection, options, /*window=*/nullptr);
    });
}

@@ -5520,6 +5518,13 @@ void InputDispatcher::setInputWindowsLocked(
                                            WindowInfo::InputConfig::TRUSTED_OVERLAY),
                            "%s has feature INTERCEPTS_STYLUS, but is not a trusted overlay.",
                            window->getName().c_str());

        // Ensure all do-not-pilfer requests come from trusted overlays
        LOG_ALWAYS_FATAL_IF(info.inputConfig.test(WindowInfo::InputConfig::DO_NOT_PILFER) &&
                                    !info.inputConfig.test(
                                            WindowInfo::InputConfig::TRUSTED_OVERLAY),
                            "%s has feature DO_NOT_PILFER, but is not a trusted overlay.",
                            window->getName().c_str());
    }

    // Copy old handles for release if they are no longer present.
@@ -6253,7 +6258,7 @@ Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputChannel(const
    return clientChannel;
}

Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
Result<std::unique_ptr<InputChannel>> InputDispatcher::createFocusInputMonitor(
        ui::LogicalDisplayId displayId, const std::string& name, gui::Pid pid) {
    std::unique_ptr<InputChannel> serverChannel;
    std::unique_ptr<InputChannel> clientChannel;
@@ -6266,15 +6271,15 @@ Result<std::unique_ptr<InputChannel>> InputDispatcher::createInputMonitor(
        std::scoped_lock _l(mLock);

        if (displayId < ui::LogicalDisplayId::DEFAULT) {
            return base::Error(BAD_VALUE) << "Attempted to create input monitor with name " << name
                                          << " without a specified display.";
            return base::Error(BAD_VALUE) << "Attempted to create focus input monitor with name "
                                          << name << " without a specified display.";
        }

        const sp<IBinder>& token = serverChannel->getConnectionToken();
        std::function<int(int events)> callback = std::bind(&InputDispatcher::handleReceiveCallback,
                                                            this, std::placeholders::_1, token);

        mConnectionManager.createGlobalInputMonitor(displayId, std::move(serverChannel),
        mConnectionManager.createFocusInputMonitor(displayId, std::move(serverChannel),
                                                   mIdGenerator, pid, callback);
    }

@@ -6317,14 +6322,15 @@ status_t InputDispatcher::removeInputChannelLocked(const std::shared_ptr<Connect
}

void InputDispatcher::ConnectionManager::removeMonitorChannel(const sp<IBinder>& connectionToken) {
    for (auto it = mGlobalMonitorsByDisplay.begin(); it != mGlobalMonitorsByDisplay.end();) {
    for (auto it = mFocusInputMonitorsByDisplay.begin();
         it != mFocusInputMonitorsByDisplay.end();) {
        auto& [displayId, monitors] = *it;
        std::erase_if(monitors, [connectionToken](const Monitor& monitor) {
            return monitor.connection->getToken() == connectionToken;
        });

        if (monitors.empty()) {
            it = mGlobalMonitorsByDisplay.erase(it);
            it = mFocusInputMonitorsByDisplay.erase(it);
        } else {
            ++it;
        }
@@ -6391,14 +6397,21 @@ InputDispatcher::DispatcherTouchState::pilferPointers(const sp<IBinder>& token,
        std::bitset<MAX_POINTER_ID + 1> pointerIds = getPointerIds(pointers);
        std::string canceledWindows;
        for (const TouchedWindow& w : state.windows) {
            if (w.windowHandle->getToken() != token) {
            if (w.windowHandle->getToken() == token) {
                // Skip cancelling from pilfering window.
                continue;
            }
            if (w.windowHandle->getInfo()->inputConfig.test(
                        WindowInfo::InputConfig::DO_NOT_PILFER)) {
                // Skip cancelling from window with DO_NOT_PILFER flag.
                continue;
            }
            cancellations.emplace_back(w.windowHandle,
                                           CancelationOptions::Mode::CANCEL_POINTER_EVENTS,
                                           deviceId, displayId, pointerIds);
                                       CancelationOptions::Mode::CANCEL_POINTER_EVENTS, deviceId,
                                       displayId, pointerIds);
            canceledWindows += canceledWindows.empty() ? "[" : ", ";
            canceledWindows += w.windowHandle->getName();
        }
        }
        canceledWindows += canceledWindows.empty() ? "[]" : "]";
        LOG(INFO) << "Channel " << requestingConnection.getInputChannelName()
                  << " is stealing input gesture for device " << deviceId << " from "
@@ -6408,7 +6421,7 @@ InputDispatcher::DispatcherTouchState::pilferPointers(const sp<IBinder>& token,
        // This only blocks relevant pointers to be sent to other windows
        window.addPilferingPointers(deviceId, pointerIds);

        state.cancelPointersForWindowsExcept(deviceId, pointerIds, token);
        state.cancelPointersForPilferingRequest(deviceId, pointerIds, token);
    }
    return cancellations;
}
@@ -6466,7 +6479,7 @@ void InputDispatcher::setDisplayEligibilityForPointerCapture(ui::LogicalDisplayI

std::optional<gui::Pid> InputDispatcher::ConnectionManager::findMonitorPidByToken(
        const sp<IBinder>& token) const {
    for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
    for (const auto& [_, monitors] : mFocusInputMonitorsByDisplay) {
        for (const Monitor& monitor : monitors) {
            if (monitor.connection->getToken() == token) {
                return monitor.pid;
@@ -7371,27 +7384,27 @@ InputDispatcher::ConnectionManager::~ConnectionManager() {
    }
}

void InputDispatcher::ConnectionManager::forEachGlobalMonitorConnection(
void InputDispatcher::ConnectionManager::forEachMonitorConnection(
        std::function<void(const std::shared_ptr<Connection>&)> f) const {
    for (const auto& [_, monitors] : mGlobalMonitorsByDisplay) {
    for (const auto& [_, monitors] : mFocusInputMonitorsByDisplay) {
        for (const Monitor& monitor : monitors) {
            f(monitor.connection);
        }
    }
}

void InputDispatcher::ConnectionManager::forEachGlobalMonitorConnection(
void InputDispatcher::ConnectionManager::forEachMonitorConnection(
        ui::LogicalDisplayId displayId,
        std::function<void(const std::shared_ptr<Connection>&)> f) const {
    auto monitorsIt = mGlobalMonitorsByDisplay.find(displayId);
    if (monitorsIt == mGlobalMonitorsByDisplay.end()) return;
    auto monitorsIt = mFocusInputMonitorsByDisplay.find(displayId);
    if (monitorsIt == mFocusInputMonitorsByDisplay.end()) return;

    for (const Monitor& monitor : monitorsIt->second) {
        f(monitor.connection);
    }
}

void InputDispatcher::ConnectionManager::createGlobalInputMonitor(
void InputDispatcher::ConnectionManager::createFocusInputMonitor(
        ui::LogicalDisplayId displayId, std::unique_ptr<InputChannel>&& inputChannel,
        const android::IdGenerator& idGenerator, gui::Pid pid, std::function<int(int)> callback) {
    const int fd = inputChannel->getFd();
@@ -7402,7 +7415,7 @@ void InputDispatcher::ConnectionManager::createGlobalInputMonitor(
    if (!inserted) {
        ALOGE("Created a new connection, but the token %p is already known", token.get());
    }
    mGlobalMonitorsByDisplay[displayId].emplace_back(connection, pid);
    mFocusInputMonitorsByDisplay[displayId].emplace_back(connection, pid);

    mLooper->addFd(fd, 0, ALOOPER_EVENT_INPUT, sp<LooperEventCallback>::make(callback), nullptr);
}
@@ -7438,9 +7451,9 @@ status_t InputDispatcher::ConnectionManager::removeConnection(

std::string InputDispatcher::ConnectionManager::dump(nsecs_t currentTime) const {
    std::string dump;
    if (!mGlobalMonitorsByDisplay.empty()) {
        for (const auto& [displayId, monitors] : mGlobalMonitorsByDisplay) {
            dump += StringPrintf("Global monitors on display %s:\n", displayId.toString().c_str());
    if (!mFocusInputMonitorsByDisplay.empty()) {
        for (const auto& [displayId, monitors] : mFocusInputMonitorsByDisplay) {
            dump += StringPrintf("Focus monitors on display %s:\n", displayId.toString().c_str());
            const size_t numMonitors = monitors.size();
            for (size_t i = 0; i < numMonitors; i++) {
                const Monitor& monitor = monitors[i];
@@ -7451,7 +7464,7 @@ std::string InputDispatcher::ConnectionManager::dump(nsecs_t currentTime) const
            }
        }
    } else {
        dump += "Global Monitors: <none>\n";
        dump += "Focus Monitors: <none>\n";
    }

    if (!mConnectionsByToken.empty()) {
+13 −13
Original line number Diff line number Diff line
@@ -135,9 +135,8 @@ public:
    base::Result<std::unique_ptr<InputChannel>> createInputChannel(
            const std::string& name) override;
    void setFocusedWindow(const android::gui::FocusRequest&) override;
    base::Result<std::unique_ptr<InputChannel>> createInputMonitor(ui::LogicalDisplayId displayId,
                                                                   const std::string& name,
                                                                   gui::Pid pid) override;
    base::Result<std::unique_ptr<InputChannel>> createFocusInputMonitor(
            ui::LogicalDisplayId displayId, const std::string& name, gui::Pid pid) override;
    status_t removeInputChannel(const sp<IBinder>& connectionToken) override;
    status_t pilferPointers(const sp<IBinder>& token) override;
    void requestPointerCapture(const sp<IBinder>& windowToken, bool enabled) override;
@@ -242,13 +241,13 @@ private:

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

        void createGlobalInputMonitor(ui::LogicalDisplayId displayId,
        void createFocusInputMonitor(ui::LogicalDisplayId displayId,
                                     std::unique_ptr<InputChannel>&& inputChannel,
                                     const IdGenerator& idGenerator, gui::Pid pid,
                                     std::function<int(int)> callback);
@@ -267,8 +266,9 @@ private:
        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;
        // Input channels that will receive a copy of all non-pointer input events sent to the
        // focused window on the provided display.
        std::unordered_map<ui::LogicalDisplayId, std::vector<Monitor>> mFocusInputMonitorsByDisplay;

        void removeMonitorChannel(const sp<IBinder>& connectionToken);
    };
@@ -816,7 +816,7 @@ private:
                               ftl::Flags<InputTarget::Flags> targetFlags,
                               std::optional<nsecs_t> firstDownTimeInTarget,
                               std::vector<InputTarget>& inputTargets) const REQUIRES(mLock);
    void addGlobalMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
    void addFocusInputMonitoringTargetsLocked(std::vector<InputTarget>& inputTargets,
                                              ui::LogicalDisplayId displayId) REQUIRES(mLock);
    void pokeUserActivityLocked(const EventEntry& eventEntry) REQUIRES(mLock);
    // Enqueue a drag event if needed, and update the touch state.
+10 −4
Original line number Diff line number Diff line
@@ -138,11 +138,13 @@ void TouchState::removeWindowByToken(const sp<IBinder>& token) {
    }
}

void TouchState::cancelPointersForWindowsExcept(DeviceId deviceId,
void TouchState::cancelPointersForPilferingRequest(DeviceId deviceId,
                                                   std::bitset<MAX_POINTER_ID + 1> pointerIds,
                                                   const sp<IBinder>& token) {
    std::for_each(windows.begin(), windows.end(), [&](TouchedWindow& w) {
        if (w.windowHandle->getToken() != token) {
        if (w.windowHandle->getToken() != token &&
            !w.windowHandle->getInfo()->inputConfig.test(
                    gui::WindowInfo::InputConfig::DO_NOT_PILFER)) {
            w.removeTouchingPointers(deviceId, pointerIds);
        }
    });
@@ -174,6 +176,10 @@ void TouchState::cancelPointersForNonPilferingWindows() {
    // limitation here.
    for (const auto& [deviceId, allPilferedPointerIds] : allPilferedPointerIdsByDevice) {
        std::for_each(windows.begin(), windows.end(), [&](TouchedWindow& w) {
            if (w.windowHandle->getInfo()->inputConfig.test(
                        gui::WindowInfo::InputConfig::DO_NOT_PILFER)) {
                return;
            }
            std::bitset<MAX_POINTER_ID + 1> pilferedByOtherWindows =
                    w.getPilferingPointers(deviceId) ^ allPilferedPointerIds;
            // Remove all pointers pilfered by other windows
Loading