Commit Graph
162 Commits
Author SHA1 Message Date
Andrei ShikovandFacebook GitHub Bot d63bf4add3 Align ReadableMap and MapBuffer measure methods in ViewManager
Summary:
Aligns two codepaths for measure, making sure we can use both MapBuffer and ReadableMap for measuring components.

Changelog: [Internal] - Align measure interface for MapBuffer experiment

Reviewed By: javache, mdvacca

Differential Revision: D34960317

fbshipit-source-id: a39eb84a0abb4414717463f2f1741e470be3531f
2022-03-18 00:36:07 -07:00
Andrei ShikovandFacebook GitHub Bot 28291461a8 Add @DoNotStrip to stop obfuscation of Fabric related classes
Summary:
Proguard seems to keep Fabric methods a bit differently from Redex, with method signature lookup with `MountItem` and `StateWrapperImpl` failing in release RNTester builds because of mangled names. Adding these annotations should keep the classes, ensuring lookup from native is correct.

Changelog: [Internal] - Add DoNotStrip annotations to Fabric related classes

Reviewed By: ryancat

Differential Revision: D34726510

fbshipit-source-id: 0c1d8e1fabec75511942943b533ddd8b637a5e19
2022-03-11 09:16:01 -08:00
Samuel SuslaandFacebook GitHub Bot 664f9b11ba Add option to delay deletion of viewState
Summary:
changelog: [internal]

ViewState is sometimes deleted but not created again because of race condition in C++ pre-allocation and how it checks for revision to determine if createView mount item should be dispatched.

In this diff, we add an option to delay deletion of ViewState until the next commit.

Reviewed By: ShikaSD

Differential Revision: D34553174

fbshipit-source-id: e5213f1d39137fb56fc745321a7c1b28d417ea27
2022-03-03 06:02:02 -08:00
Andrei ShikovandFacebook GitHub Bot cbcdaae2b5 Use mapbuffer for ReactViewGroup
Summary:
Provides an alternative way of diffing props on Android side. Instead of passing dynamic JSON values from JS, the new approach diff C++ props and serializes difference into a `MapBuffer`. Current implementation does this only for `RCTView` component to test performance, correctness and memory impact (as MapBuffers are supposed to be more compact and performant).

This way of passing props allows for additional alignment between platforms, as C++ props are now source of truth for the view state, similar to iOS. At the same time, changing serialization method requires reimplementing `ViewManager` codegen (done manually for now) to account for `MapBuffer`s.

Changelog: [Added][Android] - Added an experimental prop serialization path based on MapBuffer

Reviewed By: mdvacca

Differential Revision: D33735245

fbshipit-source-id: 1515b5fe92f6557ae55abe215ce48277c83974a6
2022-02-22 12:23:49 -08:00
Andrei ShikovandFacebook GitHub Bot ebc856b2de Check if view exists before skipping CREATE command
Summary:
Updates early return in the CREATE command codepath that checks if the view already exists before allocating it. Normally the view state is expected to be created only if the view is preallocated, but empty view state is also created for the flattened nodes when they create an event emitter.

By checking the view existence, we can ensure that view was indeed preallocated before, and skip for optimization purposes.

Changelog: [Internal]

Reviewed By: sammy-SC

Differential Revision: D34050884

fbshipit-source-id: 489fc1052fec9f71712ea729121ac8ef3e3f3d4e
2022-02-08 08:41:35 -08:00
Andres SuarezandFacebook GitHub Bot 8bd3edec88 Update copyright headers from Facebook to Meta
Reviewed By: aaronabramov

Differential Revision: D33367752

