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

Commit 193f0e7d authored by Prabir Pradhan's avatar Prabir Pradhan
Browse files

Send WindowInfo even if the window isn't associated with a DisplayDevice

The previous behavior was the following: If a window was in a layerStack
for which there were no DisplayDevices that mapped to it, there was no
WindowInfo sent for it.

When a display is turned OFF, it is mapped to an invalid layer stack.
So when the primary display is turned OFF, there is no WindowInfo sent
for any windows on layerStack 0 as there are no DisplayDevices that now
map to it. In this model, no window can receive input when the display
is OFF.

In this CL, we change the behavior so that WindowInfos are sent even if
there are no DisplayDevices that map to its layerStack -- except that
in this case, we do not let the window receive touches, as we do not
have a valid transform associated with it.

Bug: 239788987
Test: See bug for repro steps
Test: Observe logs at runtime
Change-Id: Ibe0e4326ddea51d461a010c29ce8616b30d29ed3
parent b32be9c3
Loading
Loading
Loading
Loading
+14 −3
Original line number Diff line number Diff line
@@ -78,6 +78,7 @@
namespace android {
namespace {
constexpr int kDumpTableRowLength = 159;
const ui::Transform kIdentityTransform;
} // namespace

using namespace ftl::flag_operators;
@@ -2209,7 +2210,8 @@ void Layer::writeToProtoCommonState(LayerProto* layerInfo, LayerVector::StateSet
    if ((traceFlags & LayerTracing::TRACE_INPUT) && needsInputInfo()) {
        WindowInfo info;
        if (useDrawing) {
            info = fillInputInfo(ui::Transform(), /* displayIsSecure */ true);
            info = fillInputInfo(
                    InputDisplayArgs{.transform = &kIdentityTransform, .isSecure = true});
        } else {
            info = state.inputInfo;
        }
@@ -2416,7 +2418,7 @@ void Layer::handleDropInputMode(gui::WindowInfo& info) const {
    }
}

WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform, bool displayIsSecure) {
WindowInfo Layer::fillInputInfo(const InputDisplayArgs& displayArgs) {
    if (!hasInputInfo()) {
        mDrawingState.inputInfo.name = getName();
        mDrawingState.inputInfo.ownerUid = mOwnerUid;
@@ -2425,12 +2427,21 @@ WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform, bool disp
        mDrawingState.inputInfo.displayId = getLayerStack().id;
    }

    const ui::Transform& displayTransform =
            displayArgs.transform != nullptr ? *displayArgs.transform : kIdentityTransform;

    WindowInfo info = mDrawingState.inputInfo;
    info.id = sequence;
    info.displayId = getLayerStack().id;

    fillInputFrameInfo(info, displayTransform);

    if (displayArgs.transform == nullptr) {
        // Do not let the window receive touches if it is not associated with a valid display
        // transform. We still allow the window to receive keys and prevent ANRs.
        info.inputConfig |= WindowInfo::InputConfig::NOT_TOUCHABLE;
    }

    // For compatibility reasons we let layers which can receive input
    // receive input before they have actually submitted a buffer. Because
    // of this we use canReceiveInput instead of isVisible to check the
@@ -2448,7 +2459,7 @@ WindowInfo Layer::fillInputInfo(const ui::Transform& displayTransform, bool disp

    // If the window will be blacked out on a display because the display does not have the secure
    // flag and the layer has the secure flag set, then drop input.
    if (!displayIsSecure && isSecure()) {
    if (!displayArgs.isSecure && isSecure()) {
        info.inputConfig |= WindowInfo::InputConfig::DROP_INPUT;
    }

+5 −1
Original line number Diff line number Diff line
@@ -854,7 +854,11 @@ public:
    bool getPremultipledAlpha() const;
    void setInputInfo(const gui::WindowInfo& info);

    gui::WindowInfo fillInputInfo(const ui::Transform& displayTransform, bool displayIsSecure);
    struct InputDisplayArgs {
        const ui::Transform* transform = nullptr;
        bool isSecure = false;
    };
    gui::WindowInfo fillInputInfo(const InputDisplayArgs& displayArgs);

    /**
     * Returns whether this layer has an explicitly set input-info.
+5 −5
Original line number Diff line number Diff line
@@ -3312,11 +3312,11 @@ void SurfaceFlinger::buildWindowInfos(std::vector<WindowInfo>& outWindowInfos,
    mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
        if (!layer->needsInputInfo()) return;

        // Do not create WindowInfos for windows on displays that cannot receive input.
        if (const auto opt = displayInputInfos.get(layer->getLayerStack())) {
            const auto& info = opt->get();
            outWindowInfos.push_back(layer->fillInputInfo(info.transform, info.isSecure));
        }
        const auto opt = displayInputInfos.get(layer->getLayerStack(),
                                               [](const auto& info) -> Layer::InputDisplayArgs {
                                                   return {&info.transform, info.isSecure};
                                               });
        outWindowInfos.push_back(layer->fillInputInfo(opt.value_or(Layer::InputDisplayArgs{})));
    });

    sNumWindowInfos = outWindowInfos.size();