mrousavy / react-native-vision-camera

📸 A powerful, high-performance React Native Camera library.
https://react-native-vision-camera.com
MIT License
7.64k stars 1.11k forks source link

🐛 <Camera> is located at top left corner on its first start - while it is expected at the center of the window #3237

Open oliviermartin opened 1 month ago

oliviermartin commented 1 month ago

What's happening?

In my simple app, the first time I start it, the is located at the top left corner of the screen while I expect it to be in the middle of the screen. But when coming back on the screen, the is now located in the middle of the screen.

What I see: Screenshot_20241010-225012_KeypMe

On the screen reload: Screenshot_20241010-225046_KeypMe

Reproduceable Code

import React from 'react';
import {
  Linking,
  StyleSheet,
  View,
} from 'react-native';
import type {CameraPermissionStatus} from 'react-native-vision-camera';
import {
  Camera,
  useCameraDevice,
} from 'react-native-vision-camera';

const styles = StyleSheet.create({
  content: {flex: 1, alignItems: 'center', justifyContent: 'center'},
  camera_view: {
    paddingBottom: 20,
    alignItems: 'center',
    justifyContent: 'center',
  },
  camera: {width: 150, height: 300, zIndex: 0},
});

function App(props): React.JSX.Element {
  const [isCameraActive, setActiveCamera] = React.useState(true);
  const [cameraPosition, setCameraPosition] = React.useState<'front' | 'back'>(
    'front',
  );
  const [cameraPermissionStatus, setCameraPermissionStatus] =
    React.useState<CameraPermissionStatus>('not-determined');
  const cameraRef = React.useRef<Camera>(null);
  let cameraDevice = useCameraDevice(cameraPosition);

  const requestCameraPermission = React.useCallback(async () => {
    const permission = await Camera.requestCameraPermission();
    console.log(`Camera permission status: ${permission}`);

    if (permission === 'denied') {
      await Linking.openSettings();
    }
    setCameraPermissionStatus(permission);
  }, []);

  React.useEffect(
    () => {
      if (cameraPermissionStatus !== 'granted') {
        requestCameraPermission();
      }
    },
  );

  console.log("cameraDevice:" + JSON.stringify(cameraDevice, (k, v) => k === "formats" ? [] : v, 2))

  return (
    <View style={styles.content}>
      { cameraDevice !== undefined && (
        <View style={styles.camera_view}>
          <Camera
            ref={cameraRef}
            device={cameraDevice}
            photo={true}
            isActive={isCameraActive}
            style={styles.camera}
          />
        </View>
      )}
    </View>
  );
}

export default App;

Relevant log output

First run (camera top-left)
---------------------------

10-10 22:56:26.267 11911 28988 I ReactNativeJS: Running "Demo" with {"rootTag":11,"initialProps":{},"fabric":true}
10-10 22:56:28.516 11911 28988 I ReactNativeJS: cameraDevice:undefined
10-10 22:56:29.739 11911 28988 I ReactNativeJS: cameraDevice:{
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "formats": [],
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "sensorOrientation": "landscape-right",
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "hardwareLevel": "limited",
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "maxZoom": 4,
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "minZoom": 1,
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "maxExposure": 20,
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "supportsLowLightBoost": false,
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "neutralZoom": 1,
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "physicalDevices": [
10-10 22:56:29.739 11911 28988 I ReactNativeJS:     "wide-angle-camera"
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   ],
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "supportsFocus": true,
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "supportsRawCapture": false,
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "isMultiCam": false,
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "minFocusDistance": 0,
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "minExposure": -20,
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "name": "1 (FRONT) androidx.camera.camera2",
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "hasFlash": false,
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "hasTorch": false,
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "position": "front",
10-10 22:56:29.739 11911 28988 I ReactNativeJS:   "id": "1"
10-10 22:56:29.739 11911 28988 I ReactNativeJS: }
10-10 22:56:42.698  3844  5208 I SurfaceFlinger: id=2022 createSurf (0x0),-1 flag=80004, d913107 Splash Screen com.demo#0
10-10 22:56:42.701  4218  4245 I ViewRootImpl@ed06b46[demo]: setView = com.android.internal.policy.DecorView@55685d TM=true
10-10 22:56:42.709  4218  4245 V WindowManager: Relayout Window{d913107 u0 Splash Screen com.demo}: viewVisibility=0 req=720x1560
10-10 22:56:42.713  4218  4245 D WindowManager: isScreenshotDisabledLocked - win: Window{d913107 u0 Splash Screen com.demo}
10-10 22:56:42.714  3844  5208 I SurfaceFlinger: id=2023 createSurf (720x1560),1 flag=404, Splash Screen com.demo#0
10-10 22:56:42.715  4218  4245 D WindowManager: makeSurface duration=2 name=Splash Screen com.demo
10-10 22:56:42.720 11911 11911 W unknown:BridgelessReact: ReactHost{0}.onHostResume(activity)
10-10 22:56:42.720 11911 11911 W unknown:BridgelessReact: ReactContext.onHostResume()
10-10 22:56:42.722  4218  4245 I ViewRootImpl@ed06b46[demo]: Relayout returned: old=(0,0,720,1560) new=(0,0,720,1560) req=(720,1560)0 dur=11 res=0x7 s={true 525462839296} ch=true fn=-1
10-10 22:56:42.723  4218  4245 I ViewRootImpl@ed06b46[demo]: [DP] dp(1) 1 android.view.ViewRootImpl.reportNextDraw:10957 android.view.ViewRootImpl.performTraversals:3845 android.view.ViewRootImpl.doTraversal:2618 
10-10 22:56:42.736  4218  4245 I ViewRootImpl@ed06b46[demo]: [DP] pdf(0) 1 android.view.ViewRootImpl.performDraw:4809 android.view.ViewRootImpl.performTraversals:3866 android.view.ViewRootImpl.doTraversal:2618 
10-10 22:56:42.736  4218  4245 I ViewRootImpl@ed06b46[demo]: [DP] rdf()
10-10 22:56:42.737  4218  4245 D WindowManager: finishDrawingWindow: Window{d913107 u0 Splash Screen com.demo} mDrawState=DRAW_PENDING
10-10 22:56:42.840 11911 28804 I com.demo: Background concurrent copying GC freed 10598(641KB) AllocSpace objects, 0(0B) LOS objects, 49% free, 6390KB/12MB, paused 365us total 165.063ms
10-10 22:56:42.861  3844  3844 D SurfaceFlinger:      DEVICE | 0x7e178150c0 | 0002 | RGBA_8888    |  165.0  322.0  555.0 1167.0 |    0    0  720 1560 | Splash Screen com.demo#0
10-10 22:56:42.925  4218  4218 D MdnieScenarioControlService:  packageName : com.demo    className : com.demo.MainActivity
10-10 22:56:42.930  4218  4245 I ViewRootImpl@ed06b46[demo]: MSG_RESIZED_REPORT: frame=(0,0,720,1560) ci=(0,58,0,96) vi=(0,58,0,96) or=1
10-10 22:56:42.931  4218  4245 I ViewRootImpl@ed06b46[demo]: [DP] dp(1) 1 android.view.ViewRootImpl.reportNextDraw:10957 android.view.ViewRootImpl.access$1200:256 android.view.ViewRootImpl$ViewRootHandler.handleMessage:6101 
10-10 22:56:42.937  4218  4245 V WindowManager: Relayout Window{d913107 u0 Splash Screen com.demo}: viewVisibility=0 req=720x1560
10-10 22:56:42.942  4218  4245 I ViewRootImpl@ed06b46[demo]: Relayout returned: old=(0,0,720,1560) new=(0,0,720,1560) req=(720,1560)0 dur=4 res=0x1 s={true 525462839296} ch=false fn=2
10-10 22:56:42.965  4218  4245 I ViewRootImpl@ed06b46[demo]: [DP] pdf(0) 1 android.view.ViewRootImpl.performDraw:4809 android.view.ViewRootImpl.performTraversals:3866 android.view.ViewRootImpl.doTraversal:2618 
10-10 22:56:42.965  4218  4245 I ViewRootImpl@ed06b46[demo]: [DP] rdf()
10-10 22:56:42.965  4218  4245 D WindowManager: finishDrawingWindow: Window{d913107 u0 Splash Screen com.demo} mDrawState=HAS_DRAWN
10-10 22:56:43.012 11911 11911 W unknown:ViewManagerPropertyUpdater: Could not find generated setter for class com.facebook.react.uimanager.RootViewManager
10-10 22:56:43.016  4218  7139 V WindowManager: Relayout Window{657b232 u0 com.demo/com.demo.MainActivity}: viewVisibility=0 req=720x1560
10-10 22:56:43.019  4218  7139 D WindowManager: isScreenshotDisabledLocked - win: Window{657b232 u0 com.demo/com.demo.MainActivity}
10-10 22:56:43.020  3844  3866 I SurfaceFlinger: id=2027 createSurf (720x1560),1 flag=404, com.demo/com.demo.MainActivity$_11911#0
10-10 22:56:43.022  4218  7139 D WindowManager: makeSurface duration=2 name=com.demo/com.demo.MainActivity$_11911
10-10 22:56:43.025  4218  7139 V WindowManager: Changing focus from null to Window{657b232 u0 com.demo/com.demo.MainActivity} displayId=0 Callers=com.android.server.wm.RootWindowContainer.updateFocusedWindowLocked:567 com.android.server.wm.WindowManagerService.updateFocusedWindowLocked:6316 com.android.server.wm.WindowManagerService.relayoutWindow:2718 com.android.server.wm.Session.relayout:219 
10-10 22:56:43.178  4218  7139 D WindowManager: finishDrawingWindow: Window{657b232 u0 com.demo/com.demo.MainActivity} mDrawState=DRAW_PENDING
10-10 22:56:43.185  4218  4245 D PkgPredictorService: pkg:com.demo activity:com.demo.MainActivity thisTime:-1
10-10 22:56:43.192  4218  4245 D ViewRootImpl@ed06b46[demo]: dispatchDetachedFromWindow: reset blurmask
10-10 22:56:43.192  4218  4245 I ViewRootImpl@ed06b46[demo]: dispatchDetachedFromWindow
10-10 22:56:43.205  4218  4245 I WindowManager: Reparenting to leash, surface=Surface(name=d913107 Splash Screen com.demo)/@0x20aade3, leashParent=Surface(name=ActivityRecord{2f8216d u0 com.demo/.MainActivity t1077})/@0x1963e0
10-10 22:56:43.206  3844  3866 I SurfaceFlinger: id=2030 createSurf (0x0),-1 flag=24000, Surface(name=d913107 Splash Screen com.demo)/@0x20aade3 - animation-leash#0
10-10 22:56:43.206  4218  4245 D WindowManager: makeSurface duration=1 leash=Surface(name=Surface(name=d913107 Splash Screen com.demo)/@0x20aade3 - animation-leash)/@0x67df699
10-10 22:56:43.212  3844  3844 D SurfaceFlinger:      DEVICE | 0x7e9b860200 | 0002 | RGBA_8888    |    5.0   10.0  715.0 1548.0 |    0    0  720 1560 | com.demo/com.demo.MainActivity$_11911#0
10-10 22:56:43.212  3844  3844 D SurfaceFlinger:      DEVICE | 0x7e17814800 | 0002 | RGBA_8888    |    5.0   10.0  715.0 1548.0 |    0    0  720 1560 | Splash Screen com.demo#0
10-10 22:56:43.256 11911 11911 V InputMethodManager: Starting input: tba=com.demo ic=null mNaviBarColor -855310 mIsGetNaviBarColorSuccess true , NavVisible : true , NavTrans : false
10-10 22:56:43.268  4218  4245 I WindowManager: Reparenting to original parent: Surface(name=ActivityRecord{2f8216d u0 com.demo/.MainActivity t1077})/@0x1963e0, destroy=true, surface=Surface(name=d913107 Splash Screen com.demo)/@0x20aade3
10-10 22:56:43.291  3844  3844 D SurfaceFlinger:      DEVICE | 0x7e9b860480 | 0002 | RGBA_8888    |    0.0    0.0  720.0 1560.0 |    0    0  720 1560 | com.demo/com.demo.MainActivity$_11911#0
10-10 22:56:43.306  4218  4245 E WindowManager: win=Window{d913107 u0 Splash Screen com.demo EXITING} destroySurfaces: appStopped=false win.mWindowRemovalAllowed=true win.mRemoveOnExit=true win.mViewVisibility=0 caller=com.android.server.wm.ActivityRecord.destroySurfaces:5257 com.android.server.wm.ActivityRecord.destroySurfaces:5238 com.android.server.wm.WindowState.onExitAnimationDone:5637 com.android.server.wm.WindowStateAnimator.onAnimationFinished:332 com.android.server.wm.WindowState.onAnimationFinished:6102 com.android.server.wm.-$$Lambda$dwJG8BAnLlvKNGuDY9U3-haNY4M.onAnimationFinished:2 com.android.server.wm.SurfaceAnimator.lambda$getFinishedCallback$0$SurfaceAnimator:112 
10-10 22:56:43.306  4218  4245 I WindowManager: Destroying surface Surface(name=Splash Screen com.demo)/@0xc34a0e called by com.android.server.wm.WindowStateAnimator.destroySurface:1794 com.android.server.wm.WindowStateAnimator.destroySurfaceLocked:765 com.android.server.wm.WindowState.destroySurfaceUnchecked:3932 com.android.server.wm.WindowState.destroySurface:3906 com.android.server.wm.ActivityRecord.destroySurfaces:5257 com.android.server.wm.ActivityRecord.destroySurfaces:5238 com.android.server.wm.WindowState.onExitAnimationDone:5637 com.android.server.wm.WindowStateAnimator.onAnimationFinished:332 
10-10 22:56:43.307  3844  3866 I Layer   : id=2023 removeFromCurrentState Splash Screen com.demo#0 (57)
10-10 22:56:43.310  3844  5002 I Layer   : id=2022 removeFromCurrentState d913107 Splash Screen com.demo#0 (57)
10-10 22:56:43.310  3844  5002 I Layer   : id=2030 removeFromCurrentState Surface(name=d913107 Splash Screen com.demo)/@0x20aade3 - animation-leash#0 (57)
10-10 22:56:43.310  3844  3867 I SurfaceFlinger: id=2022 Removed d913107 Splash Screen com.demo#0 (57)
10-10 22:56:43.311  3844  3867 I SurfaceFlinger: id=2030 Removed Surface(name=d913107 Splash Screen com.demo)/@0x20aade3 - animation-leash#0 (57)
10-10 22:56:43.311  3844  3867 I SurfaceFlinger: id=2023 Removed Splash Screen com.demo#0 (57)
10-10 22:56:43.319  3844  3844 I Layer   : id=2030[1] Destroyed Surface(name=d913107 Splash Screen com.demo)/@0x20aade3 - animation-leash#0
10-10 22:56:43.319  3844  3844 I Layer   : id=2022[1] Destroyed d913107 Splash Screen com.demo#0
10-10 22:56:43.319  3844  3844 I Layer   : id=2023[1] Destroyed Splash Screen com.demo#0
10-10 22:56:43.326  4218  4245 D ActivityTaskManager: finishFixedRotationTransform, r=ActivityRecord{2f8216d u0 com.demo/.MainActivity t1077}, caller=com.android.server.wm.WindowToken.finishFixedRotationTransform:664 com.android.server.wm.DisplayContent$FixedRotationTransitionListener.onAppTransitionFinishedLocked:7025 com.android.server.wm.AppTransition.notifyAppTransitionFinishedLocked:552 com.android.server.wm.ActivityRecord.onAnimationFinished:7170 com.android.server.wm.WindowContainer.doAnimationFinished:2626 
10-10 22:56:43.624  3882  6494 I CameraService: CameraService::connect call (PID -1 "com.demo", camera ID 1) for HAL version default and Camera API version 2
10-10 22:56:43.634  3882  6494 I CameraService: CameraService::validateClientPermissionsLocked is ok : calling pid 11911, calling uid 10408, client com.demo , cameraservice pid=3882, device user 0, currently allowed device users: 0
10-10 22:56:43.640  3882  6494 I Camera2ClientBase: Camera 1: Opened. Client: com.demo (PID 11911, UID 10408)
10-10 22:56:43.645  3882  6494 I CameraService: service.camera.client set to com.demo
10-10 22:56:43.645  3882  6494 I CameraService: startCameraOps: Start camera ops, package name = com.demo, client UID = 10408
10-10 22:56:43.652  3882  6494 I CameraService: updateProxyDeviceState: notifyCameraState for Camera ID 1,  newState 0, facing 1, clientName com.demo, apiLevel 2
10-10 22:56:43.653  4218  7119 I CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_OPEN for client com.demo API Level 2
10-10 22:56:43.654  4620  4906 I CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_OPEN for client com.demo API Level 2
10-10 22:56:43.655  7193  7493 I CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_OPEN for client com.demo API Level 2
10-10 22:56:43.691 11911 28811 I CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_OPEN for client com.demo API Level 2
10-10 22:56:43.710  3800  3965 I ExynosCameraConfigurationsSec: [CAM(1)][Front_0]-(checkClientPackageName[1493]):packageName (com.demo) cameraClient (0)
10-10 22:56:43.729 11911 11911 V InputMethodManager: Starting input: tba=com.demo ic=null mNaviBarColor -855310 mIsGetNaviBarColorSuccess true , NavVisible : true , NavTrans : false
10-10 22:56:43.881  4218  7129 V WindowManager: Relayout Window{657b232 u0 com.demo/com.demo.MainActivity}: viewVisibility=0 req=720x1560
10-10 22:56:43.916  3844  3866 I SurfaceFlinger: id=2032 createSurf (0x0),-1 flag=80004, Bounds for - com.demo/com.demo.MainActivity@0#0
10-10 22:56:43.919  3844  3866 I SurfaceFlinger: id=2033 createSurf (960x720),4 flag=404, SurfaceView - com.demo/com.demo.MainActivity@4bfe9bb@0#0
10-10 22:56:43.920  3844  3866 I SurfaceFlinger: id=2034 createSurf (0x0),-1 flag=20404, Background for -SurfaceView - com.demo/com.demo.MainActivity@4bfe9bb@0#0
10-10 22:56:43.930  4218  7119 D WindowManager: finishDrawingWindow: Window{657b232 u0 com.demo/com.demo.MainActivity} mDrawState=HAS_DRAWN
10-10 22:56:43.941 11911 29272 I SurfaceView: applySurfaceTransforms: t = android.view.SurfaceControl$Transaction@acf15fa surfaceControl = Surface(name=SurfaceView - com.demo/com.demo.MainActivity@4bfe9bb@0)/@0xc3ab7ab frame = 4
10-10 22:56:43.943  3844  3844 D SurfaceFlinger:  SOLID_COLOR |              | 0002 |  Unknown  |    0.0    0.0    0.0    0.0 |    0   58  720  778 | Background for -SurfaceView - com.la[...]part.demo.MainActivity@4bfe9bb@0#0
10-10 22:56:43.943  3844  3844 D SurfaceFlinger:      DEVICE | 0x7e9b85f800 | 0000 | RGBA_8888    |    0.0    0.0  720.0 1560.0 |    0    0  720 1560 | com.demo/com.demo.MainActivity$_11911#0
10-10 22:56:43.977 11911 29273 I SurfaceView: applySurfaceTransforms: t = android.view.SurfaceControl$Transaction@acf15fa surfaceControl = Surface(name=SurfaceView - com.demo/com.demo.MainActivity@4bfe9bb@0)/@0xc3ab7ab frame = 5
10-10 22:56:44.648  3882  3984 I CameraService: updateProxyDeviceState: notifyCameraState for Camera ID 1,  newState 1, facing 1, clientName com.demo, apiLevel 2
10-10 22:56:44.649  4218  7129 I CameraService_proxy: updateActivityCount: addNonHighRefreshRatePackage for client(com.demo)
10-10 22:56:44.649  7193  7493 I CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_ACTIVE for client com.demo API Level 2
10-10 22:56:44.652  4218  7139 I CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_ACTIVE for client com.demo API Level 2
10-10 22:56:44.653  4620  4906 I CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_ACTIVE for client com.demo API Level 2
10-10 22:56:44.657 11911 28993 I CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_ACTIVE for client com.demo API Level 2
10-10 22:56:44.684  3844  3844 D SurfaceFlinger:      CLIENT | 0x7e17813540 | 0002 | 0x0000022    |    0.0    0.0  960.0  600.0 |    0   57  375  658 | SurfaceView - com.demo/co[...]part.demo.MainActivity@4bfe9bb@0#0
10-10 22:56:44.684  3844  3844 D SurfaceFlinger:      CLIENT | 0x7e9b860480 | 0000 | RGBA_8888    |    0.0    0.0  720.0 1560.0 |    0    0  720 1560 | com.demo/com.demo.MainActivity$_11911#0

Second run (camera middle)
--------------------------

10-10 23:00:23.236 29639 30650 I ReactNativeJS: Bridgeless mode is enabled
10-10 23:00:23.776 29639 30650 I ReactNativeJS: Running "Demo" with {"rootTag":51,"initialProps":{},"fabric":true}
10-10 23:00:24.618 29639 30650 I ReactNativeJS: cameraDevice:{
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "formats": [],
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "sensorOrientation": "landscape-right",
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "hardwareLevel": "limited",
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "maxZoom": 4,
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "minZoom": 1,
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "maxExposure": 20,
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "supportsLowLightBoost": false,
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "neutralZoom": 1,
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "physicalDevices": [
10-10 23:00:24.618 29639 30650 I ReactNativeJS:     "wide-angle-camera"
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   ],
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "supportsFocus": true,
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "supportsRawCapture": false,
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "isMultiCam": false,
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "minFocusDistance": 0,
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "minExposure": -20,
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "name": "1 (FRONT) androidx.camera.camera2",
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "hasFlash": false,
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "hasTorch": false,
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "position": "front",
10-10 23:00:24.618 29639 30650 I ReactNativeJS:   "id": "1"
10-10 23:00:24.618 29639 30650 I ReactNativeJS: }
10-10 23:00:24.670  4218  4785 D ActivityTaskManager: TaskLaunchParamsModifier:task=Task{6c99a92 #1079 visible=false type=standard mode=fullscreen translucent=true A=10408:com.demo U=0 StackId=1079 sz=1} activity=ActivityRecord{460e959 u0 com.google.android.permissioncontroller/com.android.permissioncontroller.permission.ui.GrantPermissionsActivity t-1} display-from-task=0 task-display-area=DefaultTaskDisplayArea@21657849 display-area-windowing-mode=1 inherit-from-source=fullscreen activity-options-fullscreen=Rect(0, 0 - 0, 0) non-freeform-display maximized-bounds
10-10 23:00:24.702 29639 30650 I ReactNativeJS: cameraDevice:{
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "formats": [],
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "sensorOrientation": "landscape-right",
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "hardwareLevel": "limited",
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "maxZoom": 4,
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "minZoom": 1,
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "maxExposure": 20,
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "supportsLowLightBoost": false,
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "neutralZoom": 1,
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "physicalDevices": [
10-10 23:00:24.702 29639 30650 I ReactNativeJS:     "wide-angle-camera"
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   ],
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "supportsFocus": true,
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "supportsRawCapture": false,
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "isMultiCam": false,
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "minFocusDistance": 0,
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "minExposure": -20,
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "name": "1 (FRONT) androidx.camera.camera2",
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "hasFlash": false,
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "hasTorch": false,
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "position": "front",
10-10 23:00:24.702 29639 30650 I ReactNativeJS:   "id": "1"
10-10 23:00:24.702 29639 30650 I ReactNativeJS: }
10-10 23:00:24.764 29639 29639 W unknown:BridgelessReact: ReactHost{0}.onHostPause(activity)
10-10 23:00:24.764 29639 29639 W unknown:BridgelessReact: ReactContext.onHostPause()
10-10 23:00:24.768  4218  4904 D WindowManager: rotationForOrientation, orientationSource=ActivityRecord{a67a81d u0 com.demo/.MainActivity t1079}
10-10 23:00:24.772  4218  4904 V WindowManager: Changing focus from Window{9c7035e u0 com.demo/com.demo.MainActivity} to null displayId=0 Callers=com.android.server.wm.RootWindowContainer.updateFocusedWindowLocked:567 com.android.server.wm.WindowManagerService.updateFocusedWindowLocked:6316 com.android.server.wm.DisplayContent.setFocusedApp:6775 com.android.server.wm.ActivityTaskManagerService.setResumedActivityUncheckLocked:6725 
10-10 23:00:24.782  3882 17019 I CameraService: CameraService::connect call (PID -1 "com.demo", camera ID 1) for HAL version default and Camera API version 2
10-10 23:00:24.786  3882 17019 I CameraService: CameraService::validateClientPermissionsLocked is ok : calling pid 29639, calling uid 10408, client com.demo , cameraservice pid=3882, device user 0, currently allowed device users: 0
10-10 23:00:24.787  3882 17019 I Camera2ClientBase: Camera 1: Opened. Client: com.demo (PID 29639, UID 10408)
10-10 23:00:24.789  3882 17019 I CameraService: service.camera.client set to com.demo
10-10 23:00:24.789  3882 17019 I CameraService: startCameraOps: Start camera ops, package name = com.demo, client UID = 10408
10-10 23:00:24.795  3844  5208 I SurfaceFlinger: id=2403 createSurf (960x720),4 flag=404, SurfaceView - com.demo/com.demo.MainActivity@b2c693b@0#0
10-10 23:00:24.796  3882 17019 I CameraService: updateProxyDeviceState: notifyCameraState for Camera ID 1,  newState 0, facing 1, clientName com.demo, apiLevel 2
10-10 23:00:24.796  7193  8127 I CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_OPEN for client com.demo API Level 2
10-10 23:00:24.796  4218  8180 I CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_OPEN for client com.demo API Level 2
10-10 23:00:24.798  4620  5580 I CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_OPEN for client com.demo API Level 2
10-10 23:00:24.802  3844  5208 I SurfaceFlinger: id=2404 createSurf (0x0),-1 flag=20404, Background for -SurfaceView - com.demo/com.demo.MainActivity@b2c693b@0#0
10-10 23:00:24.804 29639 30647 I CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_OPEN for client com.demo API Level 2
10-10 23:00:24.813  4218  4785 D WindowManager: finishDrawingWindow: Window{9c7035e u0 com.demo/com.demo.MainActivity} mDrawState=HAS_DRAWN
10-10 23:00:24.821  3844  3844 D SurfaceFlinger:  SOLID_COLOR |              | 0002 |  Unknown  |    0.0    0.0    0.0    0.0 |  210  441  720 1161 | Background for -SurfaceView - com.la[...]part.demo.MainActivity@b2c693b@0#0
10-10 23:00:24.821  3844  3844 D SurfaceFlinger:      DEVICE | 0x7e9b860e80 | 0000 | RGBA_8888    |    0.0    0.0  720.0 1560.0 |    0    0  720 1560 | com.demo/com.demo.MainActivity$_29639#0
10-10 23:00:24.822 29639 30591 I SurfaceView: applySurfaceTransforms: t = android.view.SurfaceControl$Transaction@dee5e17 surfaceControl = Surface(name=SurfaceView - com.demo/com.demo.MainActivity@b2c693b@0)/@0xbf34204 frame = 9
10-10 23:00:24.831  3800  3965 I ExynosCameraConfigurationsSec: [CAM(1)][Front_0]-(checkClientPackageName[1493]):packageName (com.demo) cameraClient (0)
10-10 23:00:24.856 29639 30496 I com.demo: NativeAlloc concurrent copying GC freed 107141(7706KB) AllocSpace objects, 0(0B) LOS objects, 49% free, 6975KB/13MB, paused 215us total 109.815ms
10-10 23:00:24.859 29639 30590 I SurfaceView: applySurfaceTransforms: t = android.view.SurfaceControl$Transaction@dee5e17 surfaceControl = Surface(name=SurfaceView - com.demo/com.demo.MainActivity@b2c693b@0)/@0xbf34204 frame = 10
10-10 23:00:24.943  4218  4665 D MdnieScenarioControlService:  packageName : com.demo    className : com.demo.MainActivity
10-10 23:00:24.955  4218  7149 V WindowManager: Changing focus from Window{c957f65 u0 com.google.android.permissioncontroller/com.android.permissioncontroller.permission.ui.GrantPermissionsActivity} to Window{9c7035e u0 com.demo/com.demo.MainActivity} displayId=0 Callers=com.android.server.wm.RootWindowContainer.updateFocusedWindowLocked:567 com.android.server.wm.WindowManagerService.updateFocusedWindowLocked:6316 com.android.server.wm.DisplayContent.setFocusedApp:6775 com.android.server.wm.ActivityTaskManagerService.setResumedActivityUncheckLocked:6725 
10-10 23:00:24.960  4218  7149 D WindowManager: rotationForOrientation, orientationSource=ActivityRecord{a67a81d u0 com.demo/.MainActivity t1079}
10-10 23:00:24.967 29639 29639 W unknown:BridgelessReact: ReactHost{0}.onHostResume(activity)
10-10 23:00:24.967 29639 29639 W unknown:BridgelessReact: ReactContext.onHostResume()
10-10 23:00:24.981  4218  4244 V ActivityManager: Changed top to 10408,ProcessRecord{4ad4406 29639:com.demo/u0a408}
10-10 23:00:24.998  4218  7149 V WindowManager: Relayout Window{9c7035e u0 com.demo/com.demo.MainActivity}: viewVisibility=0 req=720x1560
10-10 23:00:25.009 29639 29639 I ViewRootImpl@6ccaa85[MainActivity]: updateBoundsLayer: shouldReparent = false t = android.view.SurfaceControl$Transaction@d7d6015 sc = Surface(name=Bounds for - com.demo/com.demo.MainActivity@0)/@0x6e67f2a frame = 11
10-10 23:00:25.020 29639 29639 V InputMethodManager: Starting input: tba=com.demo ic=null mNaviBarColor -855310 mIsGetNaviBarColorSuccess true , NavVisible : true , NavTrans : false
10-10 23:00:25.028  4218  4244 D SemGameManager: isGamePackage(), pkgName=com.demo
10-10 23:00:25.031  4218  4242 D SehCodecSolutionService: Update top [com.demo]
10-10 23:00:25.074  4218  4245 D ActivityTaskManager: finishFixedRotationTransform, r=ActivityRecord{a67a81d u0 com.demo/.MainActivity t1079}, caller=com.android.server.wm.WindowToken.finishFixedRotationTransform:664 com.android.server.wm.DisplayContent$FixedRotationTransitionListener.onAppTransitionFinishedLocked:7025 com.android.server.wm.AppTransition.notifyAppTransitionFinishedLocked:552 com.android.server.wm.DisplayContent.handleAnimatingStoppedAndTransition:5836 com.android.server.wm.RootWindowContainer.checkAppTransitionReady:1266 
10-10 23:00:25.161  4218  4665 D MdnieScenarioControlService:  packageName : com.demo    className : com.demo.MainActivity
10-10 23:00:25.351  3882  3984 I CameraService: updateProxyDeviceState: notifyCameraState for Camera ID 1,  newState 1, facing 1, clientName com.demo, apiLevel 2
10-10 23:00:25.352  4218  7149 I CameraService_proxy: updateActivityCount: addNonHighRefreshRatePackage for client(com.demo)
10-10 23:00:25.353  4218  7135 I CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_ACTIVE for client com.demo API Level 2
10-10 23:00:25.353  7193  8127 I CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_ACTIVE for client com.demo API Level 2
10-10 23:00:25.354  4620  5580 I CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_ACTIVE for client com.demo API Level 2
10-10 23:00:25.354 29639 30646 I CameraManagerGlobal: Camera 1 facing CAMERA_FACING_FRONT state now CAMERA_STATE_ACTIVE for client com.demo API Level 2
10-10 23:00:25.374  3844  3844 D SurfaceFlinger:      DEVICE | 0x7e17814a80 | 0002 | 0x0000022    |    0.0    0.0  960.0  720.0 |  135  440  585 1041 | SurfaceView - com.demo/co[...]part.demo.MainActivity@b2c693b@0#0
10-10 23:00:25.374  3844  3844 D SurfaceFlinger:      DEVICE | 0x7e9b860e80 | 0000 | RGBA_8888    |    0.0    0.0  720.0 1560.0 |    0    0  720 1560 | com.demo/com.demo.MainActivity$_29639#0

Camera Device

{
  "formats": [],
  "sensorOrientation": "landscape-right",
  "hardwareLevel": "limited",
  "maxZoom": 4,
  "minZoom": 1,
  "maxExposure": 20,
  "supportsLowLightBoost": false,
  "neutralZoom": 1,
  "physicalDevices": [
    "wide-angle-camera"
  ],
  "supportsFocus": true,
  "supportsRawCapture": false,
  "isMultiCam": false,
  "minFocusDistance": 0,
  "minExposure": -20,
  "name": "1 (FRONT) androidx.camera.camera2",
  "hasFlash": false,
  "hasTorch": false,
  "position": "front",
  "id": "1"
}

Device

Samsung Galaxy A20e (Android 11)

VisionCamera Version

4.5.3

Can you reproduce this issue in the VisionCamera Example app?

I didn't try (⚠️ your issue might get ignored & closed if you don't try this)

Additional information

maintenance-hans[bot] commented 1 month ago

Guten Tag, Hans here. Thank you for your detailed report! It looks like you are experiencing a valid issue with the component not starting in the expected position.

However, I noticed that you didn’t try to reproduce this issue in the VisionCamera Example app. This is important for us to understand if it is an issue specific to your app or a potential bug in the library itself. Please give it a try and let us know the results.

Also, if you could provide more logs surrounding the initialization process or any errors you might see, it would greatly help mrousavy in diagnosing the issue further. You can gather them by running adb logcat if you're using Android.

Feel free to follow up after trying the example app. Cheers! 🍻

Note: If you think I made a mistake, please ping @mrousavy to take a look.

oliviermartin commented 1 month ago

I have just tried VisionCamera Example app. The application is in full screen.

I did modify the example app to be closer to my case and it seems to work (ie: the is always in the middle of the screen):

--- a/package/example/src/CameraPage.tsx
+++ b/package/example/src/CameraPage.tsx
@@ -195,11 +195,12 @@ export function CameraPage({ navigation }: Props): React.ReactElement {
   return (
     <View style={styles.container}>
       {device != null ? (
+        <View style={styles.camera_view}>
         <PinchGestureHandler onGestureEvent={onPinchGesture} enabled={isActive}>
-          <Reanimated.View onTouchEnd={onFocusTap} style={StyleSheet.absoluteFill}>
+          <Reanimated.View onTouchEnd={onFocusTap} style={styles.camera}>
             <TapGestureHandler onEnded={onDoubleTap} numberOfTaps={2}>
               <ReanimatedCamera
-                style={StyleSheet.absoluteFill}
+                style={styles.camera}
                 device={device}
                 isActive={isActive}
                 ref={camera}
@@ -232,6 +233,7 @@ export function CameraPage({ navigation }: Props): React.ReactElement {
             </TapGestureHandler>
           </Reanimated.View>
         </PinchGestureHandler>
+        </View>
       ) : (
         <View style={styles.emptyContainer}>
           <Text style={styles.text}>Your phone does not have a Camera.</Text>
@@ -289,9 +291,15 @@ export function CameraPage({ navigation }: Props): React.ReactElement {

 const styles = StyleSheet.create({
   container: {
-    flex: 1,
-    backgroundColor: 'black',
+    flex: 1, alignItems: 'center', justifyContent: 'center',
+    backgroundColor: 'red',
+  },
+  camera_view: {
+    paddingBottom: 20,
+    alignItems: 'center',
+    justifyContent: 'center',
   },
+  camera: {width: 150, height: 300, zIndex: 0},
   captureButton: {
     position: 'absolute',
     alignSelf: 'center',

But the VisionCamera Example app is much more complex than my test app. I do not know whether I missed something.

cc: @mrousavy

oliviermartin commented 1 month ago

I have been trying to reduce VisionCamera Example app code to simpler test app. I managed few times to duplicate the issue with a minimal version of VisionCamera Example app but not as often as with my app.

I would guess it is a timing / race condition issue somewhere in react-native or react-native-vision-camera when the camera is initialized - more likely react-native-vision-camera as I would have guessed people would have seen it more if it was a generic react-native issue. When the screen is reloaded with a camera already initialized, the issue disappears.

For my test app, I used latest react-native and I have enabled new react native architecture.

timokauppinen commented 1 month ago

I'm having the same problem that the layout is set wrong occasionally (around 20% of the time) there is some race issue going on..

timokauppinen commented 1 month ago

I had on camera view component

const device = useCameraDevice('back'); const [ hasCameraRights, setHasCameraRights ] = useState(false);

useEffect(() => { (async () => { const cameraPermitted = await PermissionsAndroid.check('android.permission.CAMERA'); if (cameraPermitted) { setHasCameraRights(true); } })(); }, []);

if(!hasCameraRight) return No camera right

if (!device) { return No camera device; } return ..camera view...

After I removed that hasCameraRights check it started working correctly, so it has something to do with layout change timings.

FraserKemp commented 2 weeks ago

I am also experiencing this. I am on RN 0.72.17 on version react-native-vision-camera: 4.3.1.

I was attempting to get the camera to sit below a header but I was experiencing this exact problem where the camera pops to the top left. This only happened on android, a Pixel 3a API 33 for me, and didnt happen every single time but it would happen 1 in 10 renders of the camera.

I created a very very simple test project on RN 0.76.1 using version react-native-vision-camera: 4.6.1 to test if the issue occurred on the latest versions as well.

Reproducible code -> https://github.com/FraserKemp/CameraReproduceCase

Again I tested on Pixel 3a API 33.

timokauppinen commented 2 weeks ago

I am also experiencing this. I am on RN 0.72.17 on version react-native-vision-camera: 4.3.1.

I was attempting to get the camera to sit below a header but I was experiencing this exact problem where the camera pops to the top left. This only happened on android, a Pixel 3a API 33 for me, and didnt happen every single time but it would happen 1 in 10 renders of the camera.

I created a very very simple test project on RN 0.76.1 using version react-native-vision-camera: 4.6.1 to test if the issue occurred on the latest versions as well.

Reproducible code -> https://github.com/FraserKemp/CameraReproduceCase

Again I tested on Pixel 3a API 33.

I did not test your code, but it's similar when I had problems. I'm sure if you take that rights check away it will work. In my case I removed the right check and added it outside to the camera open event before initializing the component. You could also add some right check wrapper and only initialize the camera component after have rights.

setafd commented 2 weeks ago

I just found some strange... workaround? I have code like this

<View style={{ flex: 1 }} >
  { hasPermission ? <Camera {...someProps} /> : <NoPermissionView /> }
</View>

After some hours of debugging, I added { borderColor: "transparent", borderWidth: 0 } to <View /> style, and the issue was solved. I am not sure why or how this works, but it does in my case. Maybe it will help someone.

UPD 1: It looks like borderWidth: 0 isn't necessary.

r-rouse commented 2 weeks ago

I was experiencing the same issue. This was only happening on initial render. Once I navigate away from and back to camera the layout is correct.
@setafd your hack solved the issue for me. TY!