fbshipit-source-id: 4ce94d184485e5ee0a62cf67ad2d3ba16e285c8f
2021-12-30 15:11:21 -08:00
Xin ChenandFacebook GitHub Bot bc9168d4ca Add overflowInset to RN Android ViewGroup as separate mount instruction
Summary:
This diff adds `overflowInset` values in RN Android. These values are used to give  an enlarged boundary of a view group that also contains all its children layout. Here is [the post](https://fb.workplace.com/groups/yogalayout/permalink/2264980363573947/) that discuss more on why this is useful. I steal the pic in that post here as TLDR:

{F687030994}

In the above case, we will get overflowInset for ViewGroup A as something like `top: 0, right: -20, bottom: -20, left: 0`.

This has been added in the [Fabric core](https://fburl.com/code/f8c5tg7b) and [in IOS](https://fburl.com/code/vkh0hpt6). In Android, since we used to ignore all event coordinates outside of a ViewGroup boundary, this is not an issue. However, that caused unregistered touch area problem and got fixed in D30104853 (https://github.com/facebook/react-native/commit/e35a963bfb93bbbdd92f4dd74d14e2ad6df5e14a), which dropped the boundary check and made the hit test algorithm in [TouchTargetHelper.java](https://fburl.com/code/dj8jiz22) worse as we now need to explore all the child node under ReactRootNode.

This perf issue is getting obvious when a view loads too many items, which matches our experience with "Hover getting slow after scrolling", "Hover getting slow after going back from PDP view", and "The saved list view (in Explore) is very fast (because it has very few components)"

To fix this issue, I added the support to `overflowInset` to RN Android by
1. Sending the `overflowInset` values from Binding.cpp in RN Android as a separate mount instruction
2. Update `IntBufferBatchMountItem.java` to read the int buffer sent over JNI, and pass the `overflowInset` values to `SurfaceMountingManager.java`
3. Creating new interface `ReactOverflowViewWithInset.java` and extending the existing `ReactOverflowView.java` usages
4. Adding implementation of getter and setter for `overflowInset` in various views
5. Update `TouchTargetHelper.java` to read the values and check boundaries before exploring ViewGroup's children

Note that in #3 I didn't change `ReactOverflowView.java` interface directly. I am concerned about backward compatibility issues in case this interface is being used in OSS. I suggest we deprecate it as we are not using it anymore in our code.

Changelog:
[Internal][Android]

Reviewed By: JoshuaGross

Differential Revision: D33133977

fbshipit-source-id: 64e3e837fe7ca6e6dbdbc836ab0615182e10f28c
2021-12-20 18:43:47 -08:00
Andrei ShikovandFacebook GitHub Bot db21584ba0 Remove soft error when creating preallocated view
Summary:
This is expected with Suspense/CM enabled. We are measuring the perf impact of extra CREATE instructions atm, and will revert the change if it regresses too much.

Changelog:
[Internal]

Reviewed By: sammy-SC

Differential Revision: D32558829

fbshipit-source-id: 2e0c91be3aba4ca632814739aed6b8964e21b5a8
2021-11-19 07:21:32 -08:00
Andrei ShikovandFacebook GitHub Bot f58c496e07 Use context from entry point for prerendering
Summary:
Some of the prerendered surfaces rely on Android context being present to have correct theming (e.g. for platform colors) and measurements of platform components. This change uses context provided to initialize the surface as themed context before view is attached.
This way it is possible to configure theming with `ContextThemeWrapper` the same way as Litho does it for prerendering. The assumption is that any kind of customization done through Android theme will be applied from prerendering entry point as well.

Changelog: [Internal] - Use context from surface for prerendering

Reviewed By: mdvacca

Differential Revision: D31906091

fbshipit-source-id: 344fc96eb2f85ba5b762bee64d1a29443b3fd1d3
2021-10-26 06:00:27 -07:00
Pieter De BaetsandFacebook GitHub Bot cd4bef97d0 Add toString to all MountItem subclasses
Summary:
Useful when Fabric debug logging is enabled

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D31399518

fbshipit-source-id: b5907084604adf1f7093798315147ac63b5876f2
2021-10-06 04:05:00 -07:00
Samuel SuslaandFacebook GitHub Bot dd99475032 Fix view preallocation during cloning
Summary:
changelog: [internal]

This code assured that view preallocation is only triggered if ShadowNode is cloned from revision 0 to revision 1 (first time ShadowNode is cloned).
Node can go from virtual to view forming in subsequent clones, not just the first one. This is more of a case in Concurrent React where the node can be cloned many times before it is first mounted.

Reviewed By: mdvacca

Differential Revision: D31237719

fbshipit-source-id: 13fe6d10fdc815dbdae785d1d9d86d1c8fd36be4
2021-09-29 08:02:22 -07:00
Andrei ShikovandFacebook GitHub Bot 8b4f5073a1 Log created views with mounting errors
Summary:
Displays views from the surface mounting manager after we hit a crash during mounting.
This change should help with debugging mounting crashes (e.g. when view is added before removal)

Changelog: [Internal]

Reviewed By: cortinico

Differential Revision: D30681339

fbshipit-source-id: f83cecaf8e418a2fa5aa0713513c51bb1be77013
2021-09-01 07:31:18 -07:00
Ramanpreet NaraandFacebook GitHub Bot cbec66ef92 Rename ReactSoftException to ReactSoftExceptionLogger
Summary:
ReactSoftException makes it seem like the class is an Exception, when it's actually a logger. This rename I think is more appropriate.

Changelog: [Internal]

Reviewed By: JoshuaGross

Differential Revision: D30251735

fbshipit-source-id: 550bd543388e698774ec31753200bd3f722d8c17
2021-08-11 13:29:42 -07:00
Pieter De BaetsandFacebook GitHub Bot de255528e0 Allow resolving view from FabricUIManager
Summary: Changelog: [Internal]

Reviewed By: JoshuaGross

Differential Revision: D30043188

fbshipit-source-id: d8675754b29fb58a28a06777f602098da6dbc27f
2021-08-03 10:55:47 -07:00
Samuel SuslaandFacebook GitHub Bot 3ed3d34987 Correct error message in getViewState method
Summary:
Changelog: [internal]

Here, getting `viewState` has failed, not its view property.

Reviewed By: mdvacca

Differential Revision: D30042652

fbshipit-source-id: 42831b577f17db1f64860e68be33870f5be27207
2021-08-02 09:36:33 -07:00
Joshua GrossandFacebook GitHub Bot 41ecccefcf Immediately destroy EventEmitterWrapper on update instead of waiting for GC
Summary:
Immediately destroy EventEmitterWrapper on update instead of waiting for Java GC. This can resolve JSI::~Pointer deallocation crashes by clearing out EventEmitter and therefore EventTarget sooner, before RN teardown.

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D29415386

fbshipit-source-id: 05517bfd9e2cc2bd1b8c58d4f84c84f6f547268a
2021-06-26 12:21:16 -07:00
Joshua GrossandFacebook GitHub Bot 006f5afe12 Guard against unsafe EventEmitter setup and teardown
Summary:
Because of T92179998, T93607943, and T93394807, we are still seeking resolution to tricky crashes wrt the use of EventEmitters.

I believe the recent spike is because of two recent changes: we pass in EventEmitters earlier, during PreAllocation; and we clean them up earlier, during stopSurface, to avoid jsi::~Pointer crashes.

Additionally, the gating previously added around the PreAllocation path was incorrect and led to more nullptrs being passed around as EventEmitters.

To mitigate these issues:

1) I am adding/fixing gating to preallocation and early cleanup paths
2) I am making EventEmitterWrapper more resilient by ensuring EventEmitter is non-null before invoking it.
3) I am making sure that in more cases, we pass a non-null EventEmitter pointer to Java.
4) I am backing out the synchronization in EventEmitterWrapper (java side) as that did not resolve the issue and is a pessimisation

