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

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

Merge "Accumulate NotifyArgs inside the lock before notifying" into main

parents b41377db 23a98bf1
Loading
Loading
Loading
Loading
+20 −25
Original line number Diff line number Diff line
@@ -77,7 +77,7 @@ InputReader::InputReader(std::shared_ptr<EventHubInterface> eventHub,
      : mContext(this),
        mEventHub(eventHub),
        mPolicy(policy),
        mQueuedListener(listener),
        mNextListener(listener),
        mGlobalMetaState(AMETA_NONE),
        mLedMetaState(AMETA_NONE),
        mGeneration(1),
@@ -140,7 +140,7 @@ void InputReader::loopOnce() {
        mReaderIsAliveCondition.notify_all();

        if (!events.empty()) {
            notifyArgs += processEventsLocked(events.data(), events.size());
            mPendingArgs += processEventsLocked(events.data(), events.size());
        }

        if (mNextTimeout != LLONG_MAX) {
@@ -150,16 +150,18 @@ void InputReader::loopOnce() {
                    ALOGD("Timeout expired, latency=%0.3fms", (now - mNextTimeout) * 0.000001f);
                }
                mNextTimeout = LLONG_MAX;
                notifyArgs += timeoutExpiredLocked(now);
                mPendingArgs += timeoutExpiredLocked(now);
            }
        }

        if (oldGeneration != mGeneration) {
            inputDevicesChanged = true;
            inputDevices = getInputDevicesLocked();
            notifyArgs.emplace_back(
            mPendingArgs.emplace_back(
                    NotifyInputDevicesChangedArgs{mContext.getNextId(), inputDevices});
        }

        std::swap(notifyArgs, mPendingArgs);
    } // release lock

    // Send out a message that the describes the changed input devices.
@@ -175,8 +177,6 @@ void InputReader::loopOnce() {
        }
    }

    notifyAll(std::move(notifyArgs));

    // Flush queued events out to the listener.
    // This must happen outside of the lock because the listener could potentially call
    // back into the InputReader's methods, such as getScanCodeState, or become blocked
@@ -184,7 +184,9 @@ void InputReader::loopOnce() {
    // resulting in a deadlock.  This situation is actually quite plausible because the
    // listener is actually the input dispatcher, which calls into the window manager,
    // which occasionally calls into the input reader.
    mQueuedListener.flush();
    for (const NotifyArgs& args : notifyArgs) {
        mNextListener.notify(args);
    }
}

std::list<NotifyArgs> InputReader::processEventsLocked(const RawEvent* rawEvents, size_t count) {
@@ -236,8 +238,8 @@ void InputReader::addDeviceLocked(nsecs_t when, int32_t eventHubId) {
    InputDeviceIdentifier identifier = mEventHub->getDeviceIdentifier(eventHubId);
    std::shared_ptr<InputDevice> device = createDeviceLocked(eventHubId, identifier);

    notifyAll(device->configure(when, mConfig, /*changes=*/{}));
    notifyAll(device->reset(when));
    mPendingArgs += device->configure(when, mConfig, /*changes=*/{});
    mPendingArgs += device->reset(when);

    if (device->isIgnored()) {
        ALOGI("Device added: id=%d, eventHubId=%d, name='%s', descriptor='%s' "
@@ -310,12 +312,10 @@ void InputReader::removeDeviceLocked(nsecs_t when, int32_t eventHubId) {
        notifyExternalStylusPresenceChangedLocked();
    }

    std::list<NotifyArgs> resetEvents;
    if (device->hasEventHubDevices()) {
        resetEvents += device->configure(when, mConfig, /*changes=*/{});
        mPendingArgs += device->configure(when, mConfig, /*changes=*/{});
    }
    resetEvents += device->reset(when);
    notifyAll(std::move(resetEvents));
    mPendingArgs += device->reset(when);
}

std::shared_ptr<InputDevice> InputReader::createDeviceLocked(
@@ -387,7 +387,7 @@ void InputReader::handleConfigurationChangedLocked(nsecs_t when) {
    updateGlobalMetaStateLocked();

    // Enqueue configuration changed.
    mQueuedListener.notifyConfigurationChanged({mContext.getNextId(), when});
    mPendingArgs.emplace_back(NotifyConfigurationChangedArgs{mContext.getNextId(), when});
}

void InputReader::refreshConfigurationLocked(ConfigurationChanges changes) {
@@ -409,7 +409,7 @@ void InputReader::refreshConfigurationLocked(ConfigurationChanges changes) {
    } else {
        for (auto& devicePair : mDevices) {
            std::shared_ptr<InputDevice>& device = devicePair.second;
            notifyAll(device->configure(now, mConfig, changes));
            mPendingArgs += device->configure(now, mConfig, changes);
        }
    }

@@ -419,18 +419,13 @@ void InputReader::refreshConfigurationLocked(ConfigurationChanges changes) {
                  "There was no change in the pointer capture state.");
        } else {
            mCurrentPointerCaptureRequest = mConfig.pointerCaptureRequest;
            mQueuedListener.notifyPointerCaptureChanged(
                    {mContext.getNextId(), now, mCurrentPointerCaptureRequest});
            mPendingArgs.emplace_back(
                    NotifyPointerCaptureChangedArgs{mContext.getNextId(), now,
                                                    mCurrentPointerCaptureRequest});
        }
    }
}

void InputReader::notifyAll(std::list<NotifyArgs>&& argsList) {
    for (const NotifyArgs& args : argsList) {
        mQueuedListener.notify(args);
    }
}

void InputReader::updateGlobalMetaStateLocked() {
    mGlobalMetaState = 0;

@@ -690,7 +685,7 @@ void InputReader::vibrate(int32_t deviceId, const VibrationSequence& sequence, s

    InputDevice* device = findInputDeviceLocked(deviceId);
    if (device) {
        notifyAll(device->vibrate(sequence, repeat, token));
        mPendingArgs += device->vibrate(sequence, repeat, token);
    }
}

@@ -699,7 +694,7 @@ void InputReader::cancelVibrate(int32_t deviceId, int32_t token) {

    InputDevice* device = findInputDeviceLocked(deviceId);
    if (device) {
        notifyAll(device->cancelVibrate(token));
        mPendingArgs += device->cancelVibrate(token);
    }
}

+8 −3
Original line number Diff line number Diff line
@@ -174,7 +174,14 @@ private:
    // in parallel to passing it to the InputReader.
    std::shared_ptr<EventHubInterface> mEventHub;
    sp<InputReaderPolicyInterface> mPolicy;
    QueuedInputListener mQueuedListener;

    // The next stage that should receive the events generated inside InputReader.
    InputListenerInterface& mNextListener;
    // As various events are generated inside InputReader, they are stored inside this list. The
    // list can only be accessed with the lock, so the events inside it are well-ordered.
    // Once the reader is done working, these events will be swapped into a temporary storage and
    // sent to the 'mNextListener' without holding the lock.
    std::list<NotifyArgs> mPendingArgs GUARDED_BY(mLock);

    InputReaderConfiguration mConfig GUARDED_BY(mLock);

@@ -242,8 +249,6 @@ private:
    ConfigurationChanges mConfigurationChangesToRefresh GUARDED_BY(mLock);
    void refreshConfigurationLocked(ConfigurationChanges changes) REQUIRES(mLock);

    void notifyAll(std::list<NotifyArgs>&& argsList);

    PointerCaptureRequest mCurrentPointerCaptureRequest GUARDED_BY(mLock);

    // state queries