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

Commit cd18a1d6 authored by Caitlin Shkuratov's avatar Caitlin Shkuratov
Browse files

Fix ConcurrentModificationException in GenericGestureDetector.

Fixes: 352913191
Flag: EXEMPT bugfix
Test: start ongoing call, then open fullscreen app -> verify status bar
initially appears, but you can swipe up to dismiss it
Test: atest GenericGestureDetectorTest

Change-Id: I09a671c98d68ee256604d35d0f8248439db5903e
parent 5c11f930
Loading
Loading
Loading
Loading
+22 −16
Original line number Diff line number Diff line
@@ -14,7 +14,6 @@
 * limitations under the License.
 */


package com.android.systemui.statusbar.gesture

import android.annotation.CallSuper
@@ -55,20 +54,24 @@ abstract class GenericGestureDetector(
     * The callback receive the last motion event in the gesture.
     */
    fun addOnGestureDetectedCallback(tag: String, callback: (MotionEvent) -> Unit) {
        synchronized(callbacks) {
            val callbacksWasEmpty = callbacks.isEmpty()
            callbacks[tag] = callback
            if (callbacksWasEmpty) {
                startGestureListening()
            }
        }
    }

    /** Removes the callback. */
    fun removeOnGestureDetectedCallback(tag: String) {
        synchronized(callbacks) {
            callbacks.remove(tag)
            if (callbacks.isEmpty()) {
                stopGestureListening()
            }
        }
    }

    /** Triggered each time a touch event occurs (and at least one callback is registered). */
    abstract fun onInputEvent(ev: InputEvent)
@@ -78,7 +81,8 @@ abstract class GenericGestureDetector(
     * event in the gesture.
     */
    internal fun onGestureDetected(e: MotionEvent) {
        callbacks.values.forEach { it.invoke(e) }
        val callbackValues = synchronized(callbacks) { ArrayList(callbacks.values) }
        callbackValues.forEach { it.invoke(e) }
    }

    /** Start listening to touch events. */
@@ -86,11 +90,13 @@ abstract class GenericGestureDetector(
    internal open fun startGestureListening() {
        stopGestureListening()

        inputMonitor = InputMonitorCompat(tag, displayId).also {
            inputReceiver = it.getInputReceiver(
        inputMonitor =
            InputMonitorCompat(tag, displayId).also {
                inputReceiver =
                    it.getInputReceiver(
                        Looper.getMainLooper(),
                        Choreographer.getInstance(),
                this::onInputEvent
                        this::onInputEvent,
                    )
            }
    }