There are older, unchanged paths that could still be passing in nullptr as the EventEmitter (Update and Create). As those have not changed recently, I'm not going to fix those cases and instead, we can now rely on the caller to ensure that the EventEmitter is non-null before calling.

Changelog: [internal]

Differential Revision: D29252806

fbshipit-source-id: 5c68d95fa2465afe45e0083a0685c8c1abf31619
2021-06-19 22:57:12 -07:00
Joshua GrossandFacebook GitHub Bot 225ff72d2d Temporary mitigation for T93398735 crash: swallow PreAllocate crashes
Summary:
Because of the "disable preallocation of virtual views" experiment, for some reason, some views are being preallocated multiple times instead of not being preallocated at all.

This isn't really a problem for CreateView, and Preallocate is actually more strict here than it needs to be. I'm going to downgrade this to a soft error and will continue to analyze more. This is more of a perf issue than a correctness issue, so this should be fine.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D29206416

fbshipit-source-id: 9490a1a705c2b39def3a3e56086634439543515e
2021-06-17 17:28:32 -07:00
Andrei ShikovandFacebook GitHub Bot a7adaf3062 Retry mounting items that were scheduled on view attach
Summary:
The mount items executed before the view attach can fail with the RetryableMountingLayerException, which we should either retry or skip the item. This change updates logic for such items to catch these exceptions.

