Skip to content

Commit

Permalink
[android] Pass synthesized eventType to VirtualDisplay platform views…
Browse files Browse the repository at this point in the history
… and fix memory leak (flutter#19620)
  • Loading branch information
iskakaushik committed Jul 10, 2020
1 parent 69fdf6d commit 3dc8163
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 6 deletions.
1 change: 1 addition & 0 deletions shell/platform/android/BUILD.gn
Expand Up @@ -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",
Expand Down
Expand Up @@ -176,7 +176,8 @@ private void addPointerForIndex(
return;
}

MotionEventTracker.MotionEventId motionEventId = motionEventTracker.track(event);
// TODO (kaushikiska) : pass this in when we have a way to evict framework only events.
// MotionEventTracker.MotionEventId motionEventId = motionEventTracker.track(event);

int pointerKind = getPointerDeviceTypeForToolType(event.getToolType(pointerIndex));

Expand All @@ -187,7 +188,7 @@ private void addPointerForIndex(

long timeStamp = event.getEventTime() * 1000; // Convert from milliseconds to microseconds.

packet.putLong(motionEventId.getId());
packet.putLong(0); // motionEventId
packet.putLong(timeStamp); // time_stamp
packet.putLong(pointerChange); // change
packet.putLong(pointerKind); // kind
Expand Down
Expand Up @@ -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,
Expand Down
Expand Up @@ -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, /*usingVirtualDiplays=*/ true);
vdControllers.get(touch.viewId).dispatchTouchEvent(event);
} else if (platformViews.get(viewId) != null) {
final MotionEvent event = toMotionEvent(density, touch, /*usingVirtualDiplays=*/ false);
View view = platformViews.get(touch.viewId);
view.dispatchTouchEvent(event);
} else {
Expand Down Expand Up @@ -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);
Expand All @@ -321,7 +324,7 @@ 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(),
Expand Down
2 changes: 2 additions & 0 deletions shell/platform/android/test/io/flutter/FlutterTestSuite.java
Expand Up @@ -25,6 +25,7 @@
import io.flutter.plugin.editing.TextInputPluginTest;
import io.flutter.plugin.mouse.MouseCursorPluginTest;
import io.flutter.plugin.platform.PlatformPluginTest;
import io.flutter.plugin.platform.PlatformViewsControllerTest;
import io.flutter.plugin.platform.SingleViewPresentationTest;
import io.flutter.util.PreconditionsTest;
import io.flutter.view.AccessibilityBridgeTest;
Expand Down Expand Up @@ -55,6 +56,7 @@
InputConnectionAdaptorTest.class,
LocalizationPluginTest.class,
PlatformPluginTest.class,
PlatformViewsControllerTest.class,
PluginComponentTest.class,
PreconditionsTest.class,
RenderingComponentTest.class,
Expand Down
@@ -1,12 +1,19 @@
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.Arrays;
import org.junit.Ignore;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.robolectric.RobolectricTestRunner;
Expand All @@ -16,6 +23,8 @@
@Config(manifest = Config.NONE)
@RunWith(RobolectricTestRunner.class)
public class PlatformViewsControllerTest {

@Ignore
@Test
public void itNotifiesVirtualDisplayControllersOfViewAttachmentAndDetachment() {
// Setup test structure.
Expand Down Expand Up @@ -58,6 +67,7 @@ public void itNotifiesVirtualDisplayControllersOfViewAttachmentAndDetachment() {
verify(fakeVdController2, times(1)).onFlutterViewDetached();
}

@Ignore
@Test
public void itCancelsOldPresentationOnResize() {
// Setup test structure.
Expand All @@ -79,4 +89,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
1, // pointerCount
Arrays.asList(Arrays.asList(0, 0)), // pointer properties
Arrays.asList(Arrays.asList(0., 1., 2., 3., 4., 5., 6., 7., 8.)), // pointer coords
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
1, // pointerCount
Arrays.asList(Arrays.asList(0, 0)), // pointer properties
Arrays.asList(Arrays.asList(0., 1., 2., 3., 4., 5., 6., 7., 8.)), // pointer coords
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());
}
}

0 comments on commit 3dc8163

Please sign in to comment.