Skip to content

Commit

Permalink
[Android][iOS] Upgrade react-native-view-shot to 3.4.0 (#19405)
Browse files Browse the repository at this point in the history
* [Android][iOS] Upgrade react-native-view-shot to 3.4.0

* CHANGELOG

* Fix CHANGELOG

* Restore fix in RNViewShot.m

* Restore Expo changes to RNViewShotModules.java

* Update bare-expo Podfile.lock

* Remove unused RNViewShotPackage.java
  • Loading branch information
douglowder committed Oct 6, 2022
1 parent 0f4e875 commit 366e33a
Show file tree
Hide file tree
Showing 8 changed files with 76 additions and 33 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Expand Up @@ -9,6 +9,7 @@ Package-specific changes not released in any SDK will be added here just before

- Updated `@stripe/stripe-react-native` from `0.13.1` to `0.18.1` on iOS. ([#19055](https://github.com/expo/expo/pull/19055) by [@tsapeta](https://github.com/tsapeta))
- Updated `@shopify/flash-list` from `1.1.0` to `1.3.0`. ([#19317](https://github.com/expo/expo/pull/19317) by [@kudo](https://github.com/kudo))
- Updated `react-native-view-shot` from `3.3.0` to `3.4.0`. ([#19405](https://github.com/expo/expo/pull/19405) by [@douglowder](https://github.com/douglowder))
- Updated `react-native-webview` from `11.23.0` to `11.23.1`. ([#19375](https://github.com/expo/expo/pull/19375) by [@aleqsio](https://github.com/aleqsio))
- Updated `react-native-gesture-handler` from `2.5.0` to `2.7.0`. ([#19362](https://github.com/expo/expo/pull/19362) by [@tsapeta](https://github.com/tsapeta))
- Updated `@react-native-community/netinfo` from `9.3.0` to `9.3.3`. ([#19421](https://github.com/expo/expo/pull/19421) by [@douglowder](https://github.com/douglowder))
Expand Down
Expand Up @@ -84,11 +84,12 @@ public void captureRef(int tag, ReadableMap options, Promise promise) {
: Formats.PNG;

final double quality = options.getDouble("quality");
final Integer scaleWidth = options.hasKey("width") ? (int) (dm.density * options.getDouble("width")) : null;
final Integer scaleHeight = options.hasKey("height") ? (int) (dm.density * options.getDouble("height")) : null;
final Integer scaleWidth = options.hasKey("width") ? options.getInt("width") : null;
final Integer scaleHeight = options.hasKey("height") ? options.getInt("height") : null;
final String resultStreamFormat = options.getString("result");
final String fileName = options.hasKey("fileName") ? options.getString("fileName") : null;
final Boolean snapshotContentContainer = options.getBoolean("snapshotContentContainer");
final boolean handleGLSurfaceView = options.hasKey("handleGLSurfaceViewOnAndroid") && options.getBoolean("handleGLSurfaceViewOnAndroid");

try {
File outputFile = null;
Expand All @@ -102,7 +103,7 @@ public void captureRef(int tag, ReadableMap options, Promise promise) {
uiManager.addUIBlock(new ViewShot(
tag, extension, imageFormat, quality,
scaleWidth, scaleHeight, outputFile, resultStreamFormat,
snapshotContentContainer, reactContext, activity, promise)
snapshotContentContainer, reactContext, activity, handleGLSurfaceView, promise)
);
} catch (final Throwable ex) {
Log.e(RNVIEW_SHOT, "Failed to snapshot view tag " + tag, ex);
Expand Down
Expand Up @@ -8,16 +8,20 @@
import android.graphics.Paint;
import android.graphics.Point;
import android.net.Uri;

import android.os.Build;
import android.os.Handler;
import androidx.annotation.IntDef;
import androidx.annotation.NonNull;
import androidx.annotation.StringDef;

import android.os.Build;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.util.Base64;
import android.util.Log;
import android.view.PixelCopy;
import android.view.SurfaceView;
import android.view.TextureView;
import android.view.View;
import android.view.ViewGroup;
Expand All @@ -44,6 +48,8 @@
import java.util.Locale;
import java.util.Set;
import java.util.WeakHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.zip.Deflater;

import javax.annotation.Nullable;
Expand Down Expand Up @@ -71,6 +77,10 @@ public class ViewShot implements UIBlock, LifecycleEventListener {
* ARGB size in bytes.
*/
private static final int ARGB_SIZE = 4;
/**
* Wait timeout for surface view capture.
*/
private static final int SURFACE_VIEW_READ_PIXELS_TIMEOUT = 5;

private HandlerThread mBgThread;
private Handler mBgHandler;
Expand Down Expand Up @@ -157,6 +167,7 @@ public void run() {
private final Boolean snapshotContentContainer;
@SuppressWarnings({"unused", "FieldCanBeLocal"})
private final ReactApplicationContext reactContext;
private final boolean handleGLSurfaceView;
private final Activity currentActivity;
//endregion

Expand All @@ -174,6 +185,7 @@ public ViewShot(
final Boolean snapshotContentContainer,
final ReactApplicationContext reactContext,
final Activity currentActivity,
final boolean handleGLSurfaceView,
final Promise promise) {
this.tag = tag;
this.extension = extension;
Expand All @@ -186,6 +198,7 @@ public ViewShot(
this.snapshotContentContainer = snapshotContentContainer;
this.reactContext = reactContext;
this.currentActivity = currentActivity;
this.handleGLSurfaceView = handleGLSurfaceView;
this.promise = promise;

reactContext.addLifecycleEventListener(this);
Expand Down Expand Up @@ -405,26 +418,54 @@ private Point captureViewImpl(@NonNull final View view, @NonNull final OutputStr

for (final View child : childrenList) {
// skip any child that we don't know how to process
if (!(child instanceof TextureView)) continue;

// skip all invisible to user child views
if (child.getVisibility() != VISIBLE) continue;

final TextureView tvChild = (TextureView) child;
tvChild.setOpaque(false); // <-- switch off background fill

// NOTE (olku): get re-usable bitmap. TextureView should use bitmaps with matching size,
// otherwise content of the TextureView will be scaled to provided bitmap dimensions
final Bitmap childBitmapBuffer = tvChild.getBitmap(getExactBitmapForScreenshot(child.getWidth(), child.getHeight()));

final int countCanvasSave = c.save();
applyTransformations(c, view, child);

// due to re-use of bitmaps for screenshot, we can get bitmap that is bigger in size than requested
c.drawBitmap(childBitmapBuffer, 0, 0, paint);

c.restoreToCount(countCanvasSave);
recycleBitmap(childBitmapBuffer);
if (child instanceof TextureView) {
// skip all invisible to user child views
if (child.getVisibility() != VISIBLE) continue;

final TextureView tvChild = (TextureView) child;
tvChild.setOpaque(false); // <-- switch off background fill

// NOTE (olku): get re-usable bitmap. TextureView should use bitmaps with matching size,
// otherwise content of the TextureView will be scaled to provided bitmap dimensions
final Bitmap childBitmapBuffer = tvChild.getBitmap(getExactBitmapForScreenshot(child.getWidth(), child.getHeight()));

final int countCanvasSave = c.save();
applyTransformations(c, view, child);

// due to re-use of bitmaps for screenshot, we can get bitmap that is bigger in size than requested
c.drawBitmap(childBitmapBuffer, 0, 0, paint);

c.restoreToCount(countCanvasSave);
recycleBitmap(childBitmapBuffer);
} else if (child instanceof SurfaceView && handleGLSurfaceView) {
final SurfaceView svChild = (SurfaceView)child;
final CountDownLatch latch = new CountDownLatch(1);

if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
final Bitmap childBitmapBuffer = getExactBitmapForScreenshot(child.getWidth(), child.getHeight());
try {
PixelCopy.request(svChild, childBitmapBuffer, new PixelCopy.OnPixelCopyFinishedListener() {
@Override
public void onPixelCopyFinished(int copyResult) {
final int countCanvasSave = c.save();
applyTransformations(c, view, child);
c.drawBitmap(childBitmapBuffer, 0, 0, paint);
c.restoreToCount(countCanvasSave);
recycleBitmap(childBitmapBuffer);
latch.countDown();
}
}, new Handler(Looper.getMainLooper()));
latch.await(SURFACE_VIEW_READ_PIXELS_TIMEOUT, TimeUnit.SECONDS);
} catch (Exception e) {
Log.e(TAG, "Cannot PixelCopy for " + svChild, e);
}
} else {
Bitmap cache = svChild.getDrawingCache();
if (cache != null) {
c.drawBitmap(svChild.getDrawingCache(), 0, 0, paint);
}
}
}
}

if (width != null && height != null && (width != w || height != h)) {
Expand Down
4 changes: 2 additions & 2 deletions apps/bare-expo/ios/Podfile.lock
Expand Up @@ -634,7 +634,7 @@ PODS:
- React-Core
- react-native-slider (4.2.3):
- React-Core
- react-native-view-shot (3.3.0):
- react-native-view-shot (3.4.0):
- React-Core
- react-native-viewpager (5.0.11):
- React-Core
Expand Down Expand Up @@ -1354,7 +1354,7 @@ SPEC CHECKSUMS:
react-native-safe-area-context: 6c12e3859b6f27b25de4fee8201cfb858432d8de
react-native-segmented-control: 06607462630512ff8eef652ec560e6235a30cc3e
react-native-slider: 98b724cd3e44c3454a6d0724e796d4e9c52189ce
react-native-view-shot: da768466e1cd371de50a3a5c722d1e95456b5b2c
react-native-view-shot: a60a98a18c72bcaaaf2138f9aab960ae9b0d96c7
react-native-viewpager: b99b53127d830885917ef84809c5065edd614a78
react-native-webview: d33e2db8925d090871ffeb232dfa50cb3a727581
React-perflogger: 6009895616a455781293950bbd63d53cfc7ffbc5
Expand Down
2 changes: 1 addition & 1 deletion apps/bare-expo/package.json
Expand Up @@ -118,7 +118,7 @@
"react-native-screens": "~3.18.0",
"react-native-shared-element": "0.8.4",
"react-native-svg": "12.3.0",
"react-native-view-shot": "3.3.0",
"react-native-view-shot": "3.4.0",
"react-native-webview": "11.23.1",
"test-suite": "*"
},
Expand Down
2 changes: 1 addition & 1 deletion apps/native-component-list/package.json
Expand Up @@ -155,7 +155,7 @@
"react-native-screens": "~3.18.0",
"react-native-shared-element": "0.8.4",
"react-native-svg": "12.3.0",
"react-native-view-shot": "3.3.0",
"react-native-view-shot": "3.4.0",
"react-native-web": "~0.18.9",
"react-native-webview": "11.23.1",
"react-navigation": "^4.4.0",
Expand Down
2 changes: 1 addition & 1 deletion packages/expo/bundledNativeModules.json
Expand Up @@ -99,7 +99,7 @@
"react-native-screens": "~3.18.0",
"react-native-shared-element": "0.8.4",
"react-native-svg": "12.3.0",
"react-native-view-shot": "3.3.0",
"react-native-view-shot": "3.4.0",
"react-native-webview": "11.23.1",
"sentry-expo": "~5.0.0",
"unimodules-app-loader": "~3.1.0",
Expand Down
8 changes: 4 additions & 4 deletions yarn.lock
Expand Up @@ -17298,10 +17298,10 @@ react-native-svg@12.3.0:
css-select "^4.2.1"
css-tree "^1.0.0-alpha.39"

react-native-view-shot@3.3.0:
version "3.3.0"
resolved "https://registry.yarnpkg.com/react-native-view-shot/-/react-native-view-shot-3.3.0.tgz#7f0c6d2e09e5af770f5b74231a72625b379d60f8"
integrity sha512-dc3ZHCd0lvn1jtSI8bPQDta8YxzCvZ73vA8zzFH4S3TRlXLe8r5DF3wUUBlWv1p/bxbEa/A0J4kMUPeVt/v8TQ==
react-native-view-shot@3.4.0:
version "3.4.0"
resolved "https://registry.yarnpkg.com/react-native-view-shot/-/react-native-view-shot-3.4.0.tgz#787b31b2d0525a197864e12aaea214e905e97f9a"
integrity sha512-b0CcWJGO0xLCXRsstIYRUEg/UStrR7uujQV9jFHRIVyPfBH0gRplT7Vlgimr+PX+Xg+9/rCyIKPjqK1Knv8hxg==

react-native-web@~0.18.9:
version "0.18.9"
Expand Down

0 comments on commit 366e33a

Please sign in to comment.