Instead of passing `MountingManager` to execute the items, this change now passes a reference to the `MountItemDispatcher` (abstracted through interface to resolve cycle between the manager and dispatcher). The dispatcher executes the queue directly and schedules retry together with the next batch.

Changelog: [Internal]

Reviewed By: JoshuaGross

Differential Revision: D29068063

fbshipit-source-id: 04030b21db188d5617c3448322d25ba77d5fbb9f
2021-06-15 05:45:57 -07:00
Joshua GrossandFacebook GitHub Bot 883f4651bc Remove unused field
Summary:
This field doesn't serve a purpose anymore.

Changelog: [Internal]

Reviewed By: PeteTheHeat

Differential Revision: D29118454

fbshipit-source-id: b755a761eb7e9854d48c99dfedaf2e871f29d7f7
2021-06-14 19:44:09 -07:00
Joshua GrossandFacebook GitHub Bot 25e8fbe8ff Ensure that EventEmitterWrapper is cleaned up as soon as a View is deleted
Summary:
In T92179998, there is a crash when an EventEmitterWrapper is deallocated after the JS VM is torn down, and the EventEmitterWrapper tries to free its JSI::Pointer reference (double-free).

To make sure this happens less/not at all, free EventEmitterWrappers on ViewState when a view is deleted, instead of waiting for all of RN to be torn down.

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D29020768

