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

Commit 55c85404 authored by Dominik Laskowski's avatar Dominik Laskowski
Browse files

SF: Populate DisplayConnectionType in DisplayInfo

Without HWC support, fall back to categorizing the primary display as
internal, and secondary displays as external.

Also, validate displays in HWComposer for other 2.4 APIs.

Bug: 134771872
Test: dumpsys SurfaceFlinger --displays
Test: dumpsys display
Test: libsurfaceflinger_unittest
Change-Id: I139eeab9cc34e21a1b8584a2fcb9c9fd5dc43ac3
parent c4173b5f
Loading
Loading
Loading
Loading
+3 −0
Original line number Diff line number Diff line
@@ -20,8 +20,11 @@

namespace android {

enum class DisplayConnectionType { Internal, External };

// Immutable information about physical display.
struct DisplayInfo {
    DisplayConnectionType connectionType = DisplayConnectionType::Internal;
    float density = 0.f;
    bool secure = false;
};
+1 −0
Original line number Diff line number Diff line
@@ -88,6 +88,7 @@ public:
    MOCK_CONST_METHOD1(getColorModes, std::vector<ui::ColorMode>(DisplayId));
    MOCK_METHOD3(setActiveColorMode, status_t(DisplayId, ui::ColorMode, ui::RenderIntent));
    MOCK_CONST_METHOD0(isUsingVrComposer, bool());
    MOCK_CONST_METHOD1(getDisplayConnectionType, DisplayConnectionType(DisplayId));
    MOCK_CONST_METHOD1(isVsyncPeriodSwitchSupported, bool(DisplayId));
    MOCK_CONST_METHOD1(getDisplayVsyncPeriod, nsecs_t(DisplayId));
    MOCK_METHOD4(setActiveConfigWithConstraints,
+15 −7
Original line number Diff line number Diff line
@@ -49,16 +49,16 @@ ui::Transform::RotationFlags DisplayDevice::sPrimaryDisplayRotationFlags = ui::T

DisplayDeviceCreationArgs::DisplayDeviceCreationArgs(const sp<SurfaceFlinger>& flinger,
                                                     const wp<IBinder>& displayToken,
                                                     const std::optional<DisplayId>& displayId)
                                                     std::optional<DisplayId> displayId)
      : flinger(flinger), displayToken(displayToken), displayId(displayId) {}

DisplayDevice::DisplayDevice(DisplayDeviceCreationArgs&& args)
      : mFlinger(args.flinger),
        mDisplayToken(args.displayToken),
        mSequenceId(args.sequenceId),
        mIsVirtual(args.isVirtual),
        mConnectionType(args.connectionType),
        mCompositionDisplay{mFlinger->getCompositionEngine().createDisplay(
                compositionengine::DisplayCreationArgs{args.isVirtual, args.displayId,
                compositionengine::DisplayCreationArgs{args.isVirtual(), args.displayId,
                                                       args.powerAdvisor})},
        mPhysicalOrientation(args.physicalOrientation),
        mIsPrimary(args.isPrimary) {
@@ -248,10 +248,18 @@ ui::Transform::RotationFlags DisplayDevice::getPrimaryDisplayRotationFlags() {
}

std::string DisplayDevice::getDebugName() const {
    const auto id = getId() ? to_string(*getId()) + ", " : std::string();
    return base::StringPrintf("DisplayDevice{%s%s%s\"%s\"}", id.c_str(),
                              isPrimary() ? "primary, " : "", isVirtual() ? "virtual, " : "",
                              mDisplayName.c_str());
    std::string displayId;
    if (const auto id = getId()) {
        displayId = to_string(*id) + ", ";
    }

    const char* type = "virtual";
    if (mConnectionType) {
        type = *mConnectionType == DisplayConnectionType::Internal ? "internal" : "external";
    }

    return base::StringPrintf("DisplayDevice{%s%s%s, \"%s\"}", displayId.c_str(), type,
                              isPrimary() ? ", primary" : "", mDisplayName.c_str());
}

void DisplayDevice::dump(std::string& result) const {
+21 −8
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@
#include <math/mat4.h>
#include <renderengine/RenderEngine.h>
#include <system/window.h>
#include <ui/DisplayInfo.h>
#include <ui/DisplayState.h>
#include <ui/GraphicTypes.h>
#include <ui/HdrCapabilities.h>
@@ -52,7 +53,6 @@ class SurfaceFlinger;

struct CompositionInfo;
struct DisplayDeviceCreationArgs;
struct DisplayInfo;

namespace compositionengine {
class Display;
@@ -71,7 +71,9 @@ public:
        return mCompositionDisplay;
    }

    bool isVirtual() const { return mIsVirtual; }
    std::optional<DisplayConnectionType> getConnectionType() const { return mConnectionType; }

    bool isVirtual() const { return !mConnectionType; }
    bool isPrimary() const { return mIsPrimary; }

    // isSecure indicates whether this display can be trusted to display
@@ -159,7 +161,7 @@ private:
    const sp<SurfaceFlinger> mFlinger;
    const wp<IBinder> mDisplayToken;
    const int32_t mSequenceId;
    const bool mIsVirtual;
    const std::optional<DisplayConnectionType> mConnectionType;

    const std::shared_ptr<compositionengine::Display> mCompositionDisplay;

@@ -178,10 +180,19 @@ private:
};

struct DisplayDeviceState {
    bool isVirtual() const { return !displayId.has_value(); }
    struct Physical {
        DisplayId id;
        DisplayConnectionType type;

        bool operator==(const Physical& other) const {
            return id == other.id && type == other.type;
        }
    };

    bool isVirtual() const { return !physical; }

    int32_t sequenceId = sNextSequenceId++;
    std::optional<DisplayId> displayId;
    std::optional<Physical> physical;
    sp<IGraphicBufferProducer> surface;
    ui::LayerStack layerStack = ui::NO_LAYER_STACK;
    Rect viewport;
@@ -199,15 +210,17 @@ private:
struct DisplayDeviceCreationArgs {
    // We use a constructor to ensure some of the values are set, without
    // assuming a default value.
    DisplayDeviceCreationArgs(const sp<SurfaceFlinger>& flinger, const wp<IBinder>& displayToken,
                              const std::optional<DisplayId>& displayId);
    DisplayDeviceCreationArgs(const sp<SurfaceFlinger>&, const wp<IBinder>& displayToken,
                              std::optional<DisplayId>);

    bool isVirtual() const { return !connectionType; }

    const sp<SurfaceFlinger> flinger;
    const wp<IBinder> displayToken;
    const std::optional<DisplayId> displayId;

    int32_t sequenceId{0};
    bool isVirtual{false};
    std::optional<DisplayConnectionType> connectionType;
    bool isSecure{false};
    sp<ANativeWindow> nativeWindow;
    sp<compositionengine::DisplaySurface> displaySurface;
+34 −17
Original line number Diff line number Diff line
@@ -95,13 +95,13 @@ float Display::Config::Builder::getDefaultDensity() {
}

namespace impl {

Display::Display(android::Hwc2::Composer& composer,
                 const std::unordered_set<Capability>& capabilities, hwc2_display_t id,
                 DisplayType type)
      : mComposer(composer),
        mCapabilities(capabilities),
        mId(id),
        mIsConnected(false),
        mType(type) {
    ALOGV("Created display %" PRIu64, id);
}
@@ -109,20 +109,27 @@ Display::Display(android::Hwc2::Composer& composer,
Display::~Display() {
    mLayers.clear();

    if (mType == DisplayType::Virtual) {
        ALOGV("Destroying virtual display");
        auto intError = mComposer.destroyVirtualDisplay(mId);
        auto error = static_cast<Error>(intError);
        ALOGE_IF(error != Error::None, "destroyVirtualDisplay(%" PRIu64
                ") failed: %s (%d)", mId, to_string(error).c_str(), intError);
    } else if (mType == DisplayType::Physical) {
        auto error = setVsyncEnabled(HWC2::Vsync::Disable);
        if (error != Error::None) {
            ALOGE("~Display: Failed to disable vsync for display %" PRIu64
                    ": %s (%d)", mId, to_string(error).c_str(),
                    static_cast<int32_t>(error));
        }
    Error error = Error::None;
    const char* msg;
    switch (mType) {
        case DisplayType::Physical:
            error = setVsyncEnabled(HWC2::Vsync::Disable);
            msg = "disable VSYNC for";
            break;

        case DisplayType::Virtual:
            error = static_cast<Error>(mComposer.destroyVirtualDisplay(mId));
            msg = "destroy virtual";
            break;

        case DisplayType::Invalid: // Used in unit tests.
            break;
    }

    ALOGE_IF(error != Error::None, "%s: Failed to %s display %" PRIu64 ": %s (%d)", __FUNCTION__,
             msg, mId, to_string(error).c_str(), static_cast<int32_t>(error));

    ALOGV("Destroyed display %" PRIu64, mId);
}

// Required by HWC2 display
@@ -372,9 +379,19 @@ Error Display::getRequests(HWC2::DisplayRequest* outDisplayRequests,
    return Error::None;
}

Error Display::getType(DisplayType* outType) const
{
    *outType = mType;
Error Display::getConnectionType(android::DisplayConnectionType* outType) const {
    if (mType != DisplayType::Physical) return Error::BadDisplay;

    using ConnectionType = Hwc2::IComposerClient::DisplayConnectionType;
    ConnectionType connectionType;
    const auto error = static_cast<Error>(mComposer.getDisplayConnectionType(mId, &connectionType));
    if (error != Error::None) {
        return error;
    }

    *outType = connectionType == ConnectionType::INTERNAL
            ? android::DisplayConnectionType::Internal
            : android::DisplayConnectionType::External;
    return Error::None;
}

Loading