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
diff --git a/services/inputflinger/InputReaderBase.cpp b/services/inputflinger/InputReaderBase.cpp
index b2dadf8..9cc777d 100644
--- a/services/inputflinger/InputReaderBase.cpp
+++ b/services/inputflinger/InputReaderBase.cpp
@@ -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 @@
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;
}
diff --git a/services/inputflinger/tests/InputReader_test.cpp b/services/inputflinger/tests/InputReader_test.cpp
index 211b49e..a72d5c3 100644
--- a/services/inputflinger/tests/InputReader_test.cpp
+++ b/services/inputflinger/tests/InputReader_test.cpp
@@ -33,6 +33,8 @@
#include <math.h>
#include <memory>
+#include "input/DisplayViewport.h"
+#include "input/Input.h"
namespace android {
@@ -1233,6 +1235,47 @@
}
/**
+ * 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
*/
TEST_F(InputReaderPolicyTest, Viewports_GetByPort) {