fbshipit-source-id: 9d72a23bc9966992ef56c1e3ee523405d4333194
2021-06-09 23:48:04 -07:00
Joshua GrossandFacebook GitHub Bot ac6d1982f4 Re-land: Pass in EventEmitter during View CREATE and Preallocation
Summary:
This is a re-land of D28810022 (https://github.com/facebook/react-native/commit/7e9c741146e1b3aa542ecfe138765e95ddddac3f), which was reverted due to T92179998. The fix is in D28938530. This issue could also be resolved by preventing more view preallocations (D28811419 (https://github.com/facebook/react-native/commit/8ca18f0b602a08cd9a5c9f6681bb5dc74e0d34f7)).

 ---

EventEmitter is not transmitted from C++ to Java until an UPDATE operation is enqueued.

Practically this usually happens "right away", but in the case of an Image component, especially, the EventEmitter could be missing while events are being fired from the native side (for example, loading events).

The fix is just to pass EventEmitter in sooner, in both Create and Preallocate. There should be no ill effect since EventEmitter is nullable anyway.

One potential side-effect: since Views can be PreAllocated and potentially never deallocated until StopSurface is called, this could result in more EventEmitter objects being leaked and retained from Java. I believe the fix is to remove PreAllocated Views more aggressively.

Changelog: [Internal]

Reviewed By: sammy-SC

Differential Revision: D28938637

fbshipit-source-id: c9e290a24ed15c28881e3eead4a5f580f66b288f
2021-06-07 12:16:12 -07:00
Joshua GrossandFacebook GitHub Bot 792acff149 Clean up EventEmitterWrapper on surface deallocation
Summary:
clean up EventEmitterWrapper on surface deallocation. Will resolve T92179998.

Changelog: [Internal]

Reviewed By: sammy-SC

Differential Revision: D28938530

fbshipit-source-id: f718945f52a652a4b79a7a376f052035e4f41edb
2021-06-07 12:16:12 -07:00
Joshua GrossandFacebook GitHub Bot e15f171080 Back out "Pass in EventEmitter during View CREATE and Preallocation"
Summary:
Original commit changeset: ae4c8b4eefe6

Reverting temporarily to resolve T92179998.

Changelog: [Internal]

Reviewed By: fkgozali, sammy-SC

Differential Revision: D28938467

fbshipit-source-id: a855c8f08f4826e0bb4b918f2dd3269f200787f5
2021-06-07 12:16:12 -07:00
Joshua GrossandFacebook GitHub Bot 7e9c741146 Pass in EventEmitter during View CREATE and Preallocation
Summary:
EventEmitter is not transmitted from C++ to Java until an UPDATE operation is enqueued. Practically this usually happens "right away", but in the case of an Image component, especially, the EventEmitter could be missing while events are being fired from the native side (for example, loading events).

The fix is just to pass EventEmitter in sooner, in both Create and Preallocate. There should be no ill effect since EventEmitter is nullable anyway.

One potential side-effect: since Views can be PreAllocated and potentially never deallocated until StopSurface is called, this could result in more EventEmitter objects being leaked and retained from Java. I believe the fix is to remove PreAllocated Views more aggressively.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D28810022

fbshipit-source-id: ae4c8b4eefe619d9a99fa5f90f612d6dd4880da5
2021-06-01 15:15:47 -07:00
Andrei ShikovandFacebook GitHub Bot 712bc6769b Log when item execution is delayed during mounting
Summary:
Adds logs to indicate that MountItem was queued instead of executed.
Also moves logging of preMount items to dispatcher for consistent logging with other items.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D28690203

fbshipit-source-id: 14d24f0bebb97a810127f5187b4d46f66b6c836f
2021-05-27 04:44:30 -07:00
Joshua GrossandFacebook GitHub Bot 3c7809ed0d Call onDropViewInstance on all Views when stopSurface is called
Summary:
Call `onDropViewInstance` on all Views when stopSurface is called.

We used to do this but stopped doing it ~6 months ago. This did not cause any prod issues but is not correct.

This allows product code to do cleanup upon view deletion.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D28388929

fbshipit-source-id: a8f06d4b1b12a11a907667e0a837c653db035941
2021-05-12 14:05:56 -07:00
David VaccaandFacebook GitHub Bot 3555bf20a8 Update javadoc in fabric to remove reference to UIManagerModule
Summary:
Update javadoc in fabric to remove reference to UIManagerModule

changelog: [internal] internal

Reviewed By: fkgozali

Differential Revision: D28207024

fbshipit-source-id: 1658c01b10c2433565d6df1a6ed989d83a3c4a8d
2021-05-05 09:12:41 -07:00
Andrei ShikovandFacebook GitHub Bot 6fda118116 Show surfaceId when logging IntBufferBatchMountItem
Summary:
Adds surface id for string logs of the IntBufferBatchMountItem to help debug updates with multiple surfaces.

Changelog: [Internal]

Reviewed By: JoshuaGross

Differential Revision: D27884232

fbshipit-source-id: c5ec65585830f7aa5b902603bcd1e91b61cfe4c1
2021-04-21 10:32:18 -07:00
Andrei ShikovandFacebook GitHub Bot d97350dcbc Queue mount items executed before root view is attached
Summary:
Changelog: [Internal]

After D27016919, some mounting instructions can be executed before the view is attached, which is invalid. This change adds additional queue for such items, which can be later dispatched after view is ready.

The new queue is expected to be empty for usual rendering and used in prerendering flows only. In case of prerendering, it should only hold intermediate items between early start of `SurfaceHandler` and view attach.

Reviewed By: mdvacca

Differential Revision: D27291706

fbshipit-source-id: f383c1d0d7050f271993553b51bf2e387efe1e9e
2021-04-06 11:19:57 -07:00
Andrei ShikovandFacebook GitHub Bot 2c0a0a7c25 Allow starting surface without a view in Fabric
Summary:
Changelog: [Internal]

Adjusts SurfaceMountingManager to allow starting surface without a view and attaching the view while surface is active.
This change is only meant to work with ReactSurface to allow creating `SurfaceHandler` without mounting views.

Reviewed By: mdvacca

Differential Revision: D27016919

fbshipit-source-id: 995383bc4f1bd298953516007743ffae0edf17c2
2021-04-06 11:19:57 -07:00
Andrei ShikovandFacebook GitHub Bot 35b575fefd Refactor mount logic into MountItemDispatcher
Summary:
Changelog: [Internal]

FabricUIManager contains a lot of logic related to mounting items and manipulating dispatch queues, which can be safely extracted outside. Apart from decreased logical complexity, this change enables easier modification of the queuing behavior later in this stack.

Majority of the changes is caused by moving existing logic to a different class, no change in behavior expected.

Reviewed By: JoshuaGross

Differential Revision: D27271116

fbshipit-source-id: 86fe45b19bb839f96fde8ba607f72006f6401cc7
2021-03-24 13:55:46 -07:00
David VaccaandFacebook GitHub Bot 91b3f5d48a Implement and integrate Mapbuffer
Summary:
This diff contains the code from the 35 diff stack  - D27210587

This diff implement and integrates Mapbuffer into Fabric text measure system

changelog: [internal] internal

Reviewed By: JoshuaGross

Differential Revision: D27241836

fbshipit-source-id: f40a780df0723f27da440f709a8676cfcca63953
2021-03-24 03:52:31 -07:00
Joshua GrossandFacebook GitHub Bot b84ae3875c Immediately destroy C++ state when deleteView is processed
Summary:
Followup to D26858584 (https://github.com/facebook/react-native/commit/00959ffd6b9aebf52ca51ce7a747a375b5a8cdd1). We should also immediately destroy C++ state memory (which will decrement a shared_ptr) when deleting a view.

This could improve memory while a surface is being used.

Changelog: [Internal]

Reviewed By: fkgozali

Differential Revision: D26876537

fbshipit-source-id: fc8353bed47db8fdbf5c7f6c6253ac788c460d9a
2021-03-07 13:19:50 -08:00
Joshua GrossandFacebook GitHub Bot 00959ffd6b Destroy Fabric State objects earlier in Java
Summary:
There are races between BackgroundExecutor and Fabric/View teardown, where, because of the way things are set up currently, a View will strongly retain a pointer into some native State object which can keep a host of other objects alive in C++, even after stopSurface, and even after RN itself starts tearing down.

To alleviate this, we more aggressively clear State from Java, without waiting for Java GC: 1) on stopSurface, 2) whenever a State object is stale from Java's perspective.

