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

Commit f49608d3 authored by Siarhei Vishniakou's avatar Siarhei Vishniakou
Browse files

Check if input devices are opening

If input devices are opening, but not yet open, they will be sitting in
mOpeningDevices list and not in mDevices map.

Therefore, when pairing a video device, we should check both places.

This is needed because of a recent behaviour change where device can
only be in 1 place at a given time.

Bug: 165554458
Test: adb shell dumpsys input
Change-Id: Id44a2d7a6f8246dec26cb33c6d073d7f0c39e507
parent 36ca632e
Loading
Loading
Loading
Loading
+31 −26
Original line number Diff line number Diff line
@@ -979,18 +979,30 @@ size_t EventHub::getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSiz
            mNeedToSendFinishedDeviceScan = true;
        }

        for (auto it = mOpeningDevices.begin(); it != mOpeningDevices.end();) {
            std::unique_ptr<Device> device = std::move(*it);
        while (!mOpeningDevices.empty()) {
            std::unique_ptr<Device> device = std::move(*mOpeningDevices.rbegin());
            mOpeningDevices.pop_back();
            ALOGV("Reporting device opened: id=%d, name=%s\n", device->id, device->path.c_str());
            event->when = now;
            event->deviceId = device->id == mBuiltInKeyboardId ? 0 : device->id;
            event->type = DEVICE_ADDED;
            event += 1;
            auto [dev_it, insert] = mDevices.insert_or_assign(device->id, std::move(device));
            if (!insert) {

            // Try to find a matching video device by comparing device names
            for (auto it = mUnattachedVideoDevices.begin(); it != mUnattachedVideoDevices.end();
                 it++) {
                std::unique_ptr<TouchVideoDevice>& videoDevice = *it;
                if (tryAddVideoDevice(*device, videoDevice)) {
                    // videoDevice was transferred to 'device'
                    it = mUnattachedVideoDevices.erase(it);
                    break;
                }
            }

            auto [dev_it, inserted] = mDevices.insert_or_assign(device->id, std::move(device));
            if (!inserted) {
                ALOGW("Device id %d exists, replaced.", device->id);
            }
            it = mOpeningDevices.erase(it);
            mNeedToSendFinishedDeviceScan = true;
            if (--capacity == 0) {
                break;
@@ -1536,21 +1548,6 @@ status_t EventHub::openDeviceLocked(const std::string& devicePath) {
        device->setLedForControllerLocked();
    }

    // Find a matching video device by comparing device names
    // This should be done before registerDeviceForEpollLocked, so that both fds are added to epoll
    for (std::unique_ptr<TouchVideoDevice>& videoDevice : mUnattachedVideoDevices) {
        if (device->identifier.name == videoDevice->getName()) {
            device->videoDevice = std::move(videoDevice);
            break;
        }
    }
    mUnattachedVideoDevices
            .erase(std::remove_if(mUnattachedVideoDevices.begin(), mUnattachedVideoDevices.end(),
                                  [](const std::unique_ptr<TouchVideoDevice>& videoDevice) {
                                      return videoDevice == nullptr;
                                  }),
                   mUnattachedVideoDevices.end());

    if (registerDeviceForEpollLocked(*device) != OK) {
        return -1;
    }
@@ -1576,12 +1573,8 @@ void EventHub::openVideoDeviceLocked(const std::string& devicePath) {
    }
    // Transfer ownership of this video device to a matching input device
    for (const auto& [id, device] : mDevices) {
        if (videoDevice->getName() == device->identifier.name) {
            device->videoDevice = std::move(videoDevice);
            if (device->enabled) {
                registerVideoDeviceForEpollLocked(*device->videoDevice);
            }
            return;
        if (tryAddVideoDevice(*device, videoDevice)) {
            return; // 'device' now owns 'videoDevice'
        }
    }

@@ -1592,6 +1585,18 @@ void EventHub::openVideoDeviceLocked(const std::string& devicePath) {
    mUnattachedVideoDevices.push_back(std::move(videoDevice));
}

bool EventHub::tryAddVideoDevice(EventHub::Device& device,
                                 std::unique_ptr<TouchVideoDevice>& videoDevice) {
    if (videoDevice->getName() != device.identifier.name) {
        return false;
    }
    device.videoDevice = std::move(videoDevice);
    if (device.enabled) {
        registerVideoDeviceForEpollLocked(*device.videoDevice);
    }
    return true;
}

bool EventHub::isDeviceEnabled(int32_t deviceId) {
    AutoMutex _l(mLock);
    Device* device = getDeviceLocked(deviceId);
+8 −0
Original line number Diff line number Diff line
@@ -460,6 +460,14 @@ private:

    status_t openDeviceLocked(const std::string& devicePath);
    void openVideoDeviceLocked(const std::string& devicePath);
    /**
     * Try to associate a video device with an input device. If the association succeeds,
     * the videoDevice is moved into the input device. 'videoDevice' will become null if this
     * happens.
     * Return true if the association succeeds.
     * Return false otherwise.
     */
    bool tryAddVideoDevice(Device& device, std::unique_ptr<TouchVideoDevice>& videoDevice);
    void createVirtualKeyboardLocked();
    void addDeviceLocked(std::unique_ptr<Device> device);
    void assignDescriptorLocked(InputDeviceIdentifier& identifier);