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

Commit 38d2ad5b authored by Patrick Williams's avatar Patrick Williams
Browse files

Fix unsynchronized calls to IWindowInfosPublisher

Bug: 411453834
Flag: EXEMPT bugfix
Test: presubmits
Change-Id: If4b4f7703010f07b2854389f0aeaf6459191b83e
parent 4f3ff0fa
Loading
Loading
Loading
Loading
+28 −30
Original line number Diff line number Diff line
@@ -54,49 +54,47 @@ android::base::Result<gui::WindowInfosUpdate> WindowInfosListenerReporter::addWi
status_t WindowInfosListenerReporter::removeWindowInfosListener(
        const sp<WindowInfosListener>& windowInfosListener,
        const sp<gui::ISurfaceComposer>& surfaceComposer) {
    status_t status = OK;
    {
    std::scoped_lock lock(mListenersMutex);
        if (mWindowInfosListeners.find(windowInfosListener) == mWindowInfosListeners.end()) {
            return status;
    mWindowInfosListeners.erase(windowInfosListener);
    if (!mWindowInfosListeners.empty()) {
        return OK;
    }

    if (binder::Status status = surfaceComposer->removeWindowInfosListener(this); !status.isOk()) {
        ALOGW("Failed to remove window infos listener from SurfaceFlinger");
        return statusTFromBinderStatus(status);
    }

        if (mWindowInfosListeners.size() == 1) {
            binder::Status s = surfaceComposer->removeWindowInfosListener(this);
            status = statusTFromBinderStatus(s);
    // Clear the last stored state since we're disabling updates and don't want to hold
    // stale values
    mLastUpdate = gui::WindowInfosUpdate();
        }

        if (status == OK) {
            mWindowInfosListeners.erase(windowInfosListener);
        }
    }
    mWindowInfosPublisher.clear();
    mListenerId = UNASSIGNED_LISTENER_ID;

    return status;
    return OK;
}

binder::Status WindowInfosListenerReporter::onWindowInfosChanged(
        const gui::WindowInfosUpdate& update) {
    std::unordered_set<sp<WindowInfosListener>, gui::SpHash<WindowInfosListener>>
            windowInfosListeners;

    ListenerSet listeners;
    int64_t id;
    sp<gui::IWindowInfosPublisher> publisher;
    {
        std::scoped_lock lock(mListenersMutex);
        for (auto listener : mWindowInfosListeners) {
            windowInfosListeners.insert(listener);
        }

        listeners = mWindowInfosListeners;
        publisher = mWindowInfosPublisher;
        id = mListenerId;
        mLastUpdate = update;
    }

    for (auto listener : windowInfosListeners) {
    // Publisher may be null if we've removed the last window infos listener before handling all
    // in-flight onWindowInfosChanged calls.
    if (!publisher) {
        return binder::Status::ok();
    }
    for (auto listener : listeners) {
        listener->onWindowInfosChanged(update);
    }

    mWindowInfosPublisher->ackWindowInfosReceived(update.vsyncId, mListenerId);

    publisher->ackWindowInfosReceived(update.vsyncId, id);
    return binder::Status::ok();
}

+8 −6
Original line number Diff line number Diff line
@@ -42,13 +42,15 @@ private:
    WindowInfosListenerReporter() = default;
    friend class sp<WindowInfosListenerReporter>;

    std::mutex mListenersMutex;
    std::unordered_set<sp<gui::WindowInfosListener>, gui::SpHash<gui::WindowInfosListener>>
            mWindowInfosListeners GUARDED_BY(mListenersMutex);
    using ListenerSet =
            std::unordered_set<sp<gui::WindowInfosListener>, gui::SpHash<gui::WindowInfosListener>>;

    gui::WindowInfosUpdate mLastUpdate GUARDED_BY(mListenersMutex);
    static constexpr int64_t UNASSIGNED_LISTENER_ID = -1;

    sp<gui::IWindowInfosPublisher> mWindowInfosPublisher;
    int64_t mListenerId;
    std::mutex mListenersMutex;
    ListenerSet mWindowInfosListeners GUARDED_BY(mListenersMutex);
    gui::WindowInfosUpdate mLastUpdate GUARDED_BY(mListenersMutex);
    sp<gui::IWindowInfosPublisher> mWindowInfosPublisher GUARDED_BY(mListenersMutex);
    int64_t mListenerId GUARDED_BY(mListenersMutex);
};
} // namespace android