diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaScriptTimerManager.java b/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaScriptTimerManager.java new file mode 100644 index 00000000000..c4d14d8489d --- /dev/null +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaScriptTimerManager.java @@ -0,0 +1,30 @@ +package com.facebook.react.modules.core; + +import com.facebook.react.bridge.WritableArray; + +/** An interface used by {@link JavaTimerManager} to access and call JS timers from Java. */ +public interface JavaScriptTimerManager { + + /** + * Calls the JS callback(s) associated with the timer ID(s). Also unregisters the callback if the + * timer isn't recurring (e.g. unregisters for setTimeout, doesn't for setInterval). + * + * @param timerIDs An array of timer handles to call. Accepts an array as an optimization, to + * avoid unnecessary JNI calls. + */ + void callTimers(WritableArray timerIDs); + + /** + * Invoke the JS callback registered with `requestIdleCallback`. + * + * @param frameTime The amount of time left in the frame, in ms. + */ + void callIdleCallbacks(double frameTime); + + /** + * Shows a warning message in development when environment times are out of sync. + * + * @param warningMessage The message to show + */ + void emitTimeDriftWarning(String warningMessage); +} diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java b/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java index 01799dd138b..09ab3993330 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/core/JavaTimerManager.java @@ -73,7 +73,7 @@ public class JavaTimerManager { } if (mTimersToCall != null) { - mReactApplicationContext.getJSModule(JSTimers.class).callTimers(mTimersToCall); + mJavaScriptTimerManager.callTimers(mTimersToCall); mTimersToCall = null; } @@ -131,9 +131,7 @@ public class JavaTimerManager { } if (sendIdleEvents) { - mReactApplicationContext - .getJSModule(JSTimers.class) - .callIdleCallbacks(absoluteFrameStartTime); + mJavaScriptTimerManager.callIdleCallbacks(absoluteFrameStartTime); } mCurrentIdleCallbackRunnable = null; @@ -145,6 +143,7 @@ public class JavaTimerManager { } private final ReactApplicationContext mReactApplicationContext; + private final JavaScriptTimerManager mJavaScriptTimerManager; private final ReactChoreographer mReactChoreographer; private final DevSupportManager mDevSupportManager; private final Object mTimerGuard = new Object(); @@ -162,9 +161,11 @@ public class JavaTimerManager { public JavaTimerManager( ReactApplicationContext reactContext, + JavaScriptTimerManager javaScriptTimerManager, ReactChoreographer reactChoreographer, DevSupportManager devSupportManager) { mReactApplicationContext = reactContext; + mJavaScriptTimerManager = javaScriptTimerManager; mReactChoreographer = reactChoreographer; mDevSupportManager = devSupportManager; @@ -317,11 +318,9 @@ public class JavaTimerManager { if (mDevSupportManager.getDevSupportEnabled()) { long driftTime = Math.abs(remoteTime - deviceTime); if (driftTime > 60000) { - mReactApplicationContext - .getJSModule(JSTimers.class) - .emitTimeDriftWarning( - "Debugger and device times have drifted by more than 60s. Please correct this by " - + "running adb shell \"date `date +%m%d%H%M%Y.%S`\" on your debugger machine."); + mJavaScriptTimerManager.emitTimeDriftWarning( + "Debugger and device times have drifted by more than 60s. Please correct this by " + + "running adb shell \"date `date +%m%d%H%M%Y.%S`\" on your debugger machine."); } } @@ -330,7 +329,7 @@ public class JavaTimerManager { if (duration == 0 && !repeat) { WritableArray timerToCall = Arguments.createArray(); timerToCall.pushInt(callbackID); - mReactApplicationContext.getJSModule(JSTimers.class).callTimers(timerToCall); + mJavaScriptTimerManager.callTimers(timerToCall); return; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.java index d656eb878d2..f37b840ddfe 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/core/TimingModule.java @@ -10,6 +10,7 @@ import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.ReactApplicationContext; import com.facebook.react.bridge.ReactContextBaseJavaModule; import com.facebook.react.bridge.ReactMethod; +import com.facebook.react.bridge.WritableArray; import com.facebook.react.devsupport.interfaces.DevSupportManager; import com.facebook.react.jstasks.HeadlessJsTaskContext; import com.facebook.react.jstasks.HeadlessJsTaskEventListener; @@ -20,6 +21,23 @@ import com.facebook.react.module.annotations.ReactModule; public final class TimingModule extends ReactContextBaseJavaModule implements LifecycleEventListener, HeadlessJsTaskEventListener { + public class BridgeTimerManager implements JavaScriptTimerManager { + @Override + public void callTimers(WritableArray timerIDs) { + getReactApplicationContext().getJSModule(JSTimers.class).callTimers(timerIDs); + } + + @Override + public void callIdleCallbacks(double frameTime) { + getReactApplicationContext().getJSModule(JSTimers.class).callIdleCallbacks(frameTime); + } + + @Override + public void emitTimeDriftWarning(String warningMessage) { + getReactApplicationContext().getJSModule(JSTimers.class).emitTimeDriftWarning(warningMessage); + } + } + public static final String NAME = "Timing"; private final JavaTimerManager mJavaTimerManager; @@ -28,7 +46,11 @@ public final class TimingModule extends ReactContextBaseJavaModule super(reactContext); mJavaTimerManager = - new JavaTimerManager(reactContext, ReactChoreographer.getInstance(), devSupportManager); + new JavaTimerManager( + reactContext, + new BridgeTimerManager(), + ReactChoreographer.getInstance(), + devSupportManager); } @Override