diff --git a/shell/platform/android/BUILD.gn b/shell/platform/android/BUILD.gn index da29ead5521d4..93e6b140a7304 100644 --- a/shell/platform/android/BUILD.gn +++ b/shell/platform/android/BUILD.gn @@ -456,6 +456,7 @@ action("robolectric_tests") { "test/io/flutter/plugin/localization/LocalizationPluginTest.java", "test/io/flutter/plugin/mouse/MouseCursorPluginTest.java", "test/io/flutter/plugin/platform/PlatformPluginTest.java", + "test/io/flutter/plugin/platform/PlatformViewsControllerTest.java", "test/io/flutter/plugin/platform/SingleViewPresentationTest.java", "test/io/flutter/plugins/GeneratedPluginRegistrant.java", "test/io/flutter/util/FakeKeyEvent.java", diff --git a/shell/platform/android/io/flutter/embedding/engine/systemchannels/PlatformViewsChannel.java b/shell/platform/android/io/flutter/embedding/engine/systemchannels/PlatformViewsChannel.java index 3f238c98d99a0..19ebe0abe1ac3 100644 --- a/shell/platform/android/io/flutter/embedding/engine/systemchannels/PlatformViewsChannel.java +++ b/shell/platform/android/io/flutter/embedding/engine/systemchannels/PlatformViewsChannel.java @@ -384,7 +384,7 @@ public static class PlatformViewTouch { /** TODO(iskakaushik): javadoc */ public final long motionEventId; - PlatformViewTouch( + public PlatformViewTouch( int viewId, @NonNull Number downTime, @NonNull Number eventTime, diff --git a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java index bb95de64ca592..77b38a60e2096 100644 --- a/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java +++ b/shell/platform/android/io/flutter/plugin/platform/PlatformViewsController.java @@ -254,10 +254,11 @@ public void onTouch(@NonNull PlatformViewsChannel.PlatformViewTouch touch) { final int viewId = touch.viewId; float density = context.getResources().getDisplayMetrics().density; ensureValidAndroidVersion(Build.VERSION_CODES.KITKAT_WATCH); - final MotionEvent event = toMotionEvent(density, touch); if (vdControllers.containsKey(viewId)) { + final MotionEvent event = toMotionEvent(density, touch, true); vdControllers.get(touch.viewId).dispatchTouchEvent(event); } else if (platformViews.get(viewId) != null) { + final MotionEvent event = toMotionEvent(density, touch, false); View view = platformViews.get(touch.viewId); view.dispatchTouchEvent(event); } else { @@ -305,7 +306,9 @@ private void ensureValidAndroidVersion(int minSdkVersion) { } }; - private MotionEvent toMotionEvent(float density, PlatformViewsChannel.PlatformViewTouch touch) { + @VisibleForTesting + public MotionEvent toMotionEvent( + float density, PlatformViewsChannel.PlatformViewTouch touch, boolean usingVirtualDiplays) { MotionEventTracker.MotionEventId motionEventId = MotionEventTracker.MotionEventId.from(touch.motionEventId); MotionEvent trackedEvent = motionEventTracker.pop(motionEventId); @@ -321,11 +324,11 @@ private MotionEvent toMotionEvent(float density, PlatformViewsChannel.PlatformVi parsePointerCoordsList(touch.rawPointerCoords, density) .toArray(new PointerCoords[touch.pointerCount]); - if (trackedEvent != null) { + if (!usingVirtualDiplays && trackedEvent != null) { return MotionEvent.obtain( trackedEvent.getDownTime(), trackedEvent.getEventTime(), - touch.action, // TODO (kaushikiska): https://github.com/flutter/flutter/issues/61169 + trackedEvent.getAction(), touch.pointerCount, pointerProperties, pointerCoords, diff --git a/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewsControllerTest.java b/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewsControllerTest.java index 8b2dfce5fbf06..ff305af208da8 100644 --- a/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewsControllerTest.java +++ b/shell/platform/android/test/io/flutter/plugin/platform/PlatformViewsControllerTest.java @@ -1,12 +1,18 @@ package io.flutter.plugin.platform; +import static io.flutter.embedding.engine.systemchannels.PlatformViewsChannel.PlatformViewTouch; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.mockito.Matchers.eq; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.never; import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; +import android.view.MotionEvent; import android.view.View; +import io.flutter.embedding.android.MotionEventTracker; +import java.util.Collections; import org.junit.Test; import org.junit.runner.RunWith; import org.robolectric.RobolectricTestRunner; @@ -79,4 +85,100 @@ public void itCancelsOldPresentationOnResize() { assertEquals(fakeVdController1.presentation != presentation, true); assertEquals(presentation.isShowing(), false); } + + @Test + public void itUsesActionEventTypeFromFrameworkEventForVirtualDisplays() { + MotionEventTracker motionEventTracker = MotionEventTracker.getInstance(); + PlatformViewsController platformViewsController = new PlatformViewsController(); + + MotionEvent original = + MotionEvent.obtain( + 100, // downTime + 100, // eventTime + 1, // action + 0, // x + 0, // y + 0 // metaState + ); + + // track an event that will later get passed to us from framework + MotionEventTracker.MotionEventId motionEventId = motionEventTracker.track(original); + + PlatformViewTouch frameWorkTouch = + new PlatformViewTouch( + 0, // viewId + original.getDownTime(), + original.getEventTime(), + 2, // action + 0, // pointerCount + Collections.emptyList(), + Collections.emptyList(), + original.getMetaState(), + original.getButtonState(), + original.getXPrecision(), + original.getYPrecision(), + original.getDeviceId(), + original.getEdgeFlags(), + original.getSource(), + original.getFlags(), + motionEventId.getId()); + + MotionEvent resolvedEvent = + platformViewsController.toMotionEvent( + 1, // density + frameWorkTouch, + true // usingVirtualDisplays + ); + + assertEquals(resolvedEvent.getAction(), frameWorkTouch.action); + assertNotEquals(resolvedEvent.getAction(), original.getAction()); + } + + @Test + public void itUsesActionEventTypeFromMotionEventForHybridPlatformViews() { + MotionEventTracker motionEventTracker = MotionEventTracker.getInstance(); + PlatformViewsController platformViewsController = new PlatformViewsController(); + + MotionEvent original = + MotionEvent.obtain( + 100, // downTime + 100, // eventTime + 1, // action + 0, // x + 0, // y + 0 // metaState + ); + + // track an event that will later get passed to us from framework + MotionEventTracker.MotionEventId motionEventId = motionEventTracker.track(original); + + PlatformViewTouch frameWorkTouch = + new PlatformViewTouch( + 0, // viewId + original.getDownTime(), + original.getEventTime(), + 2, // action + 0, // pointerCount + Collections.emptyList(), + Collections.emptyList(), + original.getMetaState(), + original.getButtonState(), + original.getXPrecision(), + original.getYPrecision(), + original.getDeviceId(), + original.getEdgeFlags(), + original.getSource(), + original.getFlags(), + motionEventId.getId()); + + MotionEvent resolvedEvent = + platformViewsController.toMotionEvent( + 1, // density + frameWorkTouch, + false // usingVirtualDisplays + ); + + assertNotEquals(resolvedEvent.getAction(), frameWorkTouch.action); + assertEquals(resolvedEvent.getAction(), original.getAction()); + } }