Prevent crash in runAnimationStep on OnePlus and Oppo devices (#37487)

Summary:
We've been encountering a crash in `runAnimationStep` with "Calculated frame index should never be lower than 0" https://github.com/facebook/react-native/issues/35766 with OnePlus/Oppo devices as well, but don't have one on hand to test.

This just works around the issue: if the time is before the start time of an animation, we shouldn't do anything anyways, so we just log a message instead of throwing while in production. We still throw in debug mode though for easier debugging.

### Hypothesis of the root cause

Based on stacktrace in https://github.com/facebook/react-native/issues/35766 (which is the same one we see)

Normally, this should happen

1. Choreographer.java constructs a FrameDisplayEventReceiver
2. FrameDisplayEventReceiver.onVSync gets called, which sets the `mTimestampNanos`
3. FrameDisplayEventReceiver.run gets called, which then eventually calls our `doFrame` callback with `mTimestampNanos`. This then causes `FrameBasedAnimationDriver.runAnimationStep` to be called with the same timestamp

I suspect what's happening on OnePlus devices is that the `onVSync` call either doesn't happen or happens rarely enough that the `mTimestampNanos` when `run` is called is sometime in the past

### Fix

1. Add logging so we get the parameters to debug more if we end up getting this error
2. In production, just ignore past times instead of throwing an Error

## Changelog:

Pick one each for the category and type tags:

[ANDROID] [FIXED] - Prevent crash on OnePlus/Oppo devices in runAnimationStep

Pull Request resolved: https://github.com/facebook/react-native/pull/37487

Test Plan: Ran our app using patched version and verified no issues showed up when using it

Reviewed By: cipolleschi

Differential Revision: D46102968

Pulled By: cortinico

fbshipit-source-id: bcb36a0c2aed0afdb8e7e68b141a3db4eb02695a
This commit is contained in:
Harry Yu
2023-05-23 08:15:00 -07:00
committed by Lorenzo Sciandra
parent bad39493b9
commit 51bbfe1c60
@@ -7,9 +7,12 @@
package com.facebook.react.animated;
import com.facebook.common.logging.FLog;
import com.facebook.react.bridge.ReadableArray;
import com.facebook.react.bridge.ReadableMap;
import com.facebook.react.bridge.ReadableType;
import com.facebook.react.common.ReactConstants;
import com.facebook.react.common.build.ReactBuildConfig;
/**
* Implementation of {@link AnimationDriver} which provides a support for simple time-based
@@ -70,7 +73,17 @@ class FrameBasedAnimationDriver extends AnimationDriver {
long timeFromStartMillis = (frameTimeNanos - mStartFrameTimeNanos) / 1000000;
int frameIndex = (int) Math.round(timeFromStartMillis / FRAME_TIME_MILLIS);
if (frameIndex < 0) {
throw new IllegalStateException("Calculated frame index should never be lower than 0");
String message =
"Calculated frame index should never be lower than 0. Called with frameTimeNanos "
+ frameTimeNanos
+ " and mStartFrameTimeNanos "
+ mStartFrameTimeNanos;
if (ReactBuildConfig.DEBUG) {
throw new IllegalStateException(message);
} else {
FLog.w(ReactConstants.TAG, message);
return;
}
} else if (mHasFinished) {
// nothing to do here
return;