This should allow us to keep all common updateState semantics, while only introducing a new edge-case that stateWrapper can be destroyed during mounting if stopSurface happens at the same time. In those cases, checking for NPEs should be sufficient.

The possible race condition only really happens with updateState, so it's easier to check for. There should practically be no cases where there's a race between `stopSurface` and `getState`, because `getState` is only really called around state updates and view preallocation, and never after; we still check for NPEs in those cases, but it shouldn't be an issue.

Changelog: [Internal]

Reviewed By: thurn, sammy-SC, mdvacca

Differential Revision: D26858584

fbshipit-source-id: 2ef7467220865380037d69d8de322fe8797f6a12
2021-03-05 18:42:39 -08:00
Joshua GrossandFacebook GitHub Bot a65cd683ae Align View creation flow between Fabric and non-Fabric
Summary:
Ship responsibility for most View creation logic to ViewManager, where it already largely lies, and simplify code in Fabric and non-Fabric mounting layers.

Notably, some of this work was *already* being duplicated so we can expect an extremely tiny perf gain here.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D26742711

fbshipit-source-id: 4213766d4cd366bc69cd47d4654f7b269bb9e7f4
2021-03-04 22:22:34 -08:00
Joshua GrossandFacebook GitHub Bot 21a434ceec 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
2021-03-01 15:48:38 -08:00
Joshua GrossandFacebook GitHub Bot f8261bbe51 Don't pass LayoutDirection from Cxx to IntBufferBatchMountItem<Replace this line with a title. Use 1 line only, 67 chars or less>
Summary:
I thought we'd need LayoutDirection on the platform at some point, but it turns out we never use it, and don't seem to need it since components just query via `I18nUtil` one time,
and it's expected that apps restart if language changes and we need to switch between LTR and RTL. So, it seems like we'll not have any need for this on the platform at any point.

And we can save a byte per layout instruction now. Huzzah!

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D26660908

fbshipit-source-id: 54c7d132f5fa260a93fc7f09f7cf63059d52ed1f
2021-02-25 10:09:32 -08:00
Joshua GrossandFacebook GitHub Bot 81810f4c62 Add invariant to SurfaceMountingManager: when removing a view, the parent View must be a ViewGroup
Summary:
In addViewAt, we have this check. Add this same check to removeViewAt.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D26381475

fbshipit-source-id: 1050377aa4e528668446fd561ff09c61f27c700f
2021-02-10 16:03:10 -08:00
Joshua GrossandFacebook GitHub Bot e0f1101e7e Add invariant to SurfaceMountingManager: Views must not have parents when they are inserted
Summary:
We have no evidence of this happening on Android, but we are hitting a similar invariant on iOS. Adding this to Android for debugging purposes.

