mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Move lifecycle listener inside JavaTimerManager (#43338)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/43338 Reafactor JavaTimerManager so more code is shared between bridge and bridgeless. Note that HeadlessJSTaskContext is not currently configured when using bridgeless. Changelog: [Internal] Reviewed By: rshest Differential Revision: D54496604 fbshipit-source-id: 2a61294267df372e69f8316dd8f8059625d0a2bd
This commit is contained in:
committed by
Facebook GitHub Bot
parent
7c5a014c0d
commit
641a9c468f
@@ -3032,7 +3032,7 @@ public abstract interface class com/facebook/react/modules/core/JavaScriptTimerE
|
||||
public abstract fun emitTimeDriftWarning (Ljava/lang/String;)V
|
||||
}
|
||||
|
||||
public class com/facebook/react/modules/core/JavaTimerManager {
|
||||
public class com/facebook/react/modules/core/JavaTimerManager : com/facebook/react/bridge/LifecycleEventListener, com/facebook/react/jstasks/HeadlessJsTaskEventListener {
|
||||
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;Lcom/facebook/react/modules/core/JavaScriptTimerExecutor;Lcom/facebook/react/modules/core/ReactChoreographer;Lcom/facebook/react/devsupport/interfaces/DevSupportManager;)V
|
||||
public fun createAndMaybeCallTimer (IIDZ)V
|
||||
public fun createTimer (IJZ)V
|
||||
@@ -3078,25 +3078,16 @@ public final class com/facebook/react/modules/core/ReactChoreographer$CallbackTy
|
||||
public static fun values ()[Lcom/facebook/react/modules/core/ReactChoreographer$CallbackType;
|
||||
}
|
||||
|
||||
public final class com/facebook/react/modules/core/TimingModule : com/facebook/fbreact/specs/NativeTimingSpec, com/facebook/react/bridge/LifecycleEventListener, com/facebook/react/jstasks/HeadlessJsTaskEventListener {
|
||||
public final class com/facebook/react/modules/core/TimingModule : com/facebook/fbreact/specs/NativeTimingSpec, com/facebook/react/modules/core/JavaScriptTimerExecutor {
|
||||
public fun <init> (Lcom/facebook/react/bridge/ReactApplicationContext;Lcom/facebook/react/devsupport/interfaces/DevSupportManager;)V
|
||||
public fun createTimer (DDDZ)V
|
||||
public fun deleteTimer (D)V
|
||||
public fun initialize ()V
|
||||
public fun invalidate ()V
|
||||
public fun onHeadlessJsTaskFinish (I)V
|
||||
public fun onHeadlessJsTaskStart (I)V
|
||||
public fun onHostDestroy ()V
|
||||
public fun onHostPause ()V
|
||||
public fun onHostResume ()V
|
||||
public fun setSendIdleEvents (Z)V
|
||||
}
|
||||
|
||||
public class com/facebook/react/modules/core/TimingModule$BridgeTimerExecutor : com/facebook/react/modules/core/JavaScriptTimerExecutor {
|
||||
public fun <init> (Lcom/facebook/react/modules/core/TimingModule;)V
|
||||
public fun callIdleCallbacks (D)V
|
||||
public fun callTimers (Lcom/facebook/react/bridge/WritableArray;)V
|
||||
public fun createTimer (DDDZ)V
|
||||
public fun deleteTimer (D)V
|
||||
public fun emitTimeDriftWarning (Ljava/lang/String;)V
|
||||
public fun initialize ()V
|
||||
public fun invalidate ()V
|
||||
public fun setSendIdleEvents (Z)V
|
||||
}
|
||||
|
||||
public class com/facebook/react/modules/debug/DevSettingsModule : com/facebook/fbreact/specs/NativeDevSettingsSpec {
|
||||
|
||||
+12
-1
@@ -12,12 +12,14 @@ import android.view.Choreographer;
|
||||
import androidx.annotation.Nullable;
|
||||
import com.facebook.proguard.annotations.DoNotStrip;
|
||||
import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.UiThreadUtil;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.common.SystemClock;
|
||||
import com.facebook.react.devsupport.interfaces.DevSupportManager;
|
||||
import com.facebook.react.jstasks.HeadlessJsTaskContext;
|
||||
import com.facebook.react.jstasks.HeadlessJsTaskEventListener;
|
||||
import java.util.Comparator;
|
||||
import java.util.PriorityQueue;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
@@ -28,7 +30,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||
*
|
||||
* <p>This is used by the NativeModule {@link TimingModule}.
|
||||
*/
|
||||
public class JavaTimerManager {
|
||||
public class JavaTimerManager implements LifecycleEventListener, HeadlessJsTaskEventListener {
|
||||
|
||||
// These timing constants should be kept in sync with the ones in `JSTimers.js`.
|
||||
// The minimum time in milliseconds left in the frame to call idle callbacks.
|
||||
@@ -196,19 +198,24 @@ public class JavaTimerManager {
|
||||
}
|
||||
});
|
||||
mTimerIdsToTimers = new SparseArray<>();
|
||||
|
||||
mReactApplicationContext.addLifecycleEventListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostPause() {
|
||||
isPaused.set(true);
|
||||
clearFrameCallback();
|
||||
maybeIdleCallback();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostDestroy() {
|
||||
clearFrameCallback();
|
||||
maybeIdleCallback();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostResume() {
|
||||
isPaused.set(false);
|
||||
// TODO(5195192) Investigate possible problems related to restarting all tasks at the same
|
||||
@@ -217,6 +224,7 @@ public class JavaTimerManager {
|
||||
maybeSetChoreographerIdleCallback();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHeadlessJsTaskStart(int taskId) {
|
||||
if (!isRunningTasks.getAndSet(true)) {
|
||||
setChoreographerCallback();
|
||||
@@ -224,6 +232,7 @@ public class JavaTimerManager {
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHeadlessJsTaskFinish(int taskId) {
|
||||
HeadlessJsTaskContext headlessJsTaskContext =
|
||||
HeadlessJsTaskContext.getInstance(mReactApplicationContext);
|
||||
@@ -235,6 +244,8 @@ public class JavaTimerManager {
|
||||
}
|
||||
|
||||
public void onInstanceDestroy() {
|
||||
mReactApplicationContext.removeLifecycleEventListener(this);
|
||||
|
||||
clearFrameCallback();
|
||||
clearChoreographerIdleCallback();
|
||||
}
|
||||
|
||||
+22
-57
@@ -8,49 +8,16 @@
|
||||
package com.facebook.react.modules.core;
|
||||
|
||||
import com.facebook.fbreact.specs.NativeTimingSpec;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
import com.facebook.react.bridge.ReactApplicationContext;
|
||||
import com.facebook.react.bridge.WritableArray;
|
||||
import com.facebook.react.common.annotations.VisibleForTesting;
|
||||
import com.facebook.react.devsupport.interfaces.DevSupportManager;
|
||||
import com.facebook.react.jstasks.HeadlessJsTaskContext;
|
||||
import com.facebook.react.jstasks.HeadlessJsTaskEventListener;
|
||||
import com.facebook.react.module.annotations.ReactModule;
|
||||
|
||||
/** Native module for JS timer execution. Timers fire on frame boundaries. */
|
||||
@ReactModule(name = NativeTimingSpec.NAME)
|
||||
public final class TimingModule extends NativeTimingSpec
|
||||
implements LifecycleEventListener, HeadlessJsTaskEventListener {
|
||||
|
||||
public class BridgeTimerExecutor implements JavaScriptTimerExecutor {
|
||||
@Override
|
||||
public void callTimers(WritableArray timerIDs) {
|
||||
ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn();
|
||||
|
||||
if (reactApplicationContext != null) {
|
||||
reactApplicationContext.getJSModule(JSTimers.class).callTimers(timerIDs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void callIdleCallbacks(double frameTime) {
|
||||
ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn();
|
||||
|
||||
if (reactApplicationContext != null) {
|
||||
reactApplicationContext.getJSModule(JSTimers.class).callIdleCallbacks(frameTime);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void emitTimeDriftWarning(String warningMessage) {
|
||||
ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn();
|
||||
|
||||
if (reactApplicationContext != null) {
|
||||
reactApplicationContext.getJSModule(JSTimers.class).emitTimeDriftWarning(warningMessage);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public final class TimingModule extends NativeTimingSpec implements JavaScriptTimerExecutor {
|
||||
private final JavaTimerManager mJavaTimerManager;
|
||||
|
||||
public TimingModule(ReactApplicationContext reactContext, DevSupportManager devSupportManager) {
|
||||
@@ -58,18 +25,14 @@ public final class TimingModule extends NativeTimingSpec
|
||||
|
||||
mJavaTimerManager =
|
||||
new JavaTimerManager(
|
||||
reactContext,
|
||||
new BridgeTimerExecutor(),
|
||||
ReactChoreographer.getInstance(),
|
||||
devSupportManager);
|
||||
reactContext, this, ReactChoreographer.getInstance(), devSupportManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize() {
|
||||
getReactApplicationContext().addLifecycleEventListener(this);
|
||||
HeadlessJsTaskContext headlessJsTaskContext =
|
||||
HeadlessJsTaskContext.getInstance(getReactApplicationContext());
|
||||
headlessJsTaskContext.addTaskEventListener(this);
|
||||
headlessJsTaskContext.addTaskEventListener(mJavaTimerManager);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -97,28 +60,30 @@ public final class TimingModule extends NativeTimingSpec
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostResume() {
|
||||
mJavaTimerManager.onHostResume();
|
||||
public void callTimers(WritableArray timerIDs) {
|
||||
ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn();
|
||||
|
||||
if (reactApplicationContext != null) {
|
||||
reactApplicationContext.getJSModule(JSTimers.class).callTimers(timerIDs);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostPause() {
|
||||
mJavaTimerManager.onHostPause();
|
||||
public void callIdleCallbacks(double frameTime) {
|
||||
ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn();
|
||||
|
||||
if (reactApplicationContext != null) {
|
||||
reactApplicationContext.getJSModule(JSTimers.class).callIdleCallbacks(frameTime);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostDestroy() {
|
||||
mJavaTimerManager.onHostDestroy();
|
||||
}
|
||||
public void emitTimeDriftWarning(String warningMessage) {
|
||||
ReactApplicationContext reactApplicationContext = getReactApplicationContextIfActiveOrWarn();
|
||||
|
||||
@Override
|
||||
public void onHeadlessJsTaskStart(int taskId) {
|
||||
mJavaTimerManager.onHeadlessJsTaskStart(taskId);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHeadlessJsTaskFinish(int taskId) {
|
||||
mJavaTimerManager.onHeadlessJsTaskFinish(taskId);
|
||||
if (reactApplicationContext != null) {
|
||||
reactApplicationContext.getJSModule(JSTimers.class).emitTimeDriftWarning(warningMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -127,9 +92,9 @@ public final class TimingModule extends NativeTimingSpec
|
||||
|
||||
HeadlessJsTaskContext headlessJsTaskContext =
|
||||
HeadlessJsTaskContext.getInstance(reactApplicationContext);
|
||||
headlessJsTaskContext.removeTaskEventListener(this);
|
||||
headlessJsTaskContext.removeTaskEventListener(mJavaTimerManager);
|
||||
|
||||
mJavaTimerManager.onInstanceDestroy();
|
||||
reactApplicationContext.removeLifecycleEventListener(this);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
|
||||
+2
-19
@@ -21,7 +21,6 @@ import com.facebook.react.bridge.Arguments;
|
||||
import com.facebook.react.bridge.JSBundleLoader;
|
||||
import com.facebook.react.bridge.JSBundleLoaderDelegate;
|
||||
import com.facebook.react.bridge.JavaScriptContextHolder;
|
||||
import com.facebook.react.bridge.LifecycleEventListener;
|
||||
import com.facebook.react.bridge.NativeArray;
|
||||
import com.facebook.react.bridge.NativeMap;
|
||||
import com.facebook.react.bridge.NativeModule;
|
||||
@@ -143,6 +142,7 @@ final class ReactInstance {
|
||||
if (useDevSupport) {
|
||||
devSupportManager.startInspector();
|
||||
}
|
||||
|
||||
JSTimerExecutor jsTimerExecutor = createJSTimerExecutor();
|
||||
mJavaTimerManager =
|
||||
new JavaTimerManager(
|
||||
@@ -151,24 +151,6 @@ final class ReactInstance {
|
||||
ReactChoreographer.getInstance(),
|
||||
devSupportManager);
|
||||
|
||||
mBridgelessReactContext.addLifecycleEventListener(
|
||||
new LifecycleEventListener() {
|
||||
@Override
|
||||
public void onHostResume() {
|
||||
mJavaTimerManager.onHostResume();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostPause() {
|
||||
mJavaTimerManager.onHostPause();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onHostDestroy() {
|
||||
mJavaTimerManager.onHostDestroy();
|
||||
}
|
||||
});
|
||||
|
||||
JSRuntimeFactory jsRuntimeFactory = mDelegate.getJsRuntimeFactory();
|
||||
BindingsInstaller bindingsInstaller = mDelegate.getBindingsInstaller();
|
||||
// Notify JS if profiling is enabled
|
||||
@@ -448,6 +430,7 @@ final class ReactInstance {
|
||||
mQueueConfiguration.destroy();
|
||||
mTurboModuleManager.invalidate();
|
||||
mFabricUIManager.invalidate();
|
||||
mJavaTimerManager.onInstanceDestroy();
|
||||
mHybridData.resetNative();
|
||||
mComponentNameResolverManager = null;
|
||||
mUIConstantsProviderManager = null;
|
||||
|
||||
+79
-62
@@ -7,14 +7,19 @@
|
||||
|
||||
package com.facebook.react.modules.timing
|
||||
|
||||
import android.content.Context
|
||||
import android.view.Choreographer.FrameCallback
|
||||
import com.facebook.react.bridge.Arguments
|
||||
import com.facebook.react.bridge.CatalystInstance
|
||||
import com.facebook.react.bridge.JavaOnlyArray
|
||||
import com.facebook.react.bridge.JavaOnlyMap
|
||||
import com.facebook.react.bridge.ReactApplicationContext
|
||||
import com.facebook.react.bridge.WritableArray
|
||||
import com.facebook.react.common.SystemClock
|
||||
import com.facebook.react.devsupport.interfaces.DevSupportManager
|
||||
import com.facebook.react.jstasks.HeadlessJsTaskConfig
|
||||
import com.facebook.react.jstasks.HeadlessJsTaskContext
|
||||
import com.facebook.react.modules.appregistry.AppRegistry
|
||||
import com.facebook.react.modules.core.JSTimers
|
||||
import com.facebook.react.modules.core.ReactChoreographer
|
||||
import com.facebook.react.modules.core.ReactChoreographer.CallbackType
|
||||
@@ -27,9 +32,12 @@ import org.junit.runner.RunWith
|
||||
import org.mockito.ArgumentMatchers.any
|
||||
import org.mockito.ArgumentMatchers.eq
|
||||
import org.mockito.MockedStatic
|
||||
import org.mockito.Mockito.doAnswer
|
||||
import org.mockito.Mockito.doReturn
|
||||
import org.mockito.Mockito.mock
|
||||
import org.mockito.Mockito.mockStatic
|
||||
import org.mockito.Mockito.reset
|
||||
import org.mockito.Mockito.spy
|
||||
import org.mockito.Mockito.verify
|
||||
import org.mockito.Mockito.verifyNoMoreInteractions
|
||||
import org.mockito.Mockito.`when` as whenever
|
||||
@@ -43,12 +51,14 @@ class TimingModuleTest {
|
||||
const val FRAME_TIME_NS = 17 * 1000 * 1000
|
||||
}
|
||||
|
||||
private lateinit var reactContext: ReactApplicationContext
|
||||
private lateinit var headlessContext: HeadlessJsTaskContext
|
||||
private lateinit var timingModule: TimingModule
|
||||
private lateinit var reactChoreographerMock: ReactChoreographer
|
||||
private lateinit var postFrameCallbackHandler: PostFrameCallbackHandler
|
||||
private lateinit var idlePostFrameCallbackHandler: PostFrameCallbackHandler
|
||||
private var currentTimeNs = 0L
|
||||
private lateinit var jSTimersMock: JSTimers
|
||||
private lateinit var jsTimersMock: JSTimers
|
||||
private lateinit var arguments: MockedStatic<Arguments>
|
||||
private lateinit var systemClock: MockedStatic<SystemClock>
|
||||
private lateinit var reactChoreographer: MockedStatic<ReactChoreographer>
|
||||
@@ -82,9 +92,11 @@ class TimingModuleTest {
|
||||
.thenAnswer { reactChoreographerMock }
|
||||
|
||||
val reactInstance = mock(CatalystInstance::class.java)
|
||||
val reactContext = mock(ReactApplicationContext::class.java)
|
||||
whenever(reactContext.catalystInstance).thenReturn(reactInstance)
|
||||
whenever(reactContext.hasActiveReactInstance()).thenReturn(true)
|
||||
reactContext = spy(ReactApplicationContext(mock(Context::class.java)))
|
||||
doReturn(reactInstance).`when`(reactContext).catalystInstance
|
||||
doReturn(true).`when`(reactContext).hasActiveReactInstance()
|
||||
|
||||
headlessContext = HeadlessJsTaskContext.getInstance(reactContext)
|
||||
|
||||
postFrameCallbackHandler = PostFrameCallbackHandler()
|
||||
idlePostFrameCallbackHandler = PostFrameCallbackHandler()
|
||||
@@ -95,7 +107,6 @@ class TimingModuleTest {
|
||||
.thenAnswer {
|
||||
return@thenAnswer postFrameCallbackHandler.answer(it)
|
||||
}
|
||||
|
||||
whenever(
|
||||
reactChoreographerMock.postFrameCallback(
|
||||
eq(CallbackType.IDLE_EVENT), any(FrameCallback::class.java)))
|
||||
@@ -104,12 +115,17 @@ class TimingModuleTest {
|
||||
}
|
||||
|
||||
timingModule = TimingModule(reactContext, mock(DevSupportManager::class.java))
|
||||
jSTimersMock = mock(JSTimers::class.java)
|
||||
whenever(reactContext.getJSModule(JSTimers::class.java)).thenReturn(jSTimersMock)
|
||||
whenever(reactContext.runOnJSQueueThread(any(Runnable::class.java))).thenAnswer { invocation ->
|
||||
(invocation.arguments[0] as Runnable).run()
|
||||
return@thenAnswer true
|
||||
}
|
||||
jsTimersMock = mock(JSTimers::class.java)
|
||||
doReturn(jsTimersMock).`when`(reactContext).getJSModule(JSTimers::class.java)
|
||||
doReturn(mock(AppRegistry::class.java))
|
||||
.`when`(reactContext)
|
||||
.getJSModule(AppRegistry::class.java)
|
||||
doAnswer({ invocation ->
|
||||
(invocation.arguments[0] as Runnable).run()
|
||||
return@doAnswer true
|
||||
})
|
||||
.`when`(reactContext)
|
||||
.runOnJSQueueThread(any(Runnable::class.java))
|
||||
|
||||
timingModule.initialize()
|
||||
}
|
||||
@@ -134,111 +150,113 @@ class TimingModuleTest {
|
||||
|
||||
@Test
|
||||
fun testSimpleTimer() {
|
||||
timingModule.onHostResume()
|
||||
reactContext.onHostResume(null)
|
||||
timingModule.createTimer(1.0, 1.0, 0.0, false)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(1.0))
|
||||
reset(jSTimersMock)
|
||||
verify(jsTimersMock).callTimers(JavaOnlyArray.of(1.0))
|
||||
reset(jsTimersMock)
|
||||
stepChoreographerFrame()
|
||||
verifyNoMoreInteractions(jSTimersMock)
|
||||
verifyNoMoreInteractions(jsTimersMock)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSimpleRecurringTimer() {
|
||||
timingModule.createTimer(100.0, 1.0, 0.0, true)
|
||||
timingModule.onHostResume()
|
||||
reactContext.onHostResume(null)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(100.0))
|
||||
reset(jSTimersMock)
|
||||
verify(jsTimersMock).callTimers(JavaOnlyArray.of(100.0))
|
||||
reset(jsTimersMock)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(100.0))
|
||||
verify(jsTimersMock).callTimers(JavaOnlyArray.of(100.0))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCancelRecurringTimer() {
|
||||
timingModule.onHostResume()
|
||||
reactContext.onHostResume(null)
|
||||
timingModule.createTimer(105.0, 1.0, 0.0, true)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(105.0))
|
||||
reset(jSTimersMock)
|
||||
verify(jsTimersMock).callTimers(JavaOnlyArray.of(105.0))
|
||||
reset(jsTimersMock)
|
||||
timingModule.deleteTimer(105.0)
|
||||
stepChoreographerFrame()
|
||||
verifyNoMoreInteractions(jSTimersMock)
|
||||
verifyNoMoreInteractions(jsTimersMock)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testPausingAndResuming() {
|
||||
timingModule.onHostResume()
|
||||
reactContext.onHostResume(null)
|
||||
timingModule.createTimer(41.0, 1.0, 0.0, true)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jSTimersMock)
|
||||
timingModule.onHostPause()
|
||||
verify(jsTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jsTimersMock)
|
||||
reactContext.onHostPause()
|
||||
stepChoreographerFrame()
|
||||
verifyNoMoreInteractions(jSTimersMock)
|
||||
reset(jSTimersMock)
|
||||
timingModule.onHostResume()
|
||||
verifyNoMoreInteractions(jsTimersMock)
|
||||
reset(jsTimersMock)
|
||||
reactContext.onHostResume(null)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
verify(jsTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testHeadlessJsTaskInBackground() {
|
||||
timingModule.onHostPause()
|
||||
timingModule.onHeadlessJsTaskStart(42)
|
||||
reactContext.onHostPause()
|
||||
val taskConfig = HeadlessJsTaskConfig("foo", JavaOnlyMap())
|
||||
val taskId = headlessContext.startTask(taskConfig)
|
||||
timingModule.createTimer(41.0, 1.0, 0.0, true)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jSTimersMock)
|
||||
timingModule.onHeadlessJsTaskFinish(42)
|
||||
verify(jsTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jsTimersMock)
|
||||
headlessContext.finishTask(taskId)
|
||||
stepChoreographerFrame()
|
||||
verifyNoMoreInteractions(jSTimersMock)
|
||||
verifyNoMoreInteractions(jsTimersMock)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testHeadlessJsTaskInForeground() {
|
||||
timingModule.onHostResume()
|
||||
timingModule.onHeadlessJsTaskStart(42)
|
||||
val taskConfig = HeadlessJsTaskConfig("foo", JavaOnlyMap())
|
||||
val taskId = headlessContext.startTask(taskConfig)
|
||||
reactContext.onHostResume(null)
|
||||
timingModule.createTimer(41.0, 1.0, 0.0, true)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jSTimersMock)
|
||||
timingModule.onHeadlessJsTaskFinish(42)
|
||||
verify(jsTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jsTimersMock)
|
||||
headlessContext.finishTask(taskId)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jSTimersMock)
|
||||
timingModule.onHostPause()
|
||||
verifyNoMoreInteractions(jSTimersMock)
|
||||
verify(jsTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jsTimersMock)
|
||||
reactContext.onHostPause()
|
||||
verifyNoMoreInteractions(jsTimersMock)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testHeadlessJsTaskIntertwine() {
|
||||
timingModule.onHostResume()
|
||||
timingModule.onHeadlessJsTaskStart(42)
|
||||
timingModule.createTimer(41.0, 1.0, 0.0, true)
|
||||
timingModule.onHostPause()
|
||||
reactContext.onHostPause()
|
||||
val taskConfig = HeadlessJsTaskConfig("foo", JavaOnlyMap())
|
||||
val taskId = headlessContext.startTask(taskConfig)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jSTimersMock)
|
||||
timingModule.onHostResume()
|
||||
timingModule.onHeadlessJsTaskFinish(42)
|
||||
verify(jsTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jsTimersMock)
|
||||
reactContext.onHostResume(null)
|
||||
headlessContext.finishTask(taskId)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jSTimersMock)
|
||||
timingModule.onHostPause()
|
||||
verify(jsTimersMock).callTimers(JavaOnlyArray.of(41.0))
|
||||
reset(jsTimersMock)
|
||||
reactContext.onHostPause()
|
||||
stepChoreographerFrame()
|
||||
verifyNoMoreInteractions(jSTimersMock)
|
||||
verifyNoMoreInteractions(jsTimersMock)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSetTimeoutZero() {
|
||||
timingModule.createTimer(100.0, 0.0, 0.0, false)
|
||||
verify(jSTimersMock).callTimers(JavaOnlyArray.of(100.0))
|
||||
verify(jsTimersMock).callTimers(JavaOnlyArray.of(100.0))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testActiveTimersInRange() {
|
||||
timingModule.onHostResume()
|
||||
reactContext.onHostResume(null)
|
||||
assertThat(timingModule.hasActiveTimersInRange(100)).isFalse
|
||||
timingModule.createTimer(41.0, 1.0, 0.0, true)
|
||||
assertThat(timingModule.hasActiveTimersInRange(100)).isFalse // Repeating
|
||||
@@ -250,13 +268,12 @@ class TimingModuleTest {
|
||||
@Test
|
||||
fun testIdleCallback() {
|
||||
timingModule.setSendIdleEvents(true)
|
||||
timingModule.onHostResume()
|
||||
reactContext.onHostResume(null)
|
||||
stepChoreographerFrame()
|
||||
verify(jSTimersMock).callIdleCallbacks(SystemClock.currentTimeMillis().toDouble())
|
||||
verify(jsTimersMock).callIdleCallbacks(SystemClock.currentTimeMillis().toDouble())
|
||||
}
|
||||
|
||||
private class PostFrameCallbackHandler : Answer<Unit> {
|
||||
|
||||
private var frameCallback: FrameCallback? = null
|
||||
|
||||
override fun answer(invocation: InvocationOnMock) {
|
||||
|
||||
Reference in New Issue
Block a user