Add test for OnTouchModeChangeListener

Add test for OnTouchModeChangeListener and re-enable
testNonFocusedWindowOwnerCannotChangeTouchMode.

Fixes: 218883063
Test: atest TouchModeTest

Change-Id: I5f5296db9fb6bbe04a9918ee104489f35c452362
diff --git a/tests/input/src/android/input/cts/TouchModeTest.kt b/tests/input/src/android/input/cts/TouchModeTest.kt
index efa3122..493e2e0 100644
--- a/tests/input/src/android/input/cts/TouchModeTest.kt
+++ b/tests/input/src/android/input/cts/TouchModeTest.kt
@@ -20,21 +20,26 @@
 import android.app.Instrumentation
 import android.os.SystemClock
 import android.support.test.uiautomator.UiDevice
+import android.view.ViewTreeObserver
 import androidx.test.ext.junit.rules.ActivityScenarioRule
 import androidx.test.ext.junit.runners.AndroidJUnit4
+import androidx.test.filters.MediumTest
 import androidx.test.platform.app.InstrumentationRegistry
 import com.android.compatibility.common.util.PollingCheck
 import com.android.compatibility.common.util.WindowUtil
+import org.junit.Assert.assertEquals
 import org.junit.Assert.assertFalse
 import org.junit.Assert.assertTrue
 import org.junit.Before
-import org.junit.Ignore
 import org.junit.Rule
 import org.junit.Test
 import org.junit.runner.RunWith
+import java.util.concurrent.CountDownLatch
+import java.util.concurrent.TimeUnit
 
-private const val EVENT_PROPAGATION_TIMEOUT_MILLIS: Long = 5000
+private const val TOUCH_MODE_PROPAGATION_TIMEOUT_MILLIS: Long = 5000 // 5 sec
 
+@MediumTest
 @RunWith(AndroidJUnit4::class)
 class TouchModeTest {
     private val instrumentation: Instrumentation = InstrumentationRegistry.getInstrumentation()
@@ -65,15 +70,45 @@
     }
 
     @Test
-    @Ignore("b/218883063")
+    fun testOnTouchModeChangeNotification() {
+        val touchModeChangeListener = OnTouchModeChangeListenerImpl()
+        var observer = activity.window.decorView.rootView.viewTreeObserver
+        observer.addOnTouchModeChangeListener(touchModeChangeListener)
+        val newTouchMode = !isInTouchMode()
+
+        instrumentation.setInTouchMode(newTouchMode)
+        try {
+            assertTrue(touchModeChangeListener.countDownLatch.await(
+                    TOUCH_MODE_PROPAGATION_TIMEOUT_MILLIS, TimeUnit.MILLISECONDS))
+        } catch (e: InterruptedException) {
+            throw RuntimeException(e)
+        }
+
+        assertEquals(newTouchMode, touchModeChangeListener.isInTouchMode)
+    }
+
+    private class OnTouchModeChangeListenerImpl : ViewTreeObserver.OnTouchModeChangeListener {
+        val countDownLatch = CountDownLatch(1)
+        var isInTouchMode = false
+
+        override fun onTouchModeChanged(mode: Boolean) {
+            isInTouchMode = mode
+            countDownLatch.countDown()
+        }
+    }
+
+    @Test
     fun testNonFocusedWindowOwnerCannotChangeTouchMode() {
+        // It takes 400-500 milliseconds in average for DecorView to receive the touch mode changed
+        // event on 2021 hardware, so we set the timeout to 10x that. It's still possible that a
+        // test would fail, but we don't have a better way to check that an event does not occur.
+        // Due to the 2 expected touch mode events to occur, this test may take few seconds to run.
         uiDevice.pressHome()
         PollingCheck.waitFor { !activity.hasWindowFocus() }
+
         instrumentation.setInTouchMode(true)
-        // It takes 400-500 milliseconds for DecorView to receive the touch mode changed event on
-        // 2021 hardware, so we set the timeout to 10x that. It's still possible that a test would
-        // fail, but we don't have a better way to check that an event does not occur.
-        SystemClock.sleep(EVENT_PROPAGATION_TIMEOUT_MILLIS)
+
+        SystemClock.sleep(TOUCH_MODE_PROPAGATION_TIMEOUT_MILLIS)
         assertFalse(isInTouchMode())
     }
 }