Summary:
This is a workaround for missing PDF url support in Android WebView, which is a general known issue: when tapping a PDF url within WebView, instead of doing nothing, we just let android default intent handle it (e.g. it will open Chrome to load it).
This is basically to trick `shouldOverrideUrlLoading()` to return true for the specific url. The drawback is that product code needs to provide the whitelist.
The proper fix would be to use PdfRenderer in that method, but it seems like it's only for API >= 21...
Differential Revision: D5619383
fbshipit-source-id: f86b930f970dab9a5f57999df69ce94b9508edc9
Summary:
Since the `hot` parameter is not used anymore in metro-bundler (we are always applying the HMR transforms for bundlers requested through the HTTP server), we can remove it from the client request URL.
This allows us to reduce the metro-bundler memory by half when switching between HMR and not-HMR, since metro caches the bundles based on the requested URL path.
Reviewed By: davidaurelio
Differential Revision: D5630051
fbshipit-source-id: fb5dce4c31bbb38b1c0c93c97a525a992b2f6d8d
Summary:
We ran into a couple of problems with the implementation of `getCurrentPosition` on Android:
- It sometimes returns an inaccurate location
- It times out when `enableHighAccuracy` is `true` (#7495)
This change improves `getCurrentPosition` for both of the above problems. Instead of calling `requestSingleUpdate` it now calls `requestLocationUpdates` so it can receive multiple locations giving it an opportunity to pick a better one. Unlike `requestSingleUpdate`, this approach doesn't seem to timeout when `enableHighAccuracy` is `true`.
**Test plan (required)**
Verified in a test app that `getCurrentPosition` returns a good location and doesn't timeout when `enableHighAccuracy` is `true`. Also, my team has been using this change in our app in production.
Adam Comella
Microsoft Corp.
Closes https://github.com/facebook/react-native/pull/15094
Differential Revision: D5632100
Pulled By: hramos
fbshipit-source-id: 86e40b01d941a13820cb775bccad7e19dba3d692
Summary:
This is a simple groundwork PR to allow options to be passed to the `WebSocket` constructor. It represents a minor change to an undocumented part of the API, moving `headers` to within `options`.
This will be a BC for anyone manually specifying headers other than `origin` but a) that's not a common use case with WebSockets and b) it's not documented even in code and wouldn't currently pass a flow check.
NB: The third argument to the WebSocket constructor isn't part of the W3C spec, so I think this is a good place for RN-specific named parameters, better than adding a fourth argument. `protocols` needs to stay where it is, in line with the spec.
If this goes through I'd like to build on it by adding an additional connection option for SSL certificate pinning, as already supported by the underlying `okhttp` and `RCTSRWebSocket`. It could later be expanded for various other uses.
Currently, there's no way for a `WebSocket` user to specify any connection options other than url, protocol and headers. The fact that `WebSocket` connects in its constructor means any options have to go in there.
Connect to a websocket server using iOS and Android, observe the connection headers:
1. Without specifying `origin`, the default header should be set
2. Specifying it in the old way `new WebSocket(url, protocols, { origin: 'customorigin.com' })`
3. Specifying it in the new way `new WebSocket(url, protocols, { headers: { origin: 'customorigin.com' }})`.
I've tested myself using the test app with iOS and Android.
Closes https://github.com/facebook/react-native/pull/15334
Differential Revision: D5601675
Pulled By: javache
fbshipit-source-id: 5959d03a3e1d269b2c6775f3e0cf071ff08617bf
Summary:
LocalString doesn't have a check for null ptr which causes a crash if the null string passed.
Closes https://github.com/facebook/react-native/pull/15372
Differential Revision: D5601469
Pulled By: javache
fbshipit-source-id: a1b20efbae90009f0d465c077e6401a701d7515f
Summary:
If the z-index was updated after the initial mount, changes would not be reflected because we did not recalculate the z-index mapped child views and redraw the view. This adds code to do that and call it whenever we update z-index.
**Test plan**
Tested by reproducing the bug with 2 overlapping views that change z-index every second. Made sure it now works properly and z-index changes are reflected.
Closes https://github.com/facebook/react-native/pull/15203
Differential Revision: D5564832
Pulled By: achen1
fbshipit-source-id: 5b6c20147211ce0b7e8954d60f8614eafe128fb4
Summary:
My PR was pulled into RN 0.37 (d294e15c43). Since then an issue was discovered: ARTSurface skipped drawing the first render cycle if native TextureView takes too long. In case a static graphic is rendered in a single render cycle, it may be skipped resulting in an empty canvas being displayed.
A solution proposed in this PR: instead of skipping updates, make them pending and flush once the TextureView is ready.
This solution is released within our production app. It fixed ArtSurface initialisation issues cased by original PR to RN 0.37.
Closes https://github.com/facebook/react-native/pull/11539
Differential Revision: D4449255
Pulled By: shergin
fbshipit-source-id: a517909ca5c78c09a3ac8d9052664b92841b4e08
Summary:
This is the better fix for the same issue as mentioned in PR https://github.com/facebook/react-native/pull/14560
Certain rotateX, rotateY, scaleX and scaleY animations do not work correctly on some phones in Android 7.0.0, causing issues such as https://github.com/facebook/react-native/issues/14462 and https://github.com/facebook/react-native/issues/13522.
The issue can be fixed on JS side by setting an additional transform for perspective, eg. `{perspective: 1}` which triggers a `setCameraDistance` call in native code.
The fix in this PR always sets the camera distance on transforms, even when no perspective transform was specified. The default camera distance is set before the scale multiplication, to make sure that the value is appropriate for the phones density. The value calculates to an Android 'default' camera distance of 1280 * scale multiplier; https://developer.android.com/reference/android/view/View.html#setCameraDistance(float)
If a perspective transform is specified, this value will be used correctly still.
This fix was tested on the RNTester. Before the fix, on some devices, the FlatList example, with inverted turned on, will not display the list.
Devices that have been confirmed to have this issue:
FRD-AL10(honor 8) EMUI:5.0 android: 7.0
MHA-AL00(Mate9) EMUI:5.0 android:7.0
Huawei P10 VTR-L09, running Android 7.0
After the fix, the inverted FlatList displays correctly.
Closes https://github.com/facebook/react-native/pull/14646
Differential Revision: D5492009
Pulled By: shergin
fbshipit-source-id: d4da3b090a7e65df3b84e48ea32c964f4f8f7c88
Summary:
**Summary:**
There was a bug with RN.Dimensions returning incorrect window dimensions. In certain cases when device was in portrait, window dimensions reported landscape dimensions and vice versa.
This happened because in certain scenarios, after device orientation changed, dimensions update event from ReactRootView had incorrect dimensions.
Was able to reproduce this when device was rotated during app launch. After rotation global layout listener callback gets invoked. Inside the callback current and previous orientations are compared. When a change is detected, orientation and dimension change events are sent to JS. It is assumed, when orientation changes, new dimensions are available immediately. This is not the case for window dimensions as they are retrieved from resources object which gets updated asynchronously after orientation change. In cases when app is doing a lot of work on the main thread, like app startup, it takes more time to update the resources object. And when orientation change is detected in global layout, resources object is not updated with new dimensions yet. This causes dimensions update to be sent to JS with old window dimensions.
Global layout listener callback does get invoked a second time when resources object is finally updated with new dimensions, but since orientation no longer changes, no event is sent to JS.
Fixed this by separating dimensions update from orientation update. Now RN keeps track of previous window and screen dimension values. When a change is detected, an event is sent to JS with updated dimensions. This ensures that whenever dimensions change, JS gets the updated values.
This has a side effect of sending dimension update twice in some cases.
One example is the case above where window dimensions take time to update, but screen dimensions are updated immediately. This will cause two events to be sent to JS. One for window dimensions and one for screen dimensions update.
Other change is that initial value for both window and screen fields is empty. Which results in first change to trigger an event. Previously initial orientation value was 0 which meant when app started in normal portrait orientation, first layout did not trigger a dimension update event. Now even first layout sends the event. This should not be an issue as it is to make sure dimensions in JS side are correct.
**Testing:**
Verified with a sample app that correct dimensions are available when app launches.
Verified that after orientation dimensions are updated.
Verified that in the scenario described above where window dimensions are updated later, we get correct dimension values in JS.
We have incorporated this fix into our app and have been testing it internally.
Ats Jenk
Microsoft Corp.
<!--
Thank you for sending the PR!
If you changed any code, please provide us with clear instructions on how you verified your changes work. In other words, a test plan is *required*. Bonus points for screenshots and videos!
Please read the Contribution Guidelines at https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md to learn more about contributing to React Native.
Happy contributing!
-->
Closes https://github.com/facebook/react-native/pull/15181
Differential Revision: D5552195
Pulled By: shergin
fbshipit-source-id: d1f190cb960090468886ff56cda58cac296745db
Summary:
Fixes the following crash:
```
Fatal Exception: java.lang.RuntimeException: Unable to destroy activity {com.example/com.example.MainActivity}: java.lang.NullPointerException: ImagePipelineFactory was not initialized!
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3831)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3849)
at android.app.ActivityThread.access$1500(ActivityThread.java:150)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1398)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:764)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
Caused by java.lang.NullPointerException: ImagePipelineFactory was not initialized!
at com.facebook.common.internal.Preconditions.checkNotNull(Preconditions.java:226)
at com.facebook.imagepipeline.core.ImagePipelineFactory.getInstance(ImagePipelineFactory.java:74)
at com.facebook.drawee.backends.pipeline.Fresco.getImagePipelineFactory(Fresco.java:92)
at com.facebook.drawee.backends.pipeline.Fresco.getImagePipeline(Fresco.java:97)
at com.facebook.react.modules.fresco.FrescoModule.onHostDestroy(FrescoModule.java:186)
at com.facebook.react.bridge.ReactContext.onHostDestroy(ReactContext.java:240)
at com.facebook.react.ReactInstanceManager.moveToBeforeCreateLifecycleState(ReactInstanceManager.java:667)
at com.facebook.react.ReactInstanceManager.onHostDestroy(ReactInstanceManager.java:586)
at com.facebook.react.ReactInstanceManager.onHostDestroy(ReactInstanceManager.java:599)
at com.facebook.react.ReactActivityDelegate.onDestroy(ReactActivityDelegate.java:142)
at com.facebook.react.ReactActivity.onDestroy(ReactActivity.java:72)
at android.app.Activity.performDestroy(Activity.java:6456)
at android.app.Instrumentation.callActivityOnDestroy(Instrumentation.java:1143)
at android.app.ActivityThread.performDestroyActivity(ActivityThread.java:3818)
at android.app.ActivityThread.handleDestroyActivity(ActivityThread.java:3849)
at android.app.ActivityThread.access$1500(ActivityThread.java:150)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1398)
at android.os.Handler.dispatchMessage(Handler.java:102)
at android.os.Looper.loop(Looper.java:148)
at android.app.ActivityThread.main(ActivityThread.java:5417)
at java.lang.reflect.Method.invoke(Method.java)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:764)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:626)
```
This was introduced by d9ae27ba89
1. Create app with an image to be loaded
2. Background app before fresco has been initialised. (Very tight window to do this)
3. Should not crash
cc foghina
Closes https://github.com/facebook/react-native/pull/14359
Differential Revision: D5508505
Pulled By: hramos
fbshipit-source-id: 5a66d594625783f1c30180fe78c5baddb4f835aa
Summary:
This is the first PR from a series of PRs grabbou and me will make to add blob support to React Native. The next PR will include blob support for XMLHttpRequest.
I'd like to get this merged with minimal changes to preserve the attribution. My next PR can contain bigger changes.
Blobs are used to transfer binary data between server and client. Currently React Native lacks a way to deal with binary data. The only thing that comes close is uploading files through a URI.
Current workarounds to transfer binary data includes encoding and decoding them to base64 and and transferring them as string, which is not ideal, since it increases the payload size and the whole payload needs to be sent via the bridge every time changes are made.
The PR adds a way to deal with blobs via a new native module. The blob is constructed on the native side and the data never needs to pass through the bridge. Currently the only way to create a blob is to receive a blob from the server via websocket.
The PR is largely a direct port of https://github.com/silklabs/silk/tree/master/react-native-blobs by philikon into RN (with changes to integrate with RN), and attributed as such.
> **Note:** This is a breaking change for all people running iOS without CocoaPods. You will have to manually add `RCTBlob.xcodeproj` to your `Libraries` and then, add it to Build Phases. Just follow the process of manual linking. We'll also need to document this process in the release notes.
Related discussion - https://github.com/facebook/react-native/issues/11103
- `Image` can't show image when `URL.createObjectURL` is used with large images on Android
The websocket integration can be tested via a simple server,
```js
const fs = require('fs');
const http = require('http');
const WebSocketServer = require('ws').Server;
const wss = new WebSocketServer({
server: http.createServer().listen(7232),
});
wss.on('connection', (ws) => {
ws.on('message', (d) => {
console.log(d);
});
ws.send(fs.readFileSync('./some-file'));
});
```
Then on the client,
```js
var ws = new WebSocket('ws://localhost:7232');
ws.binaryType = 'blob';
ws.onerror = (error) => {
console.error(error);
};
ws.onmessage = (e) => {
console.log(e.data);
ws.send(e.data);
};
```
cc brentvatne ide
Closes https://github.com/facebook/react-native/pull/11417
Reviewed By: sahrens
Differential Revision: D5188484
Pulled By: javache
fbshipit-source-id: 6afcbc4d19aa7a27b0dc9d52701ba400e7d7e98f
Summary:
This should be functionally identical, but avoids unnecessary conditionals in the code.
<!--
Thank you for sending the PR!
If you changed any code, please provide us with clear instructions on how you verified your changes work. In other words, a test plan is *required*. Bonus points for screenshots and videos!
Please read the Contribution Guidelines at https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md to learn more about contributing to React Native.
Happy contributing!
-->
Closes https://github.com/facebook/react-native/pull/15147
Differential Revision: D5497883
Pulled By: javache
fbshipit-source-id: a4b182084ffce87adac56013a178fbc5a7a5d1bb
Summary:
This change intends to fix 2 issues with the NetInfo API:
- The NetInfo API is currently platform-specific. It returns completely different values on iOS and Android.
- The NetInfo API currently doesn't expose a way to determine whether the connection is 2g, 3g, or 4g.
The NetInfo API currently just exposes a string-based enum representing the connectivity type. The string values are different between iOS and Andorid. Because of this design, it's not obvious how to achieve the goals of this change without making a breaking change. Consequently, this change deprecates the old NetInfo APIs and introduces new ones. Specifically, these are the API changes:
- The `fetch` method is deprecated in favor of `getConnection`
- The `change` event is deprecated in favor of the `connectionchange` event.
- `getConnection`/`connectionchange` use a new set of enum values compared to `fetch`/`change`. See the documentation for the new values.
- On iOS, `cell` is now known as `cellular`. It's worth pointing out this one in particular because the old and new names are so similar. The rest of the iOS values have remained the same.
- Some of the Android enum values have been removed without a replacement (e.g. `DUMMY`, `MOBILE_DUN`, `MOBILE_HIPRI`, `MOBILE_MMS`, `MOBILE_SUPL`, `VPN`). If desirable, we could find a way to expose these in the new API. For example, we could have a `platformValue` key that exposes the platform's enum values directly (like the old `fetch` API did).
`getConnection` and `connectionchange` each expose an object which has 2 keys conveying a `ConnectionType` (e.g. wifi, cellular) and an `EffectiveConnectionType` (e.g. 2g, 3g). These enums and their values are taken directly from the W3C's Network Information API spec (https://wicg.github.io/netinfo/). Copying the W3C's API will make it easy to expose a `navigation.connection` polyfill, if we want, in the future. Additionally, because the new APIs expose an object instead of a string, it's easier to extend the APIs in the future by adding keys to the object without causing a breaking change.
Note that the W3C's spec doesn't have an "unknown" value for `EffectiveConnectionType`. I chose to introduce this non-standard value because it's possible for the current implementation to not have an `effectiveConnectionType` and I figured it was worth representing this possibility explicitly with "unknown" instead of implicitly with `null`.
**Test Plan (required)**
Verified that the methods (`fetch` and `getConnection`) and the events (`change` and `connectionchange`) return the correct data on iOS and Android when connected to a wifi network and a 4G cellular network. Verified that switching networks causes the event to fire with the correct information. Verified that the old APIs (`fetch' and 'change') emit a deprecation warning when used. My team is using a similar patch in our app.
Adam Comella
Microsoft Corp.
Closes https://github.com/facebook/react-native/pull/14618
Differential Revision: D5459593
Pulled By: shergin
fbshipit-source-id: f1e6c5d572bb3e2669fbd4ba7d0fbb106525280e
Summary:
Fixes#11209
Updating action items in a `ToolbarAndroid`, or more specifically the native `ReactToolbar`, after the initial render presently will not always work as expected - typically manifesting itself as new action items not being displayed at all (under certain circumstances).
This seems to be happening because Fresco gets back to us asynchronously and updates the `MenuItem` in a listener. However when a keyboard is displayed the `Toolbar` is in a weird state where updating the `MenuItem` doesn't automatically trigger a layout.
The solution is to trigger one manually.
This is a bit wacky, so I created a sample project:
https://github.com/Benjamin-Dobell/DynamicToolbar
`master` demonstrates the problem. Run the project, the toolbar action item is scheduled to update every 2 seconds. It works fine _until_ you give the `TextInput` focus. Once you give it focus the action item disappears and it never recovers (despite on-going renders due to state changes).
You can then checkout the `fixed` branch, run `yarn` again, and see that problem is fixed. This branch is using a prebuilt version of React Native with this patch applied. Of course you could (and probably should) also modify `master` to use a version of RN built by the Facebook CI (assuming that's a thing you guys do).
Closes https://github.com/facebook/react-native/pull/13876
Differential Revision: D5476858
Pulled By: shergin
fbshipit-source-id: 6634d8cb3ee18fd99f7dc4e1eef348accc1c45ad
Summary:
<!--
Thank you for sending the PR!
If you changed any code, please provide us with clear instructions on how you verified your changes work. In other words, a test plan is *required*. Bonus points for screenshots and videos!
Please read the Contribution Guidelines at https://github.com/facebook/react-native/blob/master/CONTRIBUTING.md to learn more about contributing to React Native.
Happy contributing!
-->
Closes https://github.com/facebook/react-native/pull/15156
Differential Revision: D5479265
Pulled By: shergin
fbshipit-source-id: a2dfa3a4357e126838a17dac4797d1d845cd56ae
Summary:
Closes https://github.com/facebook/react-native/issues/7463.
This PR fixes the `HEAD` http requests in Android.
In Android all the HEAD http requests will fail, even if the request succeeds in the native layer due to an issue in the communication with the `OkHttp`.
Closes https://github.com/facebook/react-native/pull/14289
Differential Revision: D5166130
Pulled By: hramos
fbshipit-source-id: a7a0deee0fcb5f6a645c07d4e6f4386b5f550e31