From 21a434ceec97681574aeedf5e8340f2c58f6f80e Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Mon, 1 Mar 2021 15:46:07 -0800 Subject: [PATCH 001/367] Fix crash associated with setJSResponderHandler Summary: In Fabric we're seeing setJSResponderHandler called during teardown of a surface, which causes a crash because the SurfaceId is no longer available at that point. Guard against setJSResponderHandler being called on a dead surface. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D26734786 fbshipit-source-id: 838d682ee0dd1d4de49993fa479dc2097cf33521 --- .../react/fabric/FabricUIManager.java | 11 +++++-- .../fabric/mounting/MountingManager.java | 29 ++----------------- .../mountitems/PreAllocateViewMountItem.java | 13 +++++++-- 3 files changed, 22 insertions(+), 31 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index ae5a01fcf68fad..11dfbf9c7e8337 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -1079,8 +1079,15 @@ public void setJSResponder( new MountItem() { @Override public void execute(MountingManager mountingManager) { - mountingManager.setJSResponder( - surfaceId, reactTag, initialReactTag, blockNativeResponder); + SurfaceMountingManager surfaceMountingManager = + mountingManager.getSurfaceManager(surfaceId); + if (surfaceMountingManager != null) { + surfaceMountingManager.setJSResponder( + reactTag, initialReactTag, blockNativeResponder); + } else { + FLog.e( + TAG, "setJSResponder skipped, surface no longer available [" + surfaceId + "]"); + } } @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java index b916ff6ffd3bc6..a45742450dc8b8 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/MountingManager.java @@ -270,38 +270,15 @@ public void updateProps(int reactTag, @Nullable ReadableMap props) { getSurfaceManagerForViewEnforced(reactTag).updateProps(reactTag, props); } - /** - * Set the JS responder for the view associated with the tags received as a parameter. - * - *

The JSResponder coordinates the return values of the onInterceptTouch method in Android - * Views. This allows JS to coordinate when a touch should be handled by JS or by the Android - * native views. See {@link JSResponderHandler} for more details. - * - *

This method is going to be executed on the UIThread as soon as it is delivered from JS to - * RN. - * - *

