Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9b83c640 authored by Michal Brzezinski's avatar Michal Brzezinski
Browse files

Unignoring tests and fixing FakeMotionEvent

Solution is to avoid calling finalize() twice on MotionEvent. See code comment for more info

Bug: 351784601
Flag: EXEMPT just test changes
Test: explicitly call finalize() on both objects and see there is no native error
Change-Id: Iea82a50404872abce0827480dcac62587f7c7674
parent 1425d2c2
Loading
Loading
Loading
Loading
+0 −2
Original line number Original line Diff line number Diff line
@@ -29,11 +29,9 @@ import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.filters.SmallTest
import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestCase
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertThat
import org.junit.Ignore
import org.junit.Test
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runner.RunWith


@Ignore
@SmallTest
@SmallTest
@RunWith(AndroidJUnit4::class)
@RunWith(AndroidJUnit4::class)
class BackGestureMonitorTest : SysuiTestCase() {
class BackGestureMonitorTest : SysuiTestCase() {
+28 −6
Original line number Original line Diff line number Diff line
@@ -21,8 +21,11 @@ import android.view.InputDevice.SOURCE_MOUSE
import android.view.MotionEvent
import android.view.MotionEvent
import android.view.MotionEvent.CLASSIFICATION_NONE
import android.view.MotionEvent.CLASSIFICATION_NONE
import android.view.MotionEvent.TOOL_TYPE_FINGER
import android.view.MotionEvent.TOOL_TYPE_FINGER
import java.lang.reflect.Method
import org.mockito.kotlin.doNothing
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.spy
import org.mockito.kotlin.spy
import org.mockito.kotlin.whenever


fun motionEvent(
fun motionEvent(
    action: Int,
    action: Int,
@@ -37,12 +40,31 @@ fun motionEvent(
    val event =
    val event =
        MotionEvent.obtain(/* downTime= */ 0, /* eventTime= */ 0, action, x, y, /* metaState= */ 0)
        MotionEvent.obtain(/* downTime= */ 0, /* eventTime= */ 0, action, x, y, /* metaState= */ 0)
    event.source = source
    event.source = source
    return spy<MotionEvent>(event) {
    val spy =
        spy<MotionEvent>(event) {
            on { getToolType(0) } doReturn toolType
            on { getToolType(0) } doReturn toolType
            on { getPointerCount() } doReturn pointerCount
            on { getPointerCount() } doReturn pointerCount
            axisValues.forEach { (key, value) -> on { getAxisValue(key) } doReturn value }
            axisValues.forEach { (key, value) -> on { getAxisValue(key) } doReturn value }
            on { getClassification() } doReturn classification
            on { getClassification() } doReturn classification
        }
        }
    ensureFinalizeIsNotCalledTwice(spy)
    return spy
}

private fun ensureFinalizeIsNotCalledTwice(spy: MotionEvent) {
    // Spy in mockito will create copy of the spied object, copying all its field etc. Here it means
    // we create copy of MotionEvent and its mNativePtr, so we have two separate objects of type
    // MotionEvents with the same mNativePtr. That breaks because MotionEvent has custom finalize()
    // method which goes to native code and tries to delete the reference from mNativePtr. It works
    // first time but second time reference is already deleted and it breaks. That's why we have to
    // avoid calling finalize twice
    doNothing().whenever(spy).finalizeUsingReflection()
}

private fun MotionEvent.finalizeUsingReflection() {
    val finalizeMethod: Method = MotionEvent::class.java.getDeclaredMethod("finalize")
    finalizeMethod.isAccessible = true
    finalizeMethod.invoke(this)
}
}


fun touchpadEvent(
fun touchpadEvent(
+0 −2
Original line number Original line Diff line number Diff line
@@ -34,11 +34,9 @@ import androidx.test.filters.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.SysuiTestCase
import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGesture.BACK
import com.android.systemui.touchpad.tutorial.ui.gesture.TouchpadGesture.BACK
import com.google.common.truth.Truth.assertThat
import com.google.common.truth.Truth.assertThat
import org.junit.Ignore
import org.junit.Test
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runner.RunWith


@Ignore
@SmallTest
@SmallTest
@RunWith(AndroidJUnit4::class)
@RunWith(AndroidJUnit4::class)
class TouchpadGestureHandlerTest : SysuiTestCase() {
class TouchpadGestureHandlerTest : SysuiTestCase() {