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

Commit dde67b89 authored by Michael Wright's avatar Michael Wright
Browse files

Support multiple internal and external viewports

The policy is still effectively the same by selecting the first display,
but this lets devices which are configured with a specific unique ID to
see the viewport that should be associated with it.

Bug: 116824030
Bug: 171549575
Test: atest InputReader_test
Change-Id: I3f78a122a3a8dce9c8dac3c88f3d51f29afa367c
parent 9febda8e
Loading
Loading
Loading
Loading
+2 −13
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@

#include <android-base/stringprintf.h>
#include <input/Input.h>
#include <input/NamedEnum.h>

#include <cinttypes>
#include <optional>
@@ -44,18 +45,6 @@ enum class ViewportType : int32_t {
    VIRTUAL = 3,
};

static const char* viewportTypeToString(ViewportType type) {
    switch (type) {
        case ViewportType::INTERNAL:
            return "INTERNAL";
        case ViewportType::EXTERNAL:
            return "EXTERNAL";
        case ViewportType::VIRTUAL:
            return "VIRTUAL";
    }
    return "UNKNOWN";
}

/*
 * Describes how coordinates are mapped on a physical display.
 * See com.android.server.display.DisplayViewport.
@@ -142,7 +131,7 @@ struct DisplayViewport {
                            "physicalFrame=[%d, %d, %d, %d], "
                            "deviceSize=[%d, %d], "
                            "isActive=[%d]",
                            viewportTypeToString(type), displayId, uniqueId.c_str(),
                            NamedEnum::string(type).c_str(), displayId, uniqueId.c_str(),
                            physicalPort ? StringPrintf("%" PRIu8, *physicalPort).c_str()
                                         : "<none>",
                            orientation, logicalLeft, logicalTop, logicalRight, logicalBottom,
+9 −4
Original line number Diff line number Diff line
@@ -19,6 +19,9 @@
//#define LOG_NDEBUG 0

#include "InputReaderBase.h"
#include "input/DisplayViewport.h"
#include "input/Input.h"
#include "input/NamedEnum.h"

#include <android/log.h>
#include <android-base/stringprintf.h>
@@ -99,17 +102,19 @@ std::optional<DisplayViewport> InputReaderConfiguration::getDisplayViewportByTyp
    size_t count = 0;
    std::optional<DisplayViewport> result = std::nullopt;
    for (const DisplayViewport& currentViewport : mDisplays) {
        // Return the first match
        // Return the first match, or the default display if we're looking for the internal viewport
        if (currentViewport.type == type) {
            if (!result) {
            if (!result ||
                (type == ViewportType::INTERNAL &&
                 currentViewport.displayId == ADISPLAY_ID_DEFAULT)) {
                result = std::make_optional(currentViewport);
            }
            count++;
        }
    }
    if (count > 1) {
        ALOGE("Found %zu viewports with type %s, but expected 1 at most",
                count, viewportTypeToString(type));
        ALOGW("Found %zu viewports with type %s, but expected 1 at most", count,
              NamedEnum::string(type).c_str());
    }
    return result;
}
+43 −0
Original line number Diff line number Diff line
@@ -33,6 +33,8 @@
#include <math.h>

#include <memory>
#include "input/DisplayViewport.h"
#include "input/Input.h"

namespace android {

@@ -1232,6 +1234,47 @@ TEST_F(InputReaderPolicyTest, Viewports_TwoOfSameType) {
    }
}

/**
 * When we have multiple internal displays make sure we always return the default display when
 * querying by type.
 */
TEST_F(InputReaderPolicyTest, Viewports_ByTypeReturnsDefaultForInternal) {
    const std::string uniqueId1 = "uniqueId1";
    const std::string uniqueId2 = "uniqueId2";
    constexpr int32_t nonDefaultDisplayId = 2;
    static_assert(nonDefaultDisplayId != ADISPLAY_ID_DEFAULT,
                  "Test display ID should not be ADISPLAY_ID_DEFAULT");

    // Add the default display first and ensure it gets returned.
    mFakePolicy->clearViewports();
    mFakePolicy->addDisplayViewport(ADISPLAY_ID_DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT,
                                    DISPLAY_ORIENTATION_0, uniqueId1, NO_PORT,
                                    ViewportType::INTERNAL);
    mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT,
                                    DISPLAY_ORIENTATION_0, uniqueId2, NO_PORT,
                                    ViewportType::INTERNAL);

    std::optional<DisplayViewport> viewport =
            mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
    ASSERT_TRUE(viewport);
    ASSERT_EQ(ADISPLAY_ID_DEFAULT, viewport->displayId);
    ASSERT_EQ(ViewportType::INTERNAL, viewport->type);

    // Add the default display second to make sure order doesn't matter.
    mFakePolicy->clearViewports();
    mFakePolicy->addDisplayViewport(nonDefaultDisplayId, DISPLAY_WIDTH, DISPLAY_HEIGHT,
                                    DISPLAY_ORIENTATION_0, uniqueId2, NO_PORT,
                                    ViewportType::INTERNAL);
    mFakePolicy->addDisplayViewport(ADISPLAY_ID_DEFAULT, DISPLAY_WIDTH, DISPLAY_HEIGHT,
                                    DISPLAY_ORIENTATION_0, uniqueId1, NO_PORT,
                                    ViewportType::INTERNAL);

    viewport = mFakePolicy->getDisplayViewportByType(ViewportType::INTERNAL);
    ASSERT_TRUE(viewport);
    ASSERT_EQ(ADISPLAY_ID_DEFAULT, viewport->displayId);
    ASSERT_EQ(ViewportType::INTERNAL, viewport->type);
}

/**
 * Check getDisplayViewportByPort
 */