Currently, there is no warranty that the view associated with the react tag exists, because - * this method is not handled by the react commit process. - * - * @param reactTag React tag of the first parent of the view that is NOT virtual - * @param initialReactTag React tag of the JS view that initiated the touch operation - * @param blockNativeResponder If native responder should be blocked or not - */ - @UiThread - public synchronized void setJSResponder( - int surfaceId, int reactTag, int initialReactTag, boolean blockNativeResponder) { - UiThreadUtil.assertOnUiThread(); - - getSurfaceManagerEnforced(surfaceId, "setJSResponder") - .setJSResponder(reactTag, initialReactTag, blockNativeResponder); - } - /** * Clears the JS Responder specified by {@link #setJSResponder(int, int, int, boolean)}. After * this method is called, all the touch events are going to be handled by JS. */ @UiThread public void clearJSResponder() { + // MountingManager and SurfaceMountingManagers all share the same JSResponderHandler. + // Must be called on MountingManager instead of SurfaceMountingManager, because we don't + // know what surfaceId it's being called for. mJSResponderHandler.clearJSResponder(); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java index 7764bd58a3c452..7b540ae89a42d3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/mounting/mountitems/PreAllocateViewMountItem.java @@ -16,6 +16,7 @@ import com.facebook.common.logging.FLog; import com.facebook.react.bridge.ReadableMap; import com.facebook.react.fabric.mounting.MountingManager; +import com.facebook.react.fabric.mounting.SurfaceMountingManager; import com.facebook.react.uimanager.StateWrapper; /** {@link MountItem} that is used to pre-allocate views for JS components. */ @@ -53,9 +54,15 @@ public void execute(@NonNull MountingManager mountingManager) { if (ENABLE_FABRIC_LOGS) { FLog.d(TAG, "Executing pre-allocation of: " + toString()); } - mountingManager - .getSurfaceManagerEnforced(mSurfaceId, "PreAllocateViewMountItem") - .preallocateView(mComponent, mReactTag, mProps, mStateWrapper, mIsLayoutable); + SurfaceMountingManager surfaceMountingManager = mountingManager.getSurfaceManager(mSurfaceId); + if (surfaceMountingManager == null) { + FLog.e( + TAG, + "Skipping View PreAllocation; no SurfaceMountingManager found for [" + mSurfaceId + "]"); + return; + } + surfaceMountingManager.preallocateView( + mComponent, mReactTag, mProps, mStateWrapper, mIsLayoutable); } @Override From 05f687fa88e29554c8da99bba33b07aac83a3a5c Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 1 Mar 2021 17:52:20 -0800 Subject: [PATCH 002/367] Extract getViewportOffset out RootView Summary: This diff moves the method getViewportOffset out of ReactRootView. This is necessary to avoid Fabric to depend from paper. changelog: [internal] internal Reviewed By: JoshuaGross Differential Revision: D26716901 fbshipit-source-id: cec67c24860a776fb361d7cda08d3142e1214c8c --- .../src/main/java/com/facebook/react/BUCK | 1 + .../com/facebook/react/ReactRootView.java | 19 ++----------------- .../main/java/com/facebook/react/fabric/BUCK | 1 - .../com/facebook/react/fabric/Binding.java | 1 + .../react/fabric/FabricUIManager.java | 4 ++-- .../react/uimanager/RootViewUtil.java | 18 ++++++++++++++++++ 6 files changed, 24 insertions(+), 20 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/BUCK b/ReactAndroid/src/main/java/com/facebook/react/BUCK index 6f76ec6ff501fc..6019f3f39f8ac7 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/BUCK @@ -30,6 +30,7 @@ rn_android_library( react_native_target("java/com/facebook/react/common:common"), react_native_target("java/com/facebook/react/devsupport:devsupport"), react_native_target("java/com/facebook/react/devsupport:interfaces"), + react_native_target("java/com/facebook/react/fabric:fabric"), react_native_target("java/com/facebook/react/jscexecutor:jscexecutor"), react_native_target("java/com/facebook/react/jstasks:jstasks"), react_native_target("java/com/facebook/react/module/annotations:annotations"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java index 610dd67bde537f..1efc5fe0890ca3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactRootView.java @@ -27,7 +27,6 @@ import android.view.WindowManager; import android.widget.FrameLayout; import androidx.annotation.Nullable; -import androidx.annotation.UiThread; import com.facebook.common.logging.FLog; import com.facebook.infer.annotation.Assertions; import com.facebook.infer.annotation.ThreadConfined; @@ -52,6 +51,7 @@ import com.facebook.react.uimanager.PixelUtil; import com.facebook.react.uimanager.ReactRoot; import com.facebook.react.uimanager.RootView; +import com.facebook.react.uimanager.RootViewUtil; import com.facebook.react.uimanager.UIManagerHelper; import com.facebook.react.uimanager.common.UIManagerType; import com.facebook.react.uimanager.events.EventDispatcher; @@ -420,21 +420,6 @@ public AtomicInteger getState() { return mState; } - @UiThread - public static Point getViewportOffset(View v) { - int[] locationInWindow = new int[2]; - v.getLocationInWindow(locationInWindow); - - // we need to subtract visibleWindowCoords - to subtract possible window insets, split - // screen or multi window - Rect visibleWindowFrame = new Rect(); - v.getWindowVisibleDisplayFrame(visibleWindowFrame); - locationInWindow[0] -= visibleWindowFrame.left; - locationInWindow[1] -= visibleWindowFrame.top; - - return new Point(locationInWindow[0], locationInWindow[1]); - } - /** * Call whenever measure specs change, or if you want to force an update of offsetX/offsetY. If * measureSpecsChanged is false and the offsetX/offsetY don't change, updateRootLayoutSpecs will @@ -472,7 +457,7 @@ private void updateRootLayoutSpecs( int offsetX = 0; int offsetY = 0; if (getUIManagerType() == FABRIC) { - Point viewportOffset = getViewportOffset(this); + Point viewportOffset = RootViewUtil.getViewportOffset(this); offsetX = viewportOffset.x; offsetY = viewportOffset.y; } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/BUCK b/ReactAndroid/src/main/java/com/facebook/react/fabric/BUCK index f3cb842381849b..12ad6392e594d6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/BUCK @@ -33,7 +33,6 @@ rn_android_library( react_native_target("java/com/facebook/react/bridge:bridge"), react_native_target("java/com/facebook/react/config:config"), react_native_target("java/com/facebook/react/fabric/jni:jni"), - react_native_target("java/com/facebook/react:react"), react_native_target("java/com/facebook/react/module/annotations:annotations"), react_native_target("java/com/facebook/react/modules/core:core"), react_native_target("java/com/facebook/react/modules/i18nmanager:i18nmanager"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/Binding.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/Binding.java index 61296c84a70cbb..9020ab17e775f7 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/Binding.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/Binding.java @@ -91,6 +91,7 @@ public void register( jsMessageQueueThread, componentFactory, reactNativeConfig); + setPixelDensity(PixelUtil.getDisplayMetricDensity()); } diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index 11dfbf9c7e8337..08cd93b133e9f3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -35,7 +35,6 @@ import com.facebook.debug.tags.ReactDebugOverlayTags; import com.facebook.infer.annotation.ThreadConfined; import com.facebook.proguard.annotations.DoNotStrip; -import com.facebook.react.ReactRootView; import com.facebook.react.bridge.LifecycleEventListener; import com.facebook.react.bridge.NativeArray; import com.facebook.react.bridge.NativeMap; @@ -73,6 +72,7 @@ import com.facebook.react.uimanager.PixelUtil; import com.facebook.react.uimanager.ReactRoot; import com.facebook.react.uimanager.ReactRootViewTagGenerator; +import com.facebook.react.uimanager.RootViewUtil; import com.facebook.react.uimanager.StateWrapper; import com.facebook.react.uimanager.ThemedReactContext; import com.facebook.react.uimanager.UIManagerHelper; @@ -252,7 +252,7 @@ public int startSurface( // ViewportOffset during measurement or onLayout. @SuppressLint("WrongThread") Point viewportOffset = - UiThreadUtil.isOnUiThread() ? ReactRootView.getViewportOffset(rootView) : new Point(0, 0); + UiThreadUtil.isOnUiThread() ? RootViewUtil.getViewportOffset(rootView) : new Point(0, 0); mBinding.startSurfaceWithConstraints( rootTag, diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/RootViewUtil.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/RootViewUtil.java index 41bae5be249ae2..2c2e35460b8074 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/RootViewUtil.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/RootViewUtil.java @@ -7,8 +7,11 @@ package com.facebook.react.uimanager; +import android.graphics.Point; +import android.graphics.Rect; import android.view.View; import android.view.ViewParent; +import androidx.annotation.UiThread; import com.facebook.infer.annotation.Assertions; public class RootViewUtil { @@ -28,4 +31,19 @@ public static RootView getRootView(View reactView) { current = (View) next; } } + + @UiThread + public static Point getViewportOffset(View v) { + int[] locationInWindow = new int[2]; + v.getLocationInWindow(locationInWindow); + + // we need to subtract visibleWindowCoords - to subtract possible window insets, split + // screen or multi window + Rect visibleWindowFrame = new Rect(); + v.getWindowVisibleDisplayFrame(visibleWindowFrame); + locationInWindow[0] -= visibleWindowFrame.left; + locationInWindow[1] -= visibleWindowFrame.top; + + return new Point(locationInWindow[0], locationInWindow[1]); + } } From 71ccc61802397a087635e8bfff9d57d9f586dc13 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Mon, 1 Mar 2021 17:52:20 -0800 Subject: [PATCH 003/367] Refactor ReactInstanceManager.getViewManagerNames Summary: This diff refactors the ReactInstanceManager.getViewManagerNames method to cache viewManager names changelog: [internal] internal Reviewed By: JoshuaGross Differential Revision: D26716898 fbshipit-source-id: 93985fe248e7b364081e04dd2b2c6d9b46cb8727 --- .../facebook/react/ReactInstanceManager.java | 51 +++++++++++-------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java index 056880805cec10..cca71a2dccf28c 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/ReactInstanceManager.java @@ -153,6 +153,7 @@ public interface ReactInstanceEventListener { /* accessed from any thread */ private final JavaScriptExecutorFactory mJavaScriptExecutorFactory; + private @Nullable List mViewManagerNames = null; private final @Nullable JSBundleLoader mBundleLoader; private final @Nullable String mJSMainModulePath; /* path to JS bundle root on Metro */ private final List mPackages; @@ -711,6 +712,9 @@ public void destroy() { synchronized (mHasStartedDestroying) { mHasStartedDestroying.notifyAll(); } + synchronized (mPackages) { + mViewManagerNames = null; + } FLog.d(ReactConstants.TAG, "ReactInstanceManager has been destroyed"); } @@ -908,33 +912,38 @@ public List getOrCreateViewManagers( public @Nullable List getViewManagerNames() { Systrace.beginSection(TRACE_TAG_REACT_JAVA_BRIDGE, "ReactInstanceManager.getViewManagerNames"); - ReactApplicationContext context; - synchronized (mReactContextLock) { - context = (ReactApplicationContext) getCurrentReactContext(); - if (context == null || !context.hasActiveCatalystInstance()) { - return null; + if (mViewManagerNames == null) { + ReactApplicationContext context; + synchronized (mReactContextLock) { + context = (ReactApplicationContext) getCurrentReactContext(); + if (context == null || !context.hasActiveCatalystInstance()) { + return null; + } } - } - synchronized (mPackages) { - Set uniqueNames = new HashSet<>(); - for (ReactPackage reactPackage : mPackages) { - SystraceMessage.beginSection( - TRACE_TAG_REACT_JAVA_BRIDGE, "ReactInstanceManager.getViewManagerName") - .arg("Package", reactPackage.getClass().getSimpleName()) - .flush(); - if (reactPackage instanceof ViewManagerOnDemandReactPackage) { - List names = - ((ViewManagerOnDemandReactPackage) reactPackage).getViewManagerNames(context); - if (names != null) { - uniqueNames.addAll(names); + synchronized (mPackages) { + if (mViewManagerNames == null) { + Set uniqueNames = new HashSet<>(); + for (ReactPackage reactPackage : mPackages) { + SystraceMessage.beginSection( + TRACE_TAG_REACT_JAVA_BRIDGE, "ReactInstanceManager.getViewManagerName") + .arg("Package", reactPackage.getClass().getSimpleName()) + .flush(); + if (reactPackage instanceof ViewManagerOnDemandReactPackage) { + List names = + ((ViewManagerOnDemandReactPackage) reactPackage).getViewManagerNames(context); + if (names != null) { + uniqueNames.addAll(names); + } + } + SystraceMessage.endSection(TRACE_TAG_REACT_JAVA_BRIDGE).flush(); } + Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE); + mViewManagerNames = new ArrayList<>(uniqueNames); } - SystraceMessage.endSection(TRACE_TAG_REACT_JAVA_BRIDGE).flush(); } - Systrace.endSection(TRACE_TAG_REACT_JAVA_BRIDGE); - return new ArrayList<>(uniqueNames); } + return new ArrayList<>(mViewManagerNames); } /** Add a listener to be notified of react instance events. */ From 5772c4947d574a1cf3dad9de9c02c7edca68bb3e Mon Sep 17 00:00:00 2001 From: Joshua Gross Date: Mon, 1 Mar 2021 18:10:19 -0800 Subject: [PATCH 004/367] Fix failing CircleCI test for touch event timestamp Summary: Timestamp is computed differently now and uses system millis as the basis for a monotonic clock. Updating this fixes tests. Changelog: [Internal] Reviewed By: RSNara Differential Revision: D26739611 fbshipit-source-id: 4908da68e1c126ea2b0772aaf408d892798549aa --- ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java b/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java index 9696e9a8069a9a..43a4558dd7fb52 100644 --- a/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java +++ b/ReactAndroid/src/test/java/com/facebook/react/RootViewTest.java @@ -115,7 +115,7 @@ public void testTouchEmitter() { rootView.startReactApplication(instanceManager, ""); rootView.simulateAttachForTesting(); - long ts = SystemClock.uptimeMillis(); + long ts = SystemClock.currentTimeMillis(); // Test ACTION_DOWN event rootView.onTouchEvent(MotionEvent.obtain(100, ts, MotionEvent.ACTION_DOWN, 0, 0, 0)); From 3e1d7da9c1e33ef6e238adb071c9a536fc77bccf Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Mon, 1 Mar 2021 20:45:04 -0800 Subject: [PATCH 005/367] Guard .asObject calls with .isObject check in JSIExecutor Summary: When we call JSIExecutor::nativeCallSyncHook, we assume that the third argument is an object and call Value::asObject on it, before checking if the Object is an Array. Calling Value::asObject throws an error if the Value isn't an Object. This diff includes an isObject check on the third argument. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D26735262 fbshipit-source-id: 96eb43d6c8bc1d78f3b5e0dc24ed6d419a446ecf --- ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp b/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp index f490891446060f..f1d4c5170604cf 100644 --- a/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp +++ b/ReactCommon/jsiexecutor/jsireact/JSIExecutor.cpp @@ -439,7 +439,7 @@ Value JSIExecutor::nativeCallSyncHook(const Value *args, size_t count) { throw std::invalid_argument("nativeCallSyncHook arg count must be 3"); } - if (!args[2].asObject(*runtime_).isArray(*runtime_)) { + if (!args[2].isObject() || !args[2].asObject(*runtime_).isArray(*runtime_)) { throw std::invalid_argument( folly::to("method parameters should be array")); } From f9a7d3aaa8a82fe567012037f83879af854a7b7c Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Mon, 1 Mar 2021 20:45:04 -0800 Subject: [PATCH 006/367] Guard .asObject calls with .isObject check in JSINativeModules Summary: Checking if the moduleInfo is null, before calling moduleInfo.asObject isn't sufficient. Before calling moduleInfo.asObject, we should first check if the moduleInfo is an Object. Changelog: [Internal] Reviewed By: fkgozali Differential Revision: D26735367 fbshipit-source-id: b726216857bf23a3c9bab14414bf45b10900e033 --- ReactCommon/jsiexecutor/jsireact/JSINativeModules.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ReactCommon/jsiexecutor/jsireact/JSINativeModules.cpp b/ReactCommon/jsiexecutor/jsireact/JSINativeModules.cpp index e7c56c206a5f26..0bf27d402e9eec 100644 --- a/ReactCommon/jsiexecutor/jsireact/JSINativeModules.cpp +++ b/ReactCommon/jsiexecutor/jsireact/JSINativeModules.cpp @@ -89,6 +89,8 @@ folly::Optional JSINativeModules::createModule( valueFromDynamic(rt, result->config), static_cast(result->index)); CHECK(!moduleInfo.isNull()) << "Module returned from genNativeModule is null"; + CHECK(moduleInfo.isObject()) + << "Module returned from genNativeModule isn't an Object"; folly::Optional module( moduleInfo.asObject(rt).getPropertyAsObject(rt, "module")); From ce8440c77c3e310263894c3ae24e900054a19f34 Mon Sep 17 00:00:00 2001 From: Ramanpreet Nara Date: Tue, 2 Mar 2021 00:12:35 -0800 Subject: [PATCH 007/367] Noop ModuleRegistry::registerModules() when called no modules Summary: In T85279528, we're trying to add a RCTURLRequestHandler to the NativeModule system, when the NativeModule system is in an invalid state. This causes a crash. Longer term, this crash will go away when we delete the legacy NativeModule system. However, in the short term: 1. The parent of this diff (i.e: D26741053) ensures that all RCTURLRequestHandlers are TurboModule-compatible. This makes the modules std::vector passed into ModuleRegistry::resigerModules empty. 2. This diff makes ModuleRegistry::registerModules() noop when the modules std::vector is empty. In tandem, these two diffs should mitigate this crash, by making sure we don't execute the code that crashes. Changelog: [Internal] Reviewed By: mdvacca Differential Revision: D26741417 fbshipit-source-id: fc4a09f6adcbdd6dbe197c9aa6a55af077bd818b --- ReactCommon/cxxreact/ModuleRegistry.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/ReactCommon/cxxreact/ModuleRegistry.cpp b/ReactCommon/cxxreact/ModuleRegistry.cpp index da75bc5b5857f3..741d97073d36b6 100644 --- a/ReactCommon/cxxreact/ModuleRegistry.cpp +++ b/ReactCommon/cxxreact/ModuleRegistry.cpp @@ -48,6 +48,11 @@ void ModuleRegistry::updateModuleNamesFromIndex(size_t index) { void ModuleRegistry::registerModules( std::vector> modules) { SystraceSection s_("ModuleRegistry::registerModules"); + // Noop if there are no NativeModules to add + if (modules.empty()) { + return; + } + if (modules_.empty() && unknownModules_.empty()) { modules_ = std::move(modules); } else { From 62fcb4e22c879e11e090c30b2ee61f4e82ff1180 Mon Sep 17 00:00:00 2001 From: Sam Goldman Date: Tue, 2 Mar 2021 00:24:36 -0800 Subject: [PATCH 008/367] Fixed Flow typing of TextInput refs Summary: `React.ElementRef>` is an inexact object type, which can not be spread into an exact object type, as is happening here. This error is masked in types-first mode, but causes the instance type of this component to be `any`. In a future version of Flow, this issue will be fixed, so this change unblocks upgrading Flow. This change is likely to cause code using `TextInput` refs to find errors which were missed before. Changelog: [General][Fixed] - Fixed Flow typing of TextInput refs Reviewed By: yungsters Differential Revision: D26733314 fbshipit-source-id: 8aa26ce5b49357b279f76dd1767a17a9fb4dd4f1 --- Libraries/Lists/FlatList.js | 2 ++ Libraries/Renderer/shims/ReactNativeTypes.js | 5 ++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/Libraries/Lists/FlatList.js b/Libraries/Lists/FlatList.js index 19012b8c9e581e..540a865d70f1a1 100644 --- a/Libraries/Lists/FlatList.js +++ b/Libraries/Lists/FlatList.js @@ -373,6 +373,8 @@ class FlatList extends React.PureComponent, void> { | ?React.ElementRef | ?React.ElementRef { if (this._listRef) { + /* $FlowFixMe[incompatible-return] Suppresses errors found when fixing + * TextInput typing */ return this._listRef.getScrollRef(); } } diff --git a/Libraries/Renderer/shims/ReactNativeTypes.js b/Libraries/Renderer/shims/ReactNativeTypes.js index 552b118556aaf0..3811bfa35ad91c 100644 --- a/Libraries/Renderer/shims/ReactNativeTypes.js +++ b/Libraries/Renderer/shims/ReactNativeTypes.js @@ -99,7 +99,7 @@ export type PartialViewConfig = $ReadOnly<{ validAttributes?: PartialAttributeConfiguration, }>; -export type NativeMethods = { +export type NativeMethods = {| blur(): void, focus(): void, measure(callback: MeasureOnSuccessCallback): void, @@ -110,8 +110,7 @@ export type NativeMethods = { onFail?: () => void, ): void, setNativeProps(nativeProps: {...}): void, - ... -}; +|}; export type HostComponent = AbstractComponent>; From dec1b6ba15df8f255d30b696a7c08ef543d1d19c Mon Sep 17 00:00:00 2001 From: Lulu Wu Date: Tue, 2 Mar 2021 10:41:20 -0800 Subject: [PATCH 009/367] Test setting layout params to wrap_content for fix text layout bug Summary: Changelog: [Android][Fixed] - Fix layout bug in ReactTextView. Reviewed By: mdvacca Differential Revision: D26752392 fbshipit-source-id: eeb9c16a4165b4d9329534981925621ae51a7dcb --- .../facebook/react/views/text/ReactTextView.java | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java index 85e5cdd62e8954..11dabebc61fb7d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/text/ReactTextView.java @@ -48,6 +48,10 @@ public class ReactTextView extends AppCompatTextView implements ReactCompoundVie private static final ViewGroup.LayoutParams EMPTY_LAYOUT_PARAMS = new ViewGroup.LayoutParams(0, 0); + private static final ViewGroup.LayoutParams WRAP_CONTENT_LAYOUT_PARAMS = + new ViewGroup.LayoutParams( + ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT); + private boolean mContainsImages; private int mDefaultGravityHorizontal; private int mDefaultGravityVertical; @@ -266,12 +270,14 @@ public int compare(Object o1, Object o2) { public void setText(ReactTextUpdate update) { mContainsImages = update.containsImages(); - if (ReactFeatureFlags.enableSettingEmptyLayoutParams) { - // Android's TextView crashes when it tries to relayout if LayoutParams are - // null; explicitly set the LayoutParams to prevent this crash. See: - // https://github.com/facebook/react-native/pull/7011 - if (getLayoutParams() == null) { + // Android's TextView crashes when it tries to relayout if LayoutParams are + // null; explicitly set the LayoutParams to prevent this crash. See: + // https://github.com/facebook/react-native/pull/7011 + if (getLayoutParams() == null) { + if (ReactFeatureFlags.enableSettingEmptyLayoutParams) { setLayoutParams(EMPTY_LAYOUT_PARAMS); + } else { + setLayoutParams(WRAP_CONTENT_LAYOUT_PARAMS); } } Spannable spannable = update.getText(); From caa5abc819bca751ad8a61718d163d63c82b59b4 Mon Sep 17 00:00:00 2001 From: David Vacca Date: Tue, 2 Mar 2021 11:04:17 -0800 Subject: [PATCH 010/367] Remove unnecessary dependency from react buck module Summary: This diff removes an unnecessary dependency from react buck module This was causing a regression in apk size in IG changelog: [internal] internal Reviewed By: JoshuaGross Differential Revision: D26755329 fbshipit-source-id: bc45d9717bb0343cd26ed2ccbaa016b55f56b9bf --- ReactAndroid/src/main/java/com/facebook/react/BUCK | 1 - 1 file changed, 1 deletion(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/BUCK b/ReactAndroid/src/main/java/com/facebook/react/BUCK index 6019f3f39f8ac7..6f76ec6ff501fc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/BUCK @@ -30,7 +30,6 @@ rn_android_library( react_native_target("java/com/facebook/react/common:common"), react_native_target("java/com/facebook/react/devsupport:devsupport"), react_native_target("java/com/facebook/react/devsupport:interfaces"), - react_native_target("java/com/facebook/react/fabric:fabric"), react_native_target("java/com/facebook/react/jscexecutor:jscexecutor"), react_native_target("java/com/facebook/react/jstasks:jstasks"), react_native_target("java/com/facebook/react/module/annotations:annotations"), From cbe7c445f7a065ec7b79717e6f7bd2dfda06f62f Mon Sep 17 00:00:00 2001 From: Andrei Shikov Date: Tue, 2 Mar 2021 13:49:32 -0800 Subject: [PATCH 011/367] Add logging to ReactModalHostView Summary: Changelog: [Internal] Reviewed By: JoshuaGross Differential Revision: D26752344 fbshipit-source-id: 0cc7987e553896144fadcc8ede8f37f74b4b5bc5 --- .../main/java/com/facebook/react/views/modal/BUCK | 1 + .../react/views/modal/ReactModalHostView.java | 15 +++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/modal/BUCK b/ReactAndroid/src/main/java/com/facebook/react/views/modal/BUCK index 73cedfd484bba5..20c442aef6ebee 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/modal/BUCK +++ b/ReactAndroid/src/main/java/com/facebook/react/views/modal/BUCK @@ -17,6 +17,7 @@ rn_android_library( YOGA_TARGET, react_native_dep("third-party/java/infer-annotations:infer-annotations"), react_native_dep("third-party/java/jsr-305:jsr-305"), + react_native_dep("libraries/fbcore/src/main/java/com/facebook/common/logging:logging"), react_native_root_target("Libraries:generated_components_java-FBReactNativeComponentSpec"), react_native_target("java/com/facebook/react/bridge:bridge"), react_native_target("java/com/facebook/react/common:common"), diff --git a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java index db03bfac47ad45..32d04e36b453e2 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java +++ b/ReactAndroid/src/main/java/com/facebook/react/views/modal/ReactModalHostView.java @@ -23,6 +23,7 @@ import android.widget.FrameLayout; import androidx.annotation.Nullable; import androidx.annotation.UiThread; +import com.facebook.common.logging.FLog; import com.facebook.infer.annotation.Assertions; import com.facebook.react.R; import com.facebook.react.bridge.GuardedRunnable; @@ -61,6 +62,8 @@ public class ReactModalHostView extends ViewGroup implements LifecycleEventListener, FabricViewStateManager.HasFabricViewStateManager { + private static final String TAG = "ReactModalHost"; + // This listener is called when the user presses KeyEvent.KEYCODE_BACK // An event is then passed to JS which can either close or not close the Modal by setting the // visible property @@ -244,6 +247,15 @@ protected void showOrUpdate() { // If the existing Dialog is currently up, we may need to redraw it or we may be able to update // the property without having to recreate the dialog if (mDialog != null) { + Context dialogContext = ContextUtils.findContextOfType(mDialog.getContext(), Activity.class); + // TODO(T85755791): remove after investigation + FLog.e( + TAG, + "Updating existing dialog with context: " + + dialogContext + + "@" + + dialogContext.hashCode()); + if (mPropertyRequiresNewDialog) { dismiss(); } else { @@ -269,6 +281,9 @@ protected void showOrUpdate() { WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE, WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE); + // TODO(T85755791): remove after investigation + FLog.e(TAG, "Creating new dialog from context: " + context + "@" + context.hashCode()); + mDialog.setContentView(getContentView()); updateProperties(); From be7f057baccaa98ad40cbf8abe59a387c30ee19b Mon Sep 17 00:00:00 2001 From: Lulu Wu Date: Tue, 2 Mar 2021 16:26:21 -0800 Subject: [PATCH 012/367] Try reduce flackiness of VeniceTest Summary: Simplify addLifecycleEventListener for the flaky test because we just want to test that listener is working. Changelog: [Android][Changed] - Add a spare implementation of addLifecycleEventListener for test purpose. Reviewed By: PeteTheHeat Differential Revision: D26749256 fbshipit-source-id: 5af216e6bfa37a15eb189aa24a3df35a7a7112de --- .../main/java/com/facebook/react/bridge/ReactContext.java | 8 +++++++- .../java/com/facebook/react/fabric/FabricUIManager.java | 4 ++-- .../com/facebook/react/modules/core/TimingModule.java | 2 +- .../react/modules/deviceinfo/DeviceInfoModule.java | 2 +- .../com/facebook/react/uimanager/ThemedReactContext.java | 4 ++-- .../com/facebook/react/uimanager/UIManagerModule.java | 4 ++-- .../react/uimanager/events/EventDispatcherImpl.java | 2 +- 7 files changed, 16 insertions(+), 10 deletions(-) diff --git a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java index 28d024fd4b002b..30d2de3f2f29dc 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java +++ b/ReactAndroid/src/main/java/com/facebook/react/bridge/ReactContext.java @@ -23,6 +23,7 @@ import com.facebook.react.bridge.queue.ReactQueueConfiguration; import com.facebook.react.common.LifecycleState; import com.facebook.react.common.ReactConstants; +import com.facebook.react.common.annotations.VisibleForTesting; import com.facebook.react.config.ReactFeatureFlags; import java.lang.ref.WeakReference; import java.util.concurrent.CopyOnWriteArraySet; @@ -182,9 +183,14 @@ public LifecycleState getLifecycleState() { return mLifecycleState; } + @VisibleForTesting public void addLifecycleEventListener(final LifecycleEventListener listener) { mLifecycleEventListeners.add(listener); - if (hasActiveCatalystInstance() || isBridgeless()) { + } + + public void addLifecycleEventListenerAndCheckState(final LifecycleEventListener listener) { + mLifecycleEventListeners.add(listener); + if (hasActiveCatalystInstance()) { switch (mLifecycleState) { case BEFORE_CREATE: case BEFORE_RESUME: diff --git a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java index 08cd93b133e9f3..e05d0d8c830aa6 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java +++ b/ReactAndroid/src/main/java/com/facebook/react/fabric/FabricUIManager.java @@ -176,7 +176,7 @@ public FabricUIManager( mEventDispatcher = eventDispatcher; mShouldDeallocateEventDispatcher = false; mEventBeatManager = eventBeatManager; - mReactApplicationContext.addLifecycleEventListener(this); + mReactApplicationContext.addLifecycleEventListenerAndCheckState(this); } public FabricUIManager( @@ -189,7 +189,7 @@ public FabricUIManager( mEventDispatcher = new EventDispatcherImpl(reactContext); mShouldDeallocateEventDispatcher = true; mEventBeatManager = eventBeatManager; - mReactApplicationContext.addLifecycleEventListener(this); + mReactApplicationContext.addLifecycleEventListenerAndCheckState(this); } // TODO (T47819352): Rename this to startSurface for consistency with xplat/iOS 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 8ac7f07606a4a0..5abe37b3a5a23f 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 @@ -68,7 +68,7 @@ public TimingModule(ReactApplicationContext reactContext, DevSupportManager devS @Override public void initialize() { - getReactApplicationContext().addLifecycleEventListener(this); + getReactApplicationContext().addLifecycleEventListenerAndCheckState(this); HeadlessJsTaskContext headlessJsTaskContext = HeadlessJsTaskContext.getInstance(getReactApplicationContext()); headlessJsTaskContext.addTaskEventListener(this); diff --git a/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java b/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java index 083c9c1d9f27b1..2de4acce4ef862 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/modules/deviceinfo/DeviceInfoModule.java @@ -37,7 +37,7 @@ public DeviceInfoModule(ReactApplicationContext reactContext) { DisplayMetricsHolder.initDisplayMetricsIfNotInitialized(reactContext); mFontScale = reactContext.getResources().getConfiguration().fontScale; mReactApplicationContext = reactContext; - mReactApplicationContext.addLifecycleEventListener(this); + mReactApplicationContext.addLifecycleEventListenerAndCheckState(this); } public DeviceInfoModule(Context context) { diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ThemedReactContext.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ThemedReactContext.java index 15701d63618a40..2e1493f3f437f3 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/ThemedReactContext.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/ThemedReactContext.java @@ -56,8 +56,8 @@ public ThemedReactContext( } @Override - public void addLifecycleEventListener(LifecycleEventListener listener) { - mReactApplicationContext.addLifecycleEventListener(listener); + public void addLifecycleEventListenerAndCheckState(LifecycleEventListener listener) { + mReactApplicationContext.addLifecycleEventListenerAndCheckState(listener); } @Override diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java index 1d49251377d546..182c04fb84077d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/UIManagerModule.java @@ -158,7 +158,7 @@ public UIManagerModule( mEventDispatcher, minTimeLeftInFrameForNonBatchedOperationMs); - reactContext.addLifecycleEventListener(this); + reactContext.addLifecycleEventListenerAndCheckState(this); } @Deprecated @@ -180,7 +180,7 @@ public UIManagerModule( mEventDispatcher, minTimeLeftInFrameForNonBatchedOperationMs); - reactContext.addLifecycleEventListener(this); + reactContext.addLifecycleEventListenerAndCheckState(this); } /** diff --git a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcherImpl.java b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcherImpl.java index a99d6b1eb31699..8e3ded74b1d13d 100644 --- a/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcherImpl.java +++ b/ReactAndroid/src/main/java/com/facebook/react/uimanager/events/EventDispatcherImpl.java @@ -104,7 +104,7 @@ public int compare(Event lhs, Event rhs) { public EventDispatcherImpl(ReactApplicationContext reactContext) { mReactContext = reactContext; - mReactContext.addLifecycleEventListener(this); + mReactContext.addLifecycleEventListenerAndCheckState(this); mReactEventEmitter = new ReactEventEmitter(mReactContext); } From 6ccd0cdebb2be335eaed93563ec9ed84677f9484 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?H=C3=A9ctor=20Ramos?= Date: Tue, 2 Mar 2021 16:38:23 -0800 Subject: [PATCH 013/367] Bump Android compileSdkVersion and targetSdkVersion to 30 (#31078) Summary: ## Summary Bump Android compileSdkVersion and targetSdkVersion to 30 ## Changelog [Android][Changed] Bump Android compileSdkVersion and targetSdkVersion from 29 to 30 Pull Request resolved: https://github.com/facebook/react-native/pull/31078 Test Plan: Circle CI and Sandcastle Reviewed By: mdvacca Differential Revision: D26765188 Pulled By: hramos fbshipit-source-id: a971641cea4860df58ce6e9b0f14405bfc4e0979 --- .buckconfig | 2 +- .circleci/Dockerfiles/Dockerfile.android | 2 +- .circleci/config.yml | 4 ++-- ReactAndroid/build.gradle | 2 +- package.json | 2 +- template/android/build.gradle | 4 ++-- 6 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.buckconfig b/.buckconfig index 0740647479601e..3d98e74d71e06a 100644 --- a/.buckconfig +++ b/.buckconfig @@ -1,6 +1,6 @@ [android] - target = android-29 + target = android-30 [download] max_number_of_retries = 3 diff --git a/.circleci/Dockerfiles/Dockerfile.android b/.circleci/Dockerfiles/Dockerfile.android index 5b313b53bfa679..92bf645af1d260 100644 --- a/.circleci/Dockerfiles/Dockerfile.android +++ b/.circleci/Dockerfiles/Dockerfile.android @@ -14,7 +14,7 @@ # and build a Android application that can be used to run the # tests specified in the scripts/ directory. # -FROM reactnativecommunity/react-native-android:2.1 +FROM reactnativecommunity/react-native-android:3.2 LABEL Description="React Native Android Test Image" LABEL maintainer="Héctor Ramos " diff --git a/.circleci/config.yml b/.circleci/config.yml index ca3e88fc57bad4..dc1337a2e107e0 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -35,7 +35,7 @@ executors: reactnativeandroid: <<: *defaults docker: - - image: reactnativecommunity/react-native-android:2.1 + - image: reactnativecommunity/react-native-android:3.2 resource_class: "large" environment: - TERM: "dumb" @@ -617,7 +617,7 @@ jobs: environment: - ANDROID_HOME: "C:\\Android\\android-sdk" - ANDROID_NDK: "C:\\Android\\android-sdk\\ndk\\20.1.5948944" - - ANDROID_BUILD_VERSION: 28 + - ANDROID_BUILD_VERSION: 30 - ANDROID_TOOLS_VERSION: 29.0.3 - GRADLE_OPTS: -Dorg.gradle.daemon=false - NDK_VERSION: 20.1.5948944 diff --git a/ReactAndroid/build.gradle b/ReactAndroid/build.gradle index 8b8a05d29e4738..0944a54a9bab74 100644 --- a/ReactAndroid/build.gradle +++ b/ReactAndroid/build.gradle @@ -378,7 +378,7 @@ task extractJNIFiles { } android { - compileSdkVersion 29 + compileSdkVersion 30 ndkVersion ANDROID_NDK_VERSION compileOptions { sourceCompatibility(JavaVersion.VERSION_1_8) diff --git a/package.json b/package.json index b3e149b7080a26..0a415efadd3699 100644 --- a/package.json +++ b/package.json @@ -67,7 +67,7 @@ "prettier": "prettier --write \"./**/*.{js,md,yml}\"", "format-check": "prettier --list-different \"./**/*.{js,md,yml}\"", "update-lock": "npx yarn-deduplicate", - "docker-setup-android": "docker pull reactnativecommunity/react-native-android:2.1", + "docker-setup-android": "docker pull reactnativecommunity/react-native-android:3.2", "docker-build-android": "docker build -t reactnativeci/android -f .circleci/Dockerfiles/Dockerfile.android .", "test-android-run-instrumentation": "docker run --cap-add=SYS_ADMIN -it reactnativeci/android bash .circleci/Dockerfiles/scripts/run-android-docker-instrumentation-tests.sh", "test-android-run-unit": "docker run --cap-add=SYS_ADMIN -it reactnativeci/android bash .circleci/Dockerfiles/scripts/run-android-docker-unit-tests.sh", diff --git a/template/android/build.gradle b/template/android/build.gradle index 93232f5fca9389..ac4d64714c0bfb 100644 --- a/template/android/build.gradle +++ b/template/android/build.gradle @@ -4,8 +4,8 @@ buildscript { ext { buildToolsVersion = "29.0.3" minSdkVersion = 21 - compileSdkVersion = 29 - targetSdkVersion = 29 + compileSdkVersion = 30 + targetSdkVersion = 30 ndkVersion = "20.1.5948944" } repositories { From 397bfa6ad7dff71f4b6d27ac17acc76fe8a6bbb5 Mon Sep 17 00:00:00 2001 From: Nadiia D Date: Tue, 2 Mar 2021 18:01:53 -0800 Subject: [PATCH 014/367] Hide caret during test runs Summary: Changelog: [General][Changed] Hide caret in the TextInput during test runs. Reviewed By: lunaleaps Differential Revision: D26728766 fbshipit-source-id: b75827f00b4d5c6243d93106093f97b40dc4b366 --- Libraries/Components/TextInput/TextInput.js | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Libraries/Components/TextInput/TextInput.js b/Libraries/Components/TextInput/TextInput.js index 39967a67111649..646e7d981a1ecf 100644 --- a/Libraries/Components/TextInput/TextInput.js +++ b/Libraries/Components/TextInput/TextInput.js @@ -1083,6 +1083,13 @@ function InternalTextInput(props: Props): React.Node { ], ); + // Hide caret during test runs due to a flashing caret + // makes screenshot tests flakey + let caretHidden = props.caretHidden; + if (Platform.isTesting) { + caretHidden = true; + } + // TextInput handles onBlur and onFocus events // so omitting onBlur and onFocus pressability handlers here. const {onBlur, onFocus, ...eventHandlers} = usePressability(config) || {}; @@ -1105,6 +1112,7 @@ function InternalTextInput(props: Props): React.Node { {...eventHandlers} accessible={accessible} blurOnSubmit={blurOnSubmit} + caretHidden={caretHidden} dataDetectorTypes={props.dataDetectorTypes} focusable={focusable} mostRecentEventCount={mostRecentEventCount} @@ -1143,6 +1151,7 @@ function InternalTextInput(props: Props): React.Node { accessible={accessible} autoCapitalize={autoCapitalize} blurOnSubmit={blurOnSubmit} + caretHidden={caretHidden} children={children} disableFullscreenUI={props.disableFullscreenUI} focusable={focusable} From ede065c8b06ff7b0fb5fdb659cb85ca01f76bd3c Mon Sep 17 00:00:00 2001 From: Luna Wei Date: Wed, 3 Mar 2021 01:07:45 -0800 Subject: [PATCH 015/367] SectionList example add updateProps to example Summary: # Changelog [General][Added] - Expand example in RNTester for separators on VirtualizedSectionList to showcase updating props on separator ("has not been pressed" -> "has been pressed") Reviewed By: nadiia, kacieb Differential Revision: D26713429 fbshipit-source-id: 21034fab5a80d46c46462c41b0989cc9e4c45d03 --- .../SectionList/SectionListExamples.js | 71 +++++++++++-------- 1 file changed, 40 insertions(+), 31 deletions(-) diff --git a/packages/rn-tester/js/examples/SectionList/SectionListExamples.js b/packages/rn-tester/js/examples/SectionList/SectionListExamples.js index 6eb9eb4c2dc8ea..df68a5209f41fe 100644 --- a/packages/rn-tester/js/examples/SectionList/SectionListExamples.js +++ b/packages/rn-tester/js/examples/SectionList/SectionListExamples.js @@ -46,8 +46,16 @@ const VIEWABILITY_CONFIG = { const Item = ({item, section, separators}) => { return ( { + separators.highlight(); + }} + onPress={() => { + separators.updateProps('trailing', {hasBeenHighlighted: true}); + separators.updateProps('leading', {hasBeenHighlighted: true}); + }} + onPressOut={() => { + separators.unhighlight(); + }} style={({pressed}) => [ styles.item, { @@ -60,7 +68,18 @@ const Item = ({item, section, separators}) => { ); }; -const Separator = (defaultColor, highlightColor, text) => ({highlighted}) => { +const Separator = (defaultColor, highlightColor, isSectionSeparator) => ({ + leadingItem, + trailingItem, + highlighted, + hasBeenHighlighted, +}) => { + const text = `${ + isSectionSeparator ? 'Section ' : '' + }separator for leading ${leadingItem} and trailing ${trailingItem} has ${ + !hasBeenHighlighted ? 'not ' : '' + }been pressed`; + return ( >(); - const onTest = null; - return ( - + ); } @@ -232,7 +240,6 @@ export function SectionList_onViewableItemsChanged(): React.Node { return ( ); @@ -242,7 +249,7 @@ type Props = { exampleProps: $Shape>, onTest?: ?() => void, testLabel?: ?string, - testOutput: ?string, + testOutput?: ?string, }; const SectionListExampleWithForwardedRef = React.forwardRef( @@ -252,18 +259,20 @@ const SectionListExampleWithForwardedRef = React.forwardRef( ): React.Node { return ( - - - {props.testOutput} - - {props.onTest != null ? ( -