Summary:
@public
The `WritableArray` and `WritableMap` interfaces currently require that nested arrays and maps also be writable. Nothing in our code actually relies on this, so we can relax this restriction and get useful properties.
For instance, it is now possible to construct a `JavaOnlyMap` (or array) that reuses `ReadableMap` and `ReadableArray` values by reference ( = structural sharing) instead of forcing a deep copy.
Reviewed By: kathryngray
Differential Revision: D16132580
fbshipit-source-id: 9f41189ebea2a82e775a7a4da8c357a5ce9c5b9d
Summary:
@public
* Removes `JsonWriter`; it's apparently a buggy fork of [`android.util.JsonWriter`](https://developer.android.com/reference/android/util/JsonWriter) which has existed since API level 11. Our version doesn't insert commas before objects or arrays within an array. Instead of fixing it, we can just use the Android one.
* Extends `JsonWriterHelper` to support serialising `ReadableMap`, `ReadableArray` and `Dynamic` values into a `JsonWriter`.
Reviewed By: kathryngray
Differential Revision: D16131713
fbshipit-source-id: d258af42b669f10218cae8b086e7adc3226d16c0
Summary: After we ran google-java-format D16071725, some Javadocs which weren't properly written broke. This includes putting unordered and ordered lists not using <ul> and <ol>, putting code blocks and pseudo-graphics not using <pre>. I ran through all the changed classes and tried to fix the broken Javadocs.
Reviewed By: cpojer
Differential Revision: D16090087
fbshipit-source-id: f31971cbc0e367a04814ff90bbfb2192751d5e16
Summary:
This diff formats the Java class files inside xplat/js/react-native-github. Since google-java-format was enabled in D16071401 we want to codemode the existing code so that users don't have to deal with formatter lint noise at diff-time.
```arc f --paths-cmd 'hg files -I "**/*.java"'```
drop-conflicts
Reviewed By: cpojer
Differential Revision: D16071725
fbshipit-source-id: fc6e3852e45742c109f0c5ac4065d64201c74204
Summary:
Right now JS triggers a view manager command with the following code:
```
UIManager.dispatchViewManagerCommand(
ReactNative.findNodeHandle(this),
UIManager.getViewManagerConfig('RCTView').Commands.hotspotUpdate,
[destX || 0, destY || 0],
);
```
As we want to get rid of calls to UIManager, we need to stop looking for the integer defined in native from JavaScript. We will be changing methods like this to be:
```
UIManager.dispatchViewManagerCommand(
ReactNative.findNodeHandle(this),
'hotspotUpdate',
[destX || 0, destY || 0],
);
```
We need to support ints and Strings to be backwards compatible, but ints will be deprecated.
Reviewed By: shergin
Differential Revision: D15955444
fbshipit-source-id: d1c488975ae03404f8f851a7035b58a90ed34163
Summary: Some TM lookup from native will fail assertion if done too early, because TM Manager is not initialized yet.
Reviewed By: mdvacca
Differential Revision: D15872776
fbshipit-source-id: 7616c1424816f73a45aa1d9723e7807ae10392a7
Summary:
To avoid unnecessary class loads, and better modularity, let's use string keys (enum) to access JSIModule's. For now all JSIModule's are all known inside the core infra (only FabricUIManager and TurboModuleManager right now), so let's keep it simple and explicitly list them out.
The only problem here is we lose some form of type safety...
Reviewed By: JoshuaGross
Differential Revision: D15872777
fbshipit-source-id: 9c2de7ef1e88ef3a6dff5888d644f9d8963af2a3
Summary:
This PR only fixes a one small orthographic error
Pull Request resolved: https://github.com/facebook/react-native/pull/25245
Differential Revision: D15796478
Pulled By: hramos
fbshipit-source-id: ccb811b43b0d2efc5d97ba335b60531a0fcbda10
Summary:
These changes were originally landed in D15327683. Unfortunately, I had to back these out because they revelaled problems with our TurboModules infra. Those problems have since been fixed, so I think it's safe for us to re-land these changes.
Please refer to D15327683 for a description.
Differential Revision: D15739355
fbshipit-source-id: 69bb3cec0731ba325f60c6c8459426546c79b54d
Summary:
Original commit changeset: e295dafdab7a
I'm backing this out because it's broken Catalyst. The fixes are in D15711539, but it could take some time to review and land them.
Reviewed By: rickhanlonii
Differential Revision: D15714896
fbshipit-source-id: c2c555a52d3d140dfdea7d54ccd8d3102c22a1c6
Summary:
`setTimeout` inside a headless JS task does not always works; the function does not get invoked until the user starts an `Activity`.
This was attempted to be used in the context of widgets. When the widget update or user interaction causes the process and React context to be created, the headless JS task may run before other app-specific JS initialisation logic has completed. If it's not possible to change the behaviour of the pre-requisites to be synchronous, then the headless JS task blocks such asynchronous JS work that it may depend on. A primitive solution is the use of `setTimeout` in order to wait for the pre-conditions to be met before continuing with the rest of the headless JS task. But as the function passed to `setTimeout` is not always called, the task will not run to completion.
This PR solves this scenario by allowing the task to be retried again with a delay. If the task returns a promise that resolves to a `{'timeout': number}` object, `AppRegistry.js` will not notify that the task has finished as per master, instead it will tell `HeadlessJsContext` to `startTask` again (cleaning up any posted `Runnable`s beforehand) via a `Handler` within the `HeadlessJsContext`.
Documentation also updated here: https://github.com/facebook/react-native-website/pull/771
### AppRegistry.js
If the task provider does not return any data, or if the data it returns does not contain `timeout` as a number, then it behaves as `master`; notifies that the task has finished. If the response does contain `{timeout: number}`, then it will attempt to queue a retry. If that fails, then it will behaves as if the task provider returned no response i.e. behaves as `master` again. If the retry was successfully queued, then there is nothing to do as we do not want the `Service` to stop itself.
### HeadlessJsTaskSupportModule.java
Similar to notify start/finished, we simply check if the context is running, and if so, pass the request onto `HeadlessJsTaskContext`. The only difference here is that we return a `Promise`, so that `AppRegistry`, as above, knows whether the enqueuing failed and thus needs to perform the usual task clean-up.
### HeadlessJsTaskContext.java
Before retrying, we need to clean-up any timeout `Runnable`'s posted for the first attempt. Then we need to copy the task config so that if this retry (second attempt) also fails, then on the third attempt (second retry) we do not run into a consumed exception. This is also why in `startTask` we copy the config before putting it in the `Map`, so that the initial attempt does leave the config's in the map as consumed. Then we post a `Runnable` to call `startTask` on the main thread's `Handler`. We use the same `taskId` because the `Service` is keeping track of active task IDs in order to calculate whether it needs to `stopSelf`. This negates the need to inform the `Service` of a new task id and us having to remove the old one.
## Changelog
[Android][added] - Allow headless JS tasks to return a promise that will cause the task to be retried again with the specified delay
Pull Request resolved: https://github.com/facebook/react-native/pull/23231
Differential Revision: D15646870
fbshipit-source-id: 4440f4b4392f1fa5c69aab7908b51b7007ba2c40
Summary:
## Summary
If a NativeModule Spec interface extends `TurboModule`, we want to make the auto-generated Java base class for that NativeModule to implement `com.facebook.react.turbomodule.core.interfaces.TurboModule`. This makes it so that our Android code recognizes that Java module as a TurboModule.
When this diff lands, all internal FB4A NativeModules will start going through the TurboModule system.
Reviewed By: fkgozali
Differential Revision: D15327683
fbshipit-source-id: e295dafdab7a0e130820318aeaf0cafa41487689
Summary:
### Problem
According to https://github.com/facebook/react-native/issues/9145, the `--port` setting is not respected when executing `react-native run-android`. The templates that report things like what port the dev server runs on are hard coded as well.
### Solution
This commit replaces the hardcoded instances of port 8081 on Android with a build configuration property. This allows setting of the port React Native Android connects to for the local build server.
For this change to work, there must also be an update to the react native CLI to pass along this setting:
https://github.com/react-native-community/react-native-cli/compare/master...nhunzaker:9145-android-no-port-hardcode-cli
To avoid some noise on their end, I figured I wouldn't submit a PR until it's this approach is deemed workable.
## Changelog
[Android][fixed] - `react-native run-android --port <x>` correctly connects to dev server and related error messages display the correct port
Pull Request resolved: https://github.com/facebook/react-native/pull/23616
Differential Revision: D15645200
Pulled By: cpojer
fbshipit-source-id: 3bdfd458b8ac3ec78290736c9ed0db2e5776ed46
Summary: `ReactContext.getNativeModule` can be used to access NativeModules. With these changes, it can also be used to instantiate (if necessary) and retrieve a TurboModule.
Reviewed By: mdvacca
Differential Revision: D15167631
fbshipit-source-id: 3cb0d9a4be16cbadebbf6648c3f1481ba26513c3
Summary: In the future we're planning to decouple ThemedReactContext from the bridge (CatalystInstance). For now, we just need to be able to create a ThemedReactContext with a ReactContext that has no Catalyst instance.
Reviewed By: mdvacca
Differential Revision: D15246442
fbshipit-source-id: 99ebda6521f4df72969011ea0e6ea41b046875c8
Summary: Refactoring ReactContext to move message queue initialization into its own function that can be called independently of initializeWithInstance. This allows you to create a ReactContext with message queue threads without a CatalystInstance.
Reviewed By: mdvacca
Differential Revision: D15246287
fbshipit-source-id: 4b8c53e68112af7eded47d8c31311500cc296dfe
Summary: Refactoring ReactContext to move message queue initialization into its own function that can be called independently of initializeWithInstance. This allows you to create a ReactContext with message queue threads without a CatalystInstance.
Reviewed By: mdvacca
Differential Revision: D14817741
fbshipit-source-id: f314a526c6534792714e5ba55dd873f1728c6b9f
Summary:
JSCallInvoker requires a `std::weak_ptr<Instance>` to create. In our C++, `CatalystInstance` is responsible for creating this `Instance` object. This `CatalystInstance` C++ initialization is separate from the `TurboModuleManager` C++ initialization. Therefore, in this diff, I made `CatalystInstance` responsible for creating the `JSCallInvoker`. It then exposes the `JSCallInvoker` using a hybrid class called `JSCallInvokerHolder`, which contains a `std::shared_ptr<JSCallInvoker>` member variable. Using `CatalystInstance.getJSCallInvokerHolder()` in TurboModuleManager.java, we get a handle to this hybrid container. Then, we pass it this hybrid object to `TurboModuleManager::initHybrid`, which retrieves the `std::shared_ptr<JSCallInvoker>` from the `JavaJSCallInvokerHandler`.
There were a few cyclic dependencies, so I had to break down the buck targets:
- `CatalystInstanceImpl.java` depends on `JSCallInvokerHolderImpl.java`, and `TurboModuleManager.java` depends on classes that are packaged with `CatalystInstanceImpl.java`. So, I had to put `JSCallInvokerHolderImpl.java` in its own buck target.
- `CatalystInstance.cpp` depends on `JavaJSCallInvokerHolder.cpp`, and `TurboModuleManager.cpp` depends on classes that are build with `CatalystInstance.cpp`. So, I had to put `JavaJSCallInvokerHolder.cpp` in its own buck target. To make things simpler, I also moved `JSCallInvoker.{cpp,h}` files into the same buck target as `JavaJSCallInvokerHolder.{cpp,h}`.
I think these steps should be enough to create the TurboModuleManager without needing a bridge:
1. Make `JSCallInvoker` an abstract base class.
2. On Android, create another derived class of `JSCallInvoker` that doesn't depend on Instance.
3. Create `JavaJSCallInvokerHolder` using an instance of this new class somewhere in C++.
4. Pass this instance of `JavaJSCallInvokerHolder` to Java and use it to create/instatiate `TurboModuleManager`.
Regarding steps 1 and 2, we can also make JSCallInvoker accept a lambda.
Reviewed By: mdvacca
Differential Revision: D15055511
fbshipit-source-id: 0ad72a86599819ec35d421dbee7e140959a26ab6
Summary: This is removing packages and libraries from the repo. Any modified buck files simply change the redirect targets to something more appropriate (no logic actually changed)
Differential Revision: D14950721
fbshipit-source-id: 6c14f827b76ca1dbaf83dcb983930f362c6a27d4
Summary: Need to force the double thing in more places.
Reviewed By: cpojer
Differential Revision: D14835792
fbshipit-source-id: fb7a5435675b322d5fbbe9858e08804e9abe65db
Summary: Removes useArrayNativeAccessor and everything needed to support it, similar to D14486283
Reviewed By: mdvacca
Differential Revision: D14487244
fbshipit-source-id: 7cfa91f7cf322c648c82be5951f3622cd6468961
Summary:
This was quite a rabit hole of remove deps -> delete dead code -> repeat.
Waaay simpler now with less duplicate lookups, redundant type verification, and extra function calls.
Reviewed By: mdvacca
Differential Revision: D14486283
fbshipit-source-id: 035db30181755d046a1ae99760468b954b2449df
Summary:
Changes our property access pattern to iterate through props once and pass the Object value directly rather than looking the value up in the map with the key.
Note some ViewManagers methods (especially yoga related ones on shadow nodes) expect a `Dyanamic`, so this diff also creates Dynamic's only when needed by the hand-written code, and introduces a new `DynamicWithObject` to create them that simply wraps the underlying object (as opposed to `DynamicWithMap` which wraps the map and does a lookup any time the `Dynamic` is accessed.
Reviewed By: mdvacca
Differential Revision: D14453300
fbshipit-source-id: df98567b6eff1e6b7c611f179eb11e413fb94e5d
Summary:
There is a small gap in the SynchronizedWeakHashSet implementation - the containsKey method of the WeakHashMap is modifying hence calling it during the iteration might cause ConcurrentModificationException. Added a command DO_IF_CONTAINS to safely handle this case.
[Android] [Bugfix] - Should fix a ConcurrentModificationException in onResume.
Pull Request resolved: https://github.com/facebook/react-native/pull/24015
Reviewed By: mdvacca
Differential Revision: D14507342
Pulled By: fkgozali
fbshipit-source-id: 2998bffb06e2cbacd8df1780964355842b1cc4a0
Summary:
This diff migrates RN to AndroidX.
As part of this diff I disabled few tests in RNAndroid OSS that will be re-enabled this week. As part of the refactor of BUCK files in OSS
Reviewed By: shergin
Differential Revision: D14200097
fbshipit-source-id: 932fcae251d1553e672acd67ecd0e703dcb364aa
Summary:
This mechanism is heavily abused inside of the react-native and inside of the various native modules.
The main problem is that people don't remove their listeners and as result, we have memory leaks.
Some modules like UIManager, NativeAnimatedModule have resources holding Activity context. Those modules are held through a pretty long chain of dependencies.
In order to allow GC to collect those listeners, I replaced the CopyOnWriteSet by WeakHashMap and synchronized access. It is not such a big deal in terms of performance as those listeners are not called/modified too frequently but this prevents hard to debug memory leaks.
Changelog:
----------
Help reviewers and the release process by writing your own changelog entry. When the change doesn't impact React Native developers, it may be ommitted from the changelog for brevity. See below for an example.
[Android] [Fixed] - ReactContext - lifecycle listeners don't cause the leaks even if not removed.
Pull Request resolved: https://github.com/facebook/react-native/pull/22318
Reviewed By: mdvacca
Differential Revision: D13106915
Pulled By: hramos
fbshipit-source-id: d506e5035a7f7bea1b57a6308fb5d9b5fcb277a7
Summary:
Instead of using measure specs to set certain yoga properties on the root node (like max width, auto width, specific width), use yoga's calculateLayout(width, height) instead. The measure specs will be stored in the shadow node. This allows us to remove duplicated code that processes the measure specs and allows us to remove other logic like the enableLayoutCalculation() method.
This diff also removes MeasureSpecProvider. MeasureSpecProvider was originally introduced to pass previously measured view measure specs to the initial creation of the root shadow node, but it turns out that this is unnecessary. We can update the root layout specs from the root view instead.
Reviewed By: mdvacca
Differential Revision: D9729744
fbshipit-source-id: 79b0b27ca879758f5dc3fc7cc8a0d38856a6cc79
Summary: This diff implements equality for ReadableNativeMap, the underlying implementation relies on the method HashMap.equals()
Reviewed By: kathryngray
Differential Revision: D14019065
fbshipit-source-id: aeaec22ce1066241ed85f0527f5cd804e3c763dd
Summary: This diff implements equality on RedableNativeArray objects. This relies on the Arrays.deepEquals method
Reviewed By: kathryngray
Differential Revision: D14022108
fbshipit-source-id: 48b59529a9060a2bddba5fc8e3681c922ec31be4
Summary:
This diff refactors JNI methods used by the Binding.cpp class in order to use ReadableMap instead of ReadableNativeMap
This will be helpful to provide a different implementation of ReadableMap from C++
Reviewed By: shergin
Differential Revision: D14077762
fbshipit-source-id: 595b0c2d3a2d6070112257b65c1141a8af36f0e1
Summary: SizeMonitoringFrameLayout was used to set layout contraints on the root shadow node when the native view's size changes. Since then, we introduced ways for the root node to use proper layout contraints using the root view's measure specs, which provides more accurate constraints for the root node, so SizeMonitoringFrameLayout is no longer needed. This ends up making a lot of UIManagerModule's method signatures cleaner
Reviewed By: mdvacca
Differential Revision: D9565720
fbshipit-source-id: c569cd15991a09987cc01e89612dc9193ad99b45
Summary:
This adds Nonnull annotations for interfaces and classes used for native modules for Android, to improve Kotlin developer experience, but also code quality checks.
[Android] [Changed] - Nonnull annotations for native module interfaces
Pull Request resolved: https://github.com/facebook/react-native/pull/23353
Differential Revision: D14018181
Pulled By: mdvacca
fbshipit-source-id: 09a583860a6075e1d6f6df8f479369ae96497133
Summary:
Kotlin is getting traction and more developers write RN native modules in it. This PR adds nullable annotations to help with Kotlin null inference and improve developer experience. Also it'll help checking code quality using lint.
I skimmed through JavaOnlyMap.java, JavaOnlyArray.java, ReadableNativeArray.java, ReadableNativeMap.java, WritableNativeArray.java and WritableNativeMap.java to infer nullability.
This is breaking change to Kotlin code.
[Android] [Changed] - Add nullable annotations to ReadableMap, WritableMap, ReadableArray, Writable.
Pull Request resolved: https://github.com/facebook/react-native/pull/23329
Differential Revision: D14002571
Pulled By: cpojer
fbshipit-source-id: 899d8b3b0a5dad43e8300e6c4ea4208cca0f01a9
Summary:
RN supports API 16 and above, but we have redundant historical artifacts where we check and target APIs 16 and below. This PR removes redundant artifacts.
[Android] [Changed] - remove redundant targetApi and version checks
Pull Request resolved: https://github.com/facebook/react-native/pull/23302
Differential Revision: D13970434
Pulled By: mdvacca
fbshipit-source-id: 096b5ee6c8f076b0365e7dda0e77940290077ea2
Summary: Simple diff that adds QPL marker to track time it takes to load .so file used by RN Fabric
Reviewed By: fkgozali
Differential Revision: D13934149
fbshipit-source-id: a5cb0fc255394cf6c936b9018c753dcc774c347f
Summary: Simple diff that adds QPL marker to track time it takes to load .so file from RN
Reviewed By: fkgozali
Differential Revision: D13845379
fbshipit-source-id: 6c2272605ba3fb08ab8ebce867f84c6a488438d0
Summary:
Added a flag that checks if TurboModules are enabled, don't expose them to JS via the old module system.
All TurboModules needs to implement TurboModule interface.
Reviewed By: mdvacca
Differential Revision: D13648332
fbshipit-source-id: f22506fe029ac82d56075f5b6962ff2df2e7eaa4
Summary:
Promise semantics per JS should allow calling resolve or reject repeatedly without crashing. Only the first one should do anything, but others should be allowed. This change fixes the Java bridge for Android. A separate change is needed for iOS.
Issue #20262
Pull Request resolved: https://github.com/facebook/react-native/pull/20303
Differential Revision: D13396975
Pulled By: cpojer
fbshipit-source-id: 81f14f73654fa7c44e043f574a39fda481ace44b
Summary: Computing things like "page faults since this thread was created" or "cpu time spent on this thread since it was created" is pretty easy - just measure it when you want it. However, if you want to know "how much wall time has elapsed since this thread was created" you need to record some timing info when the thread is created. This diff adds a an API for querying that from the RN thread holder abstraction.
Reviewed By: alexeylang
Differential Revision: D13246235
fbshipit-source-id: d36af61dbe27f662980fe508b2644e9d5255bb7e