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 (#19620)
  • Loading branch information
iskakaushik authored 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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change
@@ -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());
}
}

1 comment on commit 3dc8163

@PingShen
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we found some crash on our 1.17.5 version. how to fix this?
07-13 10:20:32.061 15665 15665 F DEBUG : signal 6 (SIGABRT), code 0 (SI_USER), fault addr --------
07-13 10:20:32.061 15665 15665 F DEBUG : Abort message: 'ubsan: shift-out-of-bounds'
07-13 10:20:32.061 15665 15665 F DEBUG : r0 00000000 r1 000037d0 r2 00000006 r3 00000008
07-13 10:20:32.061 15665 15665 F DEBUG : r4 000037d0 r5 000037d0 r6 ffcb57bc r7 0000010c
07-13 10:20:32.061 15665 15665 F DEBUG : r8 c6e34460 r9 e7b44000 r10 c6e34460 r11 00000000
07-13 10:20:32.061 15665 15665 F DEBUG : ip 00000041 sp ffcb57a8 lr e7c28a6d pc e7c20796
07-13 10:20:32.791 15665 15665 F DEBUG :
07-13 10:20:32.791 15665 15665 F DEBUG : backtrace:
07-13 10:20:32.792 15665 15665 F DEBUG : #00 pc 0001d796 /system/lib/libc.so (abort+58)
07-13 10:20:32.792 15665 15665 F DEBUG : #1 pc 0001e324 /system/lib/libinput.so (abort_with_message(char const*)+24)
07-13 10:20:32.792 15665 15665 F DEBUG : #2 pc 0001e560 /system/lib/libinput.so (__ubsan_handle_shift_out_of_bounds_minimal_abort+24)
07-13 10:20:32.792 15665 15665 F DEBUG : #3 pc 0001c807 /system/lib/libinput.so (android::VelocityTracker::addMovement(android::MotionEvent const*)+666)
07-13 10:20:32.792 15665 15665 F DEBUG : #4 pc 003f005b /system/framework/arm/boot-framework.oat (offset 0x3ef000) (android.app.admin.SecurityLog.readEventsOnWrapping [DEDUPED]+130)
07-13 10:20:32.792 15665 15665 F DEBUG : #05 pc 00195d1b /dev/ashmem/dalvik-jit-code-cache (deleted) (android.view.VelocityTracker.addMovement+58)
07-13 10:20:32.792 15665 15665 F DEBUG : #6 pc 001833a5 /dev/ashmem/dalvik-jit-code-cache (deleted) (android.view.GestureDetector.onTouchEvent+172)
07-13 10:20:32.792 15665 15665 F DEBUG : #7 pc 0018674f /dev/ashmem/dalvik-jit-code-cache (deleted) (com.amap.api.col.n3.ca.a+566)
07-13 10:20:32.792 15665 15665 F DEBUG : #8 pc 00186219 /dev/ashmem/dalvik-jit-code-cache (deleted) (com.amap.api.col.n3.bn.onTouchEvent+1328)
07-13 10:20:32.792 15665 15665 F DEBUG : #9 pc 00192cab /dev/ashmem/dalvik-jit-code-cache (deleted) (com.amap.api.col.n3.bq.onTouchEvent+74)
07-13 10:20:32.792 15665 15665 F DEBUG : #10 pc 00180edb /dev/ashmem/dalvik-jit-code-cache (deleted) (android.view.View.dispatchTouchEvent+602)
07-13 10:20:32.792 15665 15665 F DEBUG : #11 pc 000f6819 /dev/ashmem/dalvik-jit-code-cache (deleted) (android.view.ViewGroup.dispatchTransformedTouchEvent+272)
07-13 10:20:32.792 15665 15665 F DEBUG : #12 pc 000f718d /dev/ashmem/dalvik-jit-code-cache (deleted) (android.view.ViewGroup.dispatchTouchEvent+1908)
07-13 10:20:32.792 15665 15665 F DEBUG : #13 pc 000f6819 /dev/ashmem/dalvik-jit-code-cache (deleted) (android.view.ViewGroup.dispatchTransformedTouchEvent+272)
07-13 10:20:32.792 15665 15665 F DEBUG : #14 pc 000f718d /dev/ashmem/dalvik-jit-code-cache (deleted) (android.view.ViewGroup.dispatchTouchEvent+1908)
07-13 10:20:32.792 15665 15665 F DEBUG : #15 pc 000f6819 /dev/ashmem/dalvik-jit-code-cache (deleted) (android.view.ViewGroup.dispatchTransformedTouchEvent+272)
07-13 10:20:32.792 15665 15665 F DEBUG : #16 pc 000f718d /dev/ashmem/dalvik-jit-code-cache (deleted) (android.view.ViewGroup.dispatchTouchEvent+1908)
07-13 10:20:32.792 15665 15665 F DEBUG : #17 pc 000f6819 /dev/ashmem/dalvik-jit-code-cache (deleted) (android.view.ViewGroup.dispatchTransformedTouchEvent+272)
07-13 10:20:32.792 15665 15665 F DEBUG : #18 pc 000f718d /dev/ashmem/dalvik-jit-code-cache (deleted) (android.view.ViewGroup.dispatchTouchEvent+1908)
07-13 10:20:32.792 15665 15665 F DEBUG : #19 pc 000f6819 /dev/ashmem/dalvik-jit-code-cache (deleted) (android.view.ViewGroup.dispatchTransformedTouchEvent+272)
07-13 10:20:32.792 15665 15665 F DEBUG : #20 pc 000f718d /dev/ashmem/dalvik-jit-code-cache (deleted) (android.view.ViewGroup.dispatchTouchEvent+1908)
07-13 10:20:32.792 15665 15665 F DEBUG : #21 pc 000f6819 /dev/ashmem/dalvik-jit-code-cache (deleted) (android.view.ViewGroup.dispatchTransformedTouchEvent+272)
07-13 10:20:32.792 15665 15665 F DEBUG : #22 pc 000f718d /dev/ashmem/dalvik-jit-code-cache (deleted) (android.view.ViewGroup.dispatchTouchEvent+1908)
07-13 10:20:32.792 15665 15665 F DEBUG : #23 pc 00180b55 /dev/ashmem/dalvik-jit-code-cache (deleted) (io.flutter.plugin.platform.PlatformViewsController$1.onTouch+852)
07-13 10:20:32.792 15665 15665 F DEBUG : #24 pc 000cb251 /dev/ashmem/dalvik-jit-code-cache (deleted) (io.flutter.embedding.engine.systemchannels.PlatformViewsChannel$1.touch+952)
07-13 10:20:32.792 15665 15665 F DEBUG : #25 pc 001826c7 /dev/ashmem/dalvik-jit-code-cache (deleted) (io.flutter.embedding.engine.systemchannels.PlatformViewsChannel$1.onMethodCall+782)
07-13 10:20:32.792 15665 15665 F DEBUG : #26 pc 001182e1 /dev/ashmem/dalvik-jit-code-cache (deleted) (io.flutter.plugin.common.MethodChannel$IncomingMethodCallHandler.onMessage+168)
07-13 10:20:32.792 15665 15665 F DEBUG : #27 pc 0004c981 /dev/ashmem/dalvik-jit-code-cache (deleted) (io.flutter.embedding.engine.dart.DartMessenger.handleMessageFromDart+408)
07-13 10:20:32.792 15665 15665 F DEBUG : #28 pc 001187cb /dev/ashmem/dalvik-jit-code-cache (deleted) (io.flutter.embedding.engine.FlutterJNI.handlePlatformMessage+74)
07-13 10:20:32.792 15665 15665 F DEBUG : #29 pc 0043d975 /system/lib/libart.so (art_quick_invoke_stub_internal+68)
07-13 10:20:32.792 15665 15665 F DEBUG : #30 pc 00410061 /system/lib/libart.so (art_quick_invoke_stub+224)
07-13 10:20:32.792 15665 15665 F DEBUG : #31 pc 000a82ad /system/lib/libart.so (art::ArtMethod::Invoke(art::Thread*, unsigned int*, unsigned int, art::JValue*, char const*)+136)
07-13 10:20:32.792 15665 15665 F DEBUG : #32 pc 0036b4e9 /system/lib/libart.so (art::(anonymous namespace)::InvokeWithArgArray(art::ScopedObjectAccessAlreadyRunnable const&, art::ArtMethod*, art::(anonymous namespace)::ArgArray*, art::JValue*, char const*)+52)
07-13 10:20:32.792 15665 15665 F DEBUG : #33 pc 0036c499 /system/lib/libart.so (art::InvokeVirtualOrInterfaceWithVarArgs(art::ScopedObjectAccessAlreadyRunnable const&, _jobject*, _jmethodID*, std::__va_list)+316)
07-13 10:20:32.792 15665 15665 F DEBUG : #34 pc 00285053 /system/lib/libart.so (art::JNI::CallVoidMethodV(_JNIEnv*, _jobject*, _jmethodID*, std::__va_list)+482)
07-13 10:20:32.792 15665 15665 F DEBUG : #35 pc 00f9f09b /data/app/-Y5fdPE1Wz6S1r-_doYSWDg==/lib/arm/libflutter.so (offset 0xf9a000)
07-13 10:20:32.792 15665 15665 F DEBUG : #36 pc 00f9f055 /data/app/-Y5fdPE1Wz6S1r-_doYSWDg==/lib/arm/libflutter.so (offset 0xf9a000)
07-13 10:20:32.792 15665 15665 F DEBUG : #37 pc 00f9db77 /data/app/-Y5fdPE1Wz6S1r-_doYSWDg==/lib/arm/libflutter.so (offset 0xf9a000)
07-13 10:20:32.792 15665 15665 F DEBUG : #38 pc 00fd1e3b /data/app/-Y5fdPE1Wz6S1r-_doYSWDg==/lib/arm/libflutter.so (offset 0xf9a000)
07-13 10:20:32.792 15665 15665 F DEBUG : #39 pc 00fa95dd /data/app/-Y5fdPE1Wz6S1r-_doYSWDg==/lib/arm/libflutter.so (offset 0xf9a000)
07-13 10:20:32.792 15665 15665 F DEBUG : #40 pc 00facd4f /data/app/-Y5fdPE1Wz6S1r-_doYSWDg==/lib/arm/libflutter.so (offset 0xf9a000)
07-13 10:20:32.792 15665 15665 F DEBUG : #41 pc 0000f3b7 /system/lib/libutils.so (android::Looper::pollInner(int)+726)
07-13 10:20:32.792 15665 15665 F DEBUG : #42 pc 0000f05f /system/lib/libutils.so (android::Looper::pollOnce(int, int*, int*, void**)+26)
07-13 10:20:32.792 15665 15665 F DEBUG : #43 pc 000c0db9 /system/lib/libandroid_runtime.so (android::android_os_MessageQueue_nativePollOnce(_JNIEnv*, _jobject*, long long, int)+26)
07-13 10:20:32.792 15665 15665 F DEBUG : #44 pc 003fc45d /system/framework/arm/boot-framework.oat (offset 0x3ef000) (android.media.MediaExtractor.seekTo [DEDUPED]+92)
07-13 10:20:32.792 15665 15665 F DEBUG : #45 pc 0005181b /dev/ashmem/dalvik-jit-code-cache (deleted) (android.os.MessageQueue.next+194)
07-13 10:20:32.792 15665 15665 F DEBUG : #46 pc 00167a59 /dev/ashmem/dalvik-jit-code-cache (deleted) (android.os.Looper.loop+360)
07-13 10:20:32.793 15665 15665 F DEBUG : #47 pc 0043d9bb /system/lib/libart.so (art_quick_osr_stub+42)
07-13 10:20:32.793 15665 15665 F DEBUG : #48 pc 0025a9c5 /system/lib/libart.so (art::jit::Jit::MaybeDoOnStackReplacement(art::Thread*, art::ArtMethod*, unsigned int, int, art::JValue*)+1472)
07-13 10:20:32.793 15665 15665 F DEBUG : #49 pc 0040f667 /system/lib/libart.so (MterpMaybeDoOnStackReplacement+86)
07-13 10:20:32.793 15665 15665 F DEBUG : #50 pc 0043d174 /system/lib/libart.so (ExecuteMterpImpl+66164)
07-13 10:20:32.793 15665 15665 F DEBUG : #51 pc 00b51512 /system/framework/boot-framework.vdex (android.os.Looper.loop+1036)
07-13 10:20:32.793 15665 15665 F DEBUG : #52 pc 001d3d1f /system/lib/libart.so (_ZN3art11interpreterL7ExecuteEPNS_6ThreadERKNS_20CodeItemDataAccessorERNS_11ShadowFrameENS_6JValueEb.llvm.2251853088+354)
07-13 10:20:32.793 15665 15665 F DEBUG : #53 pc 001d8657 /system/lib/libart.so (art::interpreter::ArtInterpreterToInterpreterBridge(art::Thread*, art::CodeItemDataAccessor const&, art::Shado

Please sign in to comment.