Skip to content

Commit

Permalink
Migrate EventDispatcher interface to Kotlin (facebook#48445)
Browse files Browse the repository at this point in the history
Summary:
Pull Request resolved: facebook#48445

# Changelog:
[Internal] -

As in the title.

Differential Revision: D67760373
  • Loading branch information
rshest authored and facebook-github-bot committed Jan 3, 2025
1 parent 6572d75 commit 3613ceb
Show file tree
Hide file tree
Showing 7 changed files with 66 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,10 @@ import com.facebook.common.logging.FLog
* expect an EventDispatcher when the instance doesn't exist.
*/
public class BlackHoleEventDispatcher private constructor() : EventDispatcher {
public override fun dispatchEvent(event: Event<*>) {
public override fun dispatchEvent(event: Event<*>?) {
FLog.d(
"BlackHoleEventDispatcher",
"Trying to emit event to JS, but the React instance isn't ready. Event: ${event.eventName}")
"Trying to emit event to JS, but the React instance isn't ready. Event: ${event?.eventName ?: "null"}")
}

public override fun dispatchAllEvents(): Unit = Unit
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright (c) Meta Platforms, Inc. and affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/

package com.facebook.react.uimanager.events

import com.facebook.react.uimanager.common.UIManagerType

public interface EventDispatcher {
/** Sends the given Event to JS, coalescing eligible events if JS is backed up. */
public fun dispatchEvent(event: Event<*>?)

public fun dispatchAllEvents()

/** Add a listener to this EventDispatcher. */
public fun addListener(listener: EventDispatcherListener)

/** Remove a listener from this EventDispatcher. */
public fun removeListener(listener: EventDispatcherListener)

public fun addBatchEventDispatchedListener(listener: BatchEventDispatchedListener)

public fun removeBatchEventDispatchedListener(listener: BatchEventDispatchedListener)

@Deprecated("Use the modern version with RCTModernEventEmitter")
@Suppress("DEPRECATION")
public fun registerEventEmitter(@UIManagerType uiManagerType: Int, eventEmitter: RCTEventEmitter)

public fun registerEventEmitter(
@UIManagerType uiManagerType: Int,
eventEmitter: RCTModernEventEmitter
)

public fun unregisterEventEmitter(@UIManagerType uiManagerType: Int)

public fun onCatalystInstanceDestroyed()
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import android.util.LongSparseArray;
import android.view.Choreographer;
import androidx.annotation.Nullable;
import com.facebook.infer.annotation.Assertions;
import com.facebook.infer.annotation.Nullsafe;
import com.facebook.react.bridge.LifecycleEventListener;
Expand Down Expand Up @@ -111,7 +112,7 @@ public EventDispatcherImpl(ReactApplicationContext reactContext) {
}

/** Sends the given Event to JS, coalescing eligible events if JS is backed up. */
public void dispatchEvent(Event event) {
public void dispatchEvent(@Nullable Event event) {
Assertions.assertCondition(event.isInitialized(), "Dispatched event hasn't been initialized");

for (EventDispatcherListener listener : mListeners) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,14 @@ import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers
import org.mockito.MockedStatic
import org.mockito.Mockito
import org.mockito.Mockito.*
import org.mockito.Mockito.`when` as whenever
import org.mockito.Mockito.mockStatic
import org.mockito.kotlin.mock
import org.mockito.kotlin.reset
import org.mockito.kotlin.spy
import org.mockito.kotlin.times
import org.mockito.kotlin.verify
import org.mockito.kotlin.verifyNoMoreInteractions
import org.mockito.kotlin.whenever
import org.robolectric.Robolectric
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
Expand All @@ -59,20 +64,20 @@ class RootViewTest {
fun setUp() {
ReactNativeFeatureFlagsForTests.setUp()

arguments = Mockito.mockStatic(Arguments::class.java)
arguments = mockStatic(Arguments::class.java)
arguments.`when`<WritableArray> { Arguments.createArray() }.thenAnswer { JavaOnlyArray() }
arguments.`when`<WritableMap> { Arguments.createMap() }.thenAnswer { JavaOnlyMap() }

val ts = SystemClock.uptimeMillis()
systemClock = Mockito.mockStatic(SystemClock::class.java)
systemClock = mockStatic(SystemClock::class.java)
systemClock.`when`<Long> { SystemClock.uptimeMillis() }.thenReturn(ts)

catalystInstanceMock = ReactTestHelper.createMockCatalystInstance()
reactContext = spy(BridgeReactContext(RuntimeEnvironment.getApplication()))
reactContext.initializeWithInstance(catalystInstanceMock)

DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext)
val uiManagerModuleMock = mock(UIManagerModule::class.java)
val uiManagerModuleMock: UIManagerModule = mock()
whenever(catalystInstanceMock.getNativeModule(UIManagerModule::class.java))
.thenReturn(uiManagerModuleMock)
}
Expand All @@ -85,11 +90,11 @@ class RootViewTest {

@Test
fun testTouchEmitter() {
val instanceManager = mock(ReactInstanceManager::class.java)
val instanceManager: ReactInstanceManager = mock()
whenever(instanceManager.currentReactContext).thenReturn(reactContext)
val uiManager = mock(UIManagerModule::class.java)
val eventDispatcher = mock(EventDispatcher::class.java)
val eventEmitterModuleMock = mock(RCTEventEmitter::class.java)
val uiManager: UIManagerModule = mock()
val eventDispatcher: EventDispatcher = mock()
val eventEmitterModuleMock: RCTEventEmitter = mock()
whenever(catalystInstanceMock.getNativeModule(UIManagerModule::class.java))
.thenReturn(uiManager)
whenever(uiManager.eventDispatcher).thenReturn(eventDispatcher)
Expand Down Expand Up @@ -186,7 +191,7 @@ class RootViewTest {

@Test
fun testRemountApplication() {
val instanceManager = mock(ReactInstanceManager::class.java)
val instanceManager: ReactInstanceManager = mock()
val rootView = ReactRootView(reactContext)
rootView.startReactApplication(instanceManager, "")
rootView.unmountReactApplication()
Expand All @@ -195,7 +200,7 @@ class RootViewTest {

@Test
fun testCheckForKeyboardEvents() {
val instanceManager = mock(ReactInstanceManager::class.java)
val instanceManager: ReactInstanceManager = mock()
val activity = Robolectric.buildActivity(Activity::class.java).create().get()
whenever(instanceManager.currentReactContext).thenReturn(reactContext)
val rootView: ReactRootView =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentMatcher
import org.mockito.Mockito.argThat
import org.mockito.Mockito.mock
import org.mockito.Mockito.verify
import org.mockito.kotlin.argThat
import org.mockito.kotlin.mock
import org.mockito.kotlin.verify
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment

Expand Down Expand Up @@ -75,7 +75,7 @@ class JSPointerDispatcherTest {
val ev =
createMotionEvent(
MotionEvent.ACTION_DOWN, childRect.centerX().toFloat(), childRect.centerY().toFloat())
val mockDispatcher: EventDispatcher = mock(EventDispatcher::class.java)
val mockDispatcher: EventDispatcher = mock()
pointerDispatcher.handleMotionEvent(ev, mockDispatcher, false)
verify(mockDispatcher).dispatchEvent(argThat(EventWithName(PointerEventHelper.POINTER_DOWN)))
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class FakeEventDispatcher : EventDispatcher {
return recordedDispatchedEvents
}

override fun dispatchEvent(event: Event<*>) {
override fun dispatchEvent(event: Event<*>?) {
recordedDispatchedEvents.add(event)
}

Expand Down

0 comments on commit 3613ceb

Please sign in to comment.