For now it's a SoftException to catch in debug and capture information; if we don't hit this prod at all, we'll elevate to a hard crash.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D26281585

fbshipit-source-id: 8ea9cf3ac555b13bf311f24c81bbbbc2845521d5
2021-02-09 22:43:43 -08:00
Joshua GrossandFacebook GitHub Bot b0ec350568 Detect startSurface race-conditions and warn silently
Summary:
Crash in debug, log a warning and continue in production.

Changelog: [Internal]

Differential Revision: D26133167

fbshipit-source-id: 60279363a3e90d592e7ddbde188c13cda89c28c6
2021-01-28 16:22:06 -08:00
Joshua GrossandFacebook GitHub Bot de8aa2c6b9 Try to call setSurfaceId and setId earlier on ReactRootViews
Summary:
We assume that startSurface is always called off the UI thread; see if we can synchronously call setId and setSurfaceId, and in general, call setSurfaceId sooner.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D26053050

fbshipit-source-id: a657584502bb0018e9591fe610eac0fc9fab2ca9
2021-01-28 14:07:25 -08:00
Joshua GrossandFacebook GitHub Bot 335d9d88e1 Fix sendAccessibilityEvent in Fabric
Summary:
This logic got reversed.

Changelog: [internal]

Differential Revision: D26070642

fbshipit-source-id: 4c68e4af25d4907746a09e7a3afe175d88a25f95
2021-01-26 00:50:56 -08:00
Joshua GrossandFacebook GitHub Bot 5792c32e36 Fix race between stopSurface and PreAllocateMountItem
Summary:
There is a race between PreAllocateMountItems executing and killing off stale SurfaceMountingManagers.

For now I'm simplifying the "eviction" mechanism. We just keep up to 15 SurfaceMountingManagers around and start evicting them from the least-recently-referenced one.

Hopefully this logic can be simplified in the future.

I'm also sneaking in a small perf optimization for PreAllocateMountItem: don't queue them if the associated surface is already stopped, because chewing through a bunch of dead PreAllocateMountItems on the UI thread can be expensive.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D26059378

fbshipit-source-id: 3b2503d7d8e5f045ae741d0d4a5880d1b37758d2
2021-01-25 20:30:38 -08:00
Joshua GrossandFacebook GitHub Bot 595b569ead Fix EventEmitter crash for events that are sent to a stopped surface
Summary:
In SurfaceMountingManager/MountingManager/FabricUIManager infra, we try to blackhole events that are sent to a stopped surface. In this case I just forgot to add a null check. Add here to protect against events sent to stopped surfaces - for example, if a TextInput is focused when the surface is stopped, a "blur" event will be sent and will crash here otherwise. Now it blackholes silently, as expected.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D26031260

fbshipit-source-id: 9936466ca2d00267efaf7fa594c9bcd59f7aad2a
2021-01-22 19:32:15 -08:00
Joshua GrossandFacebook GitHub Bot 62f0dee235 Migrate ScrollEvent to RCTModernEventEmitter
Summary:
Motivation: perf, simplicity, adhering to new SurfaceMountingManager APIs available to us. Backwards-compatible with events sent through old system or Fabric, to Fabric or non-Fabric Views.

Changelog: [Changed][Android] Old Native method to create ScrollEvent has been deprecated and will be removed at some point in the (distant) future

Reviewed By: mdvacca

Differential Revision: D26027105

fbshipit-source-id: b9dba5b56c2bfed3b8fc4488c54b271b85ab5fa0
2021-01-22 19:32:14 -08:00
Joshua GrossandFacebook GitHub Bot 2fbbdbb2ce Create V2 EventEmitter (ModernEventEmitter) interface that surfaceId can be passed into
Summary:
Create V2 EventEmitter that surfaceId can be passed into, with a backwards-compat layer, and some debug-only logging to help assist with migration.

Changelog: [Changed][Android] RCTEventEmitter has been deprecated in favor of RCTModernEventEmitter for optimal Fabric support; RCTEventEmitter will continue to work in Fabric, but there are minor perf implications.

Reviewed By: mdvacca

Differential Revision: D26027104

fbshipit-source-id: 784ca092bbc88d19c82f6c42537c34460d96de86
2021-01-22 19:32:14 -08:00
Joshua GrossandFacebook GitHub Bot e7783ff9ad Rename addRootView -> startSurface in Fabric, and deprecate existing addRootView sites
Summary:
Deprecate addRootView, use startSurface consistently in Fabric.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D26021147

fbshipit-source-id: e23b9294695609f766e382917ae1874fc8a1b27d
2021-01-22 19:32:13 -08:00
Joshua GrossandFacebook GitHub Bot 29eb632f1c Refactor MountingManager into MountingManager + SurfaceMountingManager
Summary:
This refactors MountingManager into a minimal API that shims into a more fully-featured SurfaceMountingManager. The SurfaceMountingManager keeps track of surface start/stop, surface ID, and surface Context.

This solves a number of issues around (1) race conditions around StopSurface/StartSurface, (2) memory management of Views, (3)

Concrete improvements:

1. Simpler to reason about race conditions around StopSurface/StartSurface.
2. 1:1 relationship between SurfaceId and all Views/tags.
3. When surface is stopped, all descendent Views can be GC'd immediately.
4. Fixed separation of concerns and leaky abstractions: surfaceId/rootTag and Surface Context are now stored and manipulated *only* in SurfaceMountingManager.
5. Simpler StopSurface flow: we simply remove references to all Views, and the Fragment (outside of the scope of this code) removes the RootView. This will trigger GC and we do ~0 work. Previously, we ran a REMOVE and DELETE instruction and kept track of each View in a HashMap. Now we can simply delete the map and move on.

The caveat: NativeAnimated (or other native modules that go through UIManager). APIs like `updateProps` currently uses only the ReactTag and does not store SurfaceId. This is a good argument for moving away from ReactTag, at least in its current incarnation, but: for now this requires that you do a lookup of a ReactTag across N surfaces (worst-case) to determine which Surface a ReactTag is in.

So, to summarize, the "con" of this approach is that now `getSurfaceManagerForViewEnforced` could be slower. It is used in:
* NativeAnimatedModule calls `updateProps` through UIManager
* FabricEventEmitter calls `receiveEvent` on FabricUIManager directly
* On audit, I could find zero native callsites to `sendAccessibilityEvent` through UIManager

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D26000781

fbshipit-source-id: 386ae40c4333f8c584e05818c404868dbee6ce73
2021-01-21 23:47:34 -08:00
Joshua GrossandFacebook GitHub Bot a715c5eba7 Addressing leaked Views in Fabric MountingManager
Summary:
MountingManager keeps a map of tags to Views, and attempts to clean it up by (1) deleting tags when they're explicitly deleted, (2) recursively deleting all Views when the View hierarchy is torn down.

However, there appear to be.... substantial gaps here. In tests, when navigating between screen X -> screen Y -> back to X (triggering a StopSurface), each "StopSurface" resulted in 200-600 Views being leaked (!).

What is causing these leaks? Well, for one, the "dropView" mechanism isn't perfect, so it might be missed Views. Second, Views don't always guarantee that `reactTag == getId()`, so that could result in leaks. Third, View preallocation on Android complicates things: Views can be preallocated and then never even inserted into the View hierarchy, so DELETE mutations could never be issued. Fourth, StopSurface is also complicated on Android (largely because of View preallocatioAndroid (largely because of View preallocation).

So, I introduce a new mechanism: keep a list of all tags for a surface, and remove all tags for a surface when the surface is torn down. This should be fool-proof: it handles preallocation and normal creation; it can handle deletes; and we're guaranteed that tags cannot be added after a surface is stopped.

Is this overly complicating things? Well, hopefully we can simplify all of this in the longterm. But until we get rid of View Preallocation, it seems like we need this mechanism - and View Preallocation might be around for a while, or forever.

Other thoughts: it's possible that using other data-structures could be more efficient, but I'm guessing the perf implications here are marginal (compared to the insane amount of memory leaks we're fixing). It could also simplify things to have a SurfaceMountingManager interface that implies all actions happen on a specific surface, including teardown.

Changelog: [Internal]

Reviewed By: mdvacca

Differential Revision: D25985409

fbshipit-source-id: f55b533770b1630c6c2a9b7a694d953aa3324428
2021-01-20 17:46:30 -08:00