From 07782946974b22e6b8a7a106e807d88c6ce66489 Mon Sep 17 00:00:00 2001 From: Nicolas Morin Date: Sat, 20 Jan 2018 19:50:42 +0100 Subject: [PATCH] Fix performance issue on Android: add option to clear window background when camera starts --- README.md | 8 ++++++ .../lwansbrough/RCTCamera/RCTCameraView.java | 9 +++++++ .../RCTCamera/RCTCameraViewFinder.java | 27 ++++++++++++++++++- .../RCTCamera/RCTCameraViewManager.java | 5 ++++ src/Camera.js | 18 ++++++------- 5 files changed, 57 insertions(+), 10 deletions(-) diff --git a/README.md b/README.md index 59ffcc5..ca72fe3 100644 --- a/README.md +++ b/README.md @@ -347,6 +347,14 @@ from javascript. If set to `true`, the device will not sleep while the camera preview is visible. This mimics the behavior of the default camera app, which keeps the device awake while open. +#### `Android` `clearWindowBackground` + +Values: +`true` +`false` (default) + +If you encounter performance issue while using a window background drawable (typically defined in theme to emulate splashscreen behavior), set this to true to automatically clear window background once camera is started. + #### `Android` `permissionDialogTitle` Starting on android M individual permissions must be granted for certain services, the camera is one of them, you can use this to change the title of the dialog prompt requesting permissions. diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java index 4f9de66..0ff5a0b 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraView.java @@ -24,6 +24,7 @@ public class RCTCameraView extends ViewGroup { private String _captureQuality = "high"; private int _torchMode = -1; private int _flashMode = -1; + private boolean _clearWindowBackground = false; public RCTCameraView(Context context) { super(context); @@ -77,6 +78,7 @@ public class RCTCameraView extends ViewGroup { if (-1 != this._torchMode) { _viewFinder.setTorchMode(this._torchMode); } + _viewFinder.setClearWindowBackground(this._clearWindowBackground); addView(_viewFinder); } } @@ -124,6 +126,13 @@ public class RCTCameraView extends ViewGroup { RCTCamera.getInstance().setBarCodeTypes(types); } + public void setClearWindowBackground(boolean clearWindowBackground) { + this._clearWindowBackground = clearWindowBackground; + if (this._viewFinder != null) { + this._viewFinder.setClearWindowBackground(clearWindowBackground); + } + } + private boolean setActualDeviceOrientation(Context context) { int actualDeviceOrientation = getDeviceOrientation(context); if (_actualDeviceOrientation != actualDeviceOrientation) { diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java index 39b7741..a2c6729 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewFinder.java @@ -4,7 +4,9 @@ package com.lwansbrough.RCTCamera; +import android.app.Activity; import android.content.Context; +import android.content.ContextWrapper; import android.graphics.Rect; import android.graphics.SurfaceTexture; import android.hardware.Camera; @@ -41,6 +43,7 @@ class RCTCameraViewFinder extends TextureView implements TextureView.SurfaceText private boolean _isStarting; private boolean _isStopping; private Camera _camera; + private boolean _clearWindowBackground = false; private float mFingerSpacing; // concurrency lock for barcode scanner to avoid flooding the runtime @@ -124,6 +127,11 @@ class RCTCameraViewFinder extends TextureView implements TextureView.SurfaceText RCTCamera.getInstance().setFlashMode(_cameraType, flashMode); } + public void setClearWindowBackground(boolean clearWindowBackground) { + this._clearWindowBackground = clearWindowBackground; + } + + private void startPreview() { if (_surfaceTexture != null) { startCamera(); @@ -180,6 +188,12 @@ class RCTCameraViewFinder extends TextureView implements TextureView.SurfaceText _camera.setParameters(parameters); _camera.setPreviewTexture(_surfaceTexture); _camera.startPreview(); + // clear window background if needed + if (_clearWindowBackground) { + Activity activity = getActivity(); + if (activity != null) + activity.getWindow().setBackgroundDrawable(null); + } // send previews to `onPreviewFrame` _camera.setPreviewCallback(this); } catch (NullPointerException e) { @@ -213,6 +227,17 @@ class RCTCameraViewFinder extends TextureView implements TextureView.SurfaceText } } + private Activity getActivity() { + Context context = getContext(); + while (context instanceof ContextWrapper) { + if (context instanceof Activity) { + return (Activity)context; + } + context = ((ContextWrapper)context).getBaseContext(); + } + return null; + } + /** * Parse barcodes as BarcodeFormat constants. * @@ -500,4 +525,4 @@ class RCTCameraViewFinder extends TextureView implements TextureView.SurfaceText float y = event.getY(0) - event.getY(1); return (float) Math.sqrt(x * x + y * y); } -} \ No newline at end of file +} diff --git a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewManager.java b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewManager.java index 2a596e1..9dc6259 100644 --- a/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewManager.java +++ b/android/src/main/java/com/lwansbrough/RCTCamera/RCTCameraViewManager.java @@ -86,4 +86,9 @@ public class RCTCameraViewManager extends ViewGroupManager { } view.setBarCodeTypes(result); } + + @ReactProp(name = "clearWindowBackground") + public void setClearWindowBackground(RCTCameraView view, boolean clearWindowBackground) { + view.setClearWindowBackground(clearWindowBackground); + } } diff --git a/src/Camera.js b/src/Camera.js index 673dec2..543f0f8 100644 --- a/src/Camera.js +++ b/src/Camera.js @@ -87,6 +87,7 @@ export default class Camera extends Component { onBarCodeRead: PropTypes.func, barcodeScannerEnabled: PropTypes.bool, cropToPreview: PropTypes.bool, + clearWindowBackground: PropTypes.bool, onFocusChanged: PropTypes.func, onZoomChanged: PropTypes.func, mirrorImage: PropTypes.bool, @@ -117,6 +118,7 @@ export default class Camera extends Component { torchMode: CameraManager.TorchMode.off, mirrorImage: false, cropToPreview: false, + clearWindowBackground: false, barCodeTypes: Object.values(CameraManager.BarCodeType), permissionDialogTitle: '', permissionDialogMessage: '', @@ -191,18 +193,16 @@ export default class Camera extends Component { message: this.props.permissionDialogMessage, }); - // On devices before SDK version 23, the permissions are automatically granted if they appear in the manifest, + // On devices before SDK version 23, the permissions are automatically granted if they appear in the manifest, // so check and request should always be true. // https://github.com/facebook/react-native-website/blob/master/docs/permissionsandroid.md - const isAuthorized = Platform.Version >= 23 - ? granted === PermissionsAndroid.RESULTS.GRANTED - : granted === true; - + const isAuthorized = + Platform.Version >= 23 ? granted === PermissionsAndroid.RESULTS.GRANTED : granted === true; + this.setState({ - isAuthorized, - isAuthorizationChecked: true + isAuthorized, + isAuthorizationChecked: true, }); - } else { this.setState({ isAuthorized: true, isAuthorizationChecked: true }); } @@ -276,7 +276,7 @@ export default class Camera extends Component { mirrorImage: props.mirrorImage, fixOrientation: props.fixOrientation, cropToPreview: props.cropToPreview, - ...options + ...options, }; if (options.mode === Camera.constants.CaptureMode.video) {