@@ -37,17 +37,30 @@ using testing::Return;
3737using testing::SetArgPointee;
3838using testing::VariantWith;
3939
40- static constexpr ui::LogicalDisplayId DISPLAY_ID = ui::LogicalDisplayId::DEFAULT;
41- static constexpr int32_t DISPLAY_WIDTH = 480 ;
42- static constexpr int32_t DISPLAY_HEIGHT = 800 ;
43- static constexpr std::optional<uint8_t > NO_PORT = std::nullopt ; // no physical port is specified
44- static constexpr int32_t SLOT_COUNT = 5 ;
45-
46- static constexpr int32_t ACTION_POINTER_0_UP =
40+ namespace {
41+
42+ constexpr ui::LogicalDisplayId DISPLAY_ID = ui::LogicalDisplayId::DEFAULT;
43+ constexpr ui::LogicalDisplayId SECOND_DISPLAY_ID = ui::LogicalDisplayId{DISPLAY_ID.val () + 1 };
44+ constexpr int32_t DISPLAY_WIDTH = 480 ;
45+ constexpr int32_t DISPLAY_HEIGHT = 800 ;
46+ constexpr std::optional<uint8_t > NO_PORT = std::nullopt ; // no physical port is specified
47+ constexpr int32_t SLOT_COUNT = 5 ;
48+
49+ constexpr int32_t ACTION_DOWN = AMOTION_EVENT_ACTION_DOWN;
50+ constexpr int32_t ACTION_CANCEL = AMOTION_EVENT_ACTION_CANCEL;
51+ constexpr int32_t ACTION_POINTER_0_UP =
4752 AMOTION_EVENT_ACTION_POINTER_UP | (0 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
48- static constexpr int32_t ACTION_POINTER_1_DOWN =
53+ constexpr int32_t ACTION_POINTER_1_DOWN =
4954 AMOTION_EVENT_ACTION_POINTER_DOWN | (1 << AMOTION_EVENT_ACTION_POINTER_INDEX_SHIFT);
5055
56+ template <typename ... Args>
57+ void assertNotifyArgs (const std::list<NotifyArgs>& args, Args... matchers) {
58+ ASSERT_THAT (args, ElementsAre (matchers...))
59+ << " Got instead: " << dumpContainer (args, streamableToString);
60+ }
61+
62+ } // namespace
63+
5164/* *
5265 * Unit tests for MultiTouchInputMapper.
5366 */
@@ -270,6 +283,58 @@ TEST_F(MultiTouchInputMapperUnitTest, MultiFingerGestureWithUnexpectedReset) {
270283 VariantWith<NotifyMotionArgs>(WithMotionAction (AMOTION_EVENT_ACTION_UP))));
271284}
272285
286+ class ExternalMultiTouchInputMapperTest : public MultiTouchInputMapperUnitTest {
287+ protected:
288+ void SetUp () override { MultiTouchInputMapperUnitTest::SetUp (/* bus=*/ 0 , /* isExternal=*/ true ); }
289+ };
290+
291+ /* *
292+ * Expect fallback to internal viewport if device is external and external viewport is not present.
293+ */
294+ TEST_F (ExternalMultiTouchInputMapperTest, Viewports_Fallback) {
295+ std::list<NotifyArgs> args;
296+
297+ // Expect the event to be sent to the internal viewport,
298+ // because an external viewport is not present.
299+ args += processKey (BTN_TOUCH, 1 );
300+ args += processId (1 );
301+ args += processPosition (100 , 200 );
302+ args += processSync ();
303+
304+ assertNotifyArgs (args,
305+ VariantWith<NotifyMotionArgs>(
306+ AllOf (WithMotionAction (ACTION_DOWN), WithDisplayId (DISPLAY_ID))));
307+
308+ // Expect the event to be sent to the external viewport if it is present.
309+ DisplayViewport externalViewport =
310+ createViewport (SECOND_DISPLAY_ID, DISPLAY_WIDTH, DISPLAY_HEIGHT, ui::ROTATION_0,
311+ /* isActive=*/ true , " local:1" , NO_PORT, ViewportType::EXTERNAL);
312+ mFakePolicy ->addDisplayViewport (externalViewport);
313+ std::optional<DisplayViewport> internalViewport =
314+ mFakePolicy ->getDisplayViewportByUniqueId (" local:0" );
315+ mReaderConfiguration .setDisplayViewports ({*internalViewport, externalViewport});
316+ args = mMapper ->reconfigure (systemTime (SYSTEM_TIME_MONOTONIC), mReaderConfiguration ,
317+ InputReaderConfiguration::Change::DISPLAY_INFO);
318+
319+ assertNotifyArgs (args,
320+ VariantWith<NotifyMotionArgs>(AllOf (WithMotionAction (ACTION_CANCEL),
321+ WithDisplayId (SECOND_DISPLAY_ID))),
322+ VariantWith<NotifyDeviceResetArgs>(WithDeviceId (DEVICE_ID)));
323+ // Lift up the old pointer.
324+ processKey (BTN_TOUCH, 0 );
325+ args = processId (-1 );
326+ args += processSync ();
327+
328+ // Send new pointer
329+ args += processKey (BTN_TOUCH, 1 );
330+ args += processId (2 );
331+ args += processPosition (111 , 211 );
332+ args += processSync ();
333+ assertNotifyArgs (args,
334+ VariantWith<NotifyMotionArgs>(AllOf (WithMotionAction (ACTION_DOWN),
335+ WithDisplayId (SECOND_DISPLAY_ID))));
336+ }
337+
273338class MultiTouchInputMapperPointerModeUnitTest : public MultiTouchInputMapperUnitTest {
274339protected:
275340 void SetUp () override {
0 commit comments