Skip to content
This repository was archived by the owner on Apr 9, 2025. It is now read-only.

Update - #1

Open
emilienbidet wants to merge 367 commits into
dashdoc:mainfrom
mrousavy:main
Open

Update#1
emilienbidet wants to merge 367 commits into
dashdoc:mainfrom
mrousavy:main

Conversation

@emilienbidet

Copy link
Copy Markdown

What

Changes

Tested on

Related issues

mrousavy and others added 30 commits April 24, 2026 11:28
* feat: Add `maxDuration` and `maxFileSize` to Recorder

* chore: Clean up Kotlin code

* lint

* chore: Clean up Swift

* Update Recorder.nitro.ts

* fix: Add `cause` to `VideoRecorderError`

* fix: Set `this.recording = null`
* feat: Add `RecordingFinishedReason`

* chore: nitrogen

* Implement reason for Android

* Add docs

* Implement Swift
* docs: Add proper docs for recorder max file size / duration

* fix wrong link
…3790)

* fix: Grant permissions for Android AWS Devices

* fix broken test - android start() is not awaitable

* Disable iOS AWS Device Farm Harness Tests for now

* fix isRunning test
* feat: Proper Harness tests

* adjust

* infer type

* avoid VideoOutput persistent recorder ugly `let` + `try`/`catch`

If this throws, the test should fail anyways! try catch was unnecessary and stupid.

* remove unnecessary try catch

* fix HEIC/RAW and catch in photo output i guess

* fix: Call `setOn*Callback` on proper Thread

* fix: Await start first before stopping

* fix: Remove test where we expect more than 1 connection to throw in single cam session (android can do both)

* skip RAW/DNG tests for now as we dont have an API for that yet

* fix: Just log baseline config no need to compare FPS

* Skip Frame Drop test on Android as its currently noop

* Update visioncamera.photo.harness.ts

* fix: Stop session AFTER waiting for callbacks otherwise they are never fired

* fix: Avoid setting torch strength if it is not supported

* skip some tests

* gitignore .harness

* fix: Fix `shouldMirror()` being wrong for Photo Capture

* Update visioncamera.controller.harness.ts

* fire onWillCapturePhoto too

* fix: Fire `onDidCapturePhoto()` if the device didnt fire it before

* fix check ismirrored properly

* add a readme for harness tests
* chore: Upgrade Nitro + NitroImage

* Update Podfile.lock
…ge (#3808)

fix(ios): barcode format filter ignored due to discarded union result
* feat: Add `supportedMultiCamDeviceCombinations`

* docs

* feat: Implement it

* docs: Add docs for multi cam constraints

* More docs

* fix android build

* Update Track.swift
Revert "feat: Add `supportedMultiCamDeviceCombinations` (#3817)"

This reverts commit 2179030.
…`__element`) (#3821)

* chore: Upgrade to Nitro 0.35.6 for nitrogen `__element` fix

* specs

* Reapply "feat: Add `supportedMultiCamDeviceCombinations`" (#3820)

This reverts commit 7586e98.

* fix: Update specs what
chore: add keep tag to HybridFrame converter
mrousavy and others added 30 commits August 3, 2026 11:55
* fix: Use `onError` to emit configure/start errors

* For session too
Co-authored-by: Marc Rousavy <me@mrousavy.com>
* chore: Test Preview position regression via Harness UI

* actually tap elements
* chore: Test Preview position regression via Harness UI

* actually tap elements

* chore: Improve Harness testing code
Importing an AHardwareBuffer into Vulkan acquires a reference on it, so the
unbounded import cache pinned every camera buffer the Resizer had ever seen.
Cap it at 12 entries, evicting oldest-inserted first.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* fix: Remove preview layers as well in `updateOutputs(..)`

* Update HybridCameraSession.swift

* fix: Do it before updateInputs/updateOutputs

* remove -> detach

* Update HybridCameraSession.swift
…(..)` in `<Camera />` (#4140)

perf: Actually use `TargetCameraPosition` direct binding
… guide (#4144)

* docs: Add recommended split between Object Output and Barcode Scanner guide

* Expo tab

* links
Matrix.preScale right-multiplies and postRotate left-multiplies, so the
mirror was applied before the rotation. A reflection conjugates a rotation
into its inverse, so that ordering leaves the Image a half turn from what
`orientation` and `isMirrored` describe, and 180 degrees away from the EXIF
file path and the live preview.

The same composition is in ImageProxy.toBitmap, which the Frame and Depth
converters go through, so both are fixed here.

Adds the harness coverage that pins it: one front-camera capture, compared
point by point against the stored frame read through the reported rotation.

Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
…d with camera is not active on android (#4145)

Co-authored-by: Marc Rousavy <me@mrousavy.com>
* feat: Add `onUIRotationChanged(..)`

* ok?

* fix logic

* animated ?

* fix: Get rotation working

* Add docs

* rename `getUIRotation`

* simplify to use `getUIRotation`
* test: Add tests for `onUIRotationChanged`

* Update visioncamera.hooks.harness.tsx

* test: Refine UI rotation harness coverage
fix(docs): wrap long API member headings
…C_BREAKPOINT` on cancel (#4161)

* fix: Use callback `setPreparedPhotoSettingsArray` overload to fix `EXC_BREAKPOINT` on cancel

* test it

* Update visioncamera.photo.harness.ts

* move into finally
…4155)

Bumps the camera-libs group with 1 update in the /packages/react-native-vision-camera-barcode-scanner/android directory: androidx.camera:camera-core.
Bumps the camera-libs group with 7 updates in the /packages/react-native-vision-camera/android directory:

| Package | From | To |
| --- | --- | --- |
| androidx.camera:camera-core | `1.7.0-alpha02` | `1.7.0-alpha03` |
| androidx.camera:camera-camera2 | `1.7.0-alpha02` | `1.7.0-alpha03` |
| androidx.camera:camera-camera2-pipe | `1.7.0-alpha02` | `1.7.0-alpha03` |
| androidx.camera:camera-lifecycle | `1.7.0-alpha02` | `1.7.0-alpha03` |
| androidx.camera:camera-video | `1.7.0-alpha02` | `1.7.0-alpha03` |
| androidx.camera:camera-view | `1.7.0-alpha02` | `1.7.0-alpha03` |
| androidx.camera:camera-extensions | `1.7.0-alpha02` | `1.7.0-alpha03` |



Updates `androidx.camera:camera-core` from 1.7.0-alpha02 to 1.7.0-alpha03

Updates `androidx.camera:camera-core` from 1.7.0-alpha02 to 1.7.0-alpha03

Updates `androidx.camera:camera-camera2` from 1.7.0-alpha02 to 1.7.0-alpha03

Updates `androidx.camera:camera-camera2-pipe` from 1.7.0-alpha02 to 1.7.0-alpha03

Updates `androidx.camera:camera-lifecycle` from 1.7.0-alpha02 to 1.7.0-alpha03

Updates `androidx.camera:camera-video` from 1.7.0-alpha02 to 1.7.0-alpha03

Updates `androidx.camera:camera-view` from 1.7.0-alpha02 to 1.7.0-alpha03

Updates `androidx.camera:camera-extensions` from 1.7.0-alpha02 to 1.7.0-alpha03

Updates `androidx.camera:camera-camera2` from 1.7.0-alpha02 to 1.7.0-alpha03

Updates `androidx.camera:camera-camera2-pipe` from 1.7.0-alpha02 to 1.7.0-alpha03

Updates `androidx.camera:camera-lifecycle` from 1.7.0-alpha02 to 1.7.0-alpha03

Updates `androidx.camera:camera-video` from 1.7.0-alpha02 to 1.7.0-alpha03

Updates `androidx.camera:camera-view` from 1.7.0-alpha02 to 1.7.0-alpha03

Updates `androidx.camera:camera-extensions` from 1.7.0-alpha02 to 1.7.0-alpha03

---
updated-dependencies:
- dependency-name: androidx.camera:camera-core
  dependency-version: 1.7.0-alpha03
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: camera-libs
- dependency-name: androidx.camera:camera-core
  dependency-version: 1.7.0-alpha03
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: camera-libs
- dependency-name: androidx.camera:camera-camera2
  dependency-version: 1.7.0-alpha03
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: camera-libs
- dependency-name: androidx.camera:camera-camera2-pipe
  dependency-version: 1.7.0-alpha03
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: camera-libs
- dependency-name: androidx.camera:camera-lifecycle
  dependency-version: 1.7.0-alpha03
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: camera-libs
- dependency-name: androidx.camera:camera-video
  dependency-version: 1.7.0-alpha03
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: camera-libs
- dependency-name: androidx.camera:camera-view
  dependency-version: 1.7.0-alpha03
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: camera-libs
- dependency-name: androidx.camera:camera-extensions
  dependency-version: 1.7.0-alpha03
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: camera-libs
- dependency-name: androidx.camera:camera-camera2
  dependency-version: 1.7.0-alpha03
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: camera-libs
- dependency-name: androidx.camera:camera-camera2-pipe
  dependency-version: 1.7.0-alpha03
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: camera-libs
- dependency-name: androidx.camera:camera-lifecycle
  dependency-version: 1.7.0-alpha03
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: camera-libs
- dependency-name: androidx.camera:camera-video
  dependency-version: 1.7.0-alpha03
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: camera-libs
- dependency-name: androidx.camera:camera-view
  dependency-version: 1.7.0-alpha03
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: camera-libs
- dependency-name: androidx.camera:camera-extensions
  dependency-version: 1.7.0-alpha03
  dependency-type: direct:production
  update-type: version-update:semver-patch
  dependency-group: camera-libs
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
fix: migrate CameraX alpha03 APIs
Semver ranges never match pre-releases, so a required peer of "*" does
not match e.g. 0.37.0-beta.0. Package managers then install a second,
stable copy of Nitro next to the pre-release, and the native/JS version
guard throws "Nitro was installed twice" at runtime.

Marking the peer optional leaves the consuming app in full control of
the installed Nitro version.
* feat: Upgrade Nitro to 0.37 for View improvements

* fix: Override `react-native-nitro-modules` to 0.37.0-beta.0

`*` in peerDependencies does not match prereleases, so bun could not
dedupe the peer onto the hoisted 0.37.0-beta.0 and installed a second
copy at 0.36.5 under each package. That auto-installed peer state also
broke `bun install --frozen-lockfile` in CI - the lockfile round-trips
byte-identically, so regenerating it never helped.

Pin it via a root override for now.

* feat: Upgrade Nitro to 0.37.0-beta.1

Regenerates specs with nitrogen 0.37.0-beta.1, which migrates the View
prop types from `CachedProp` to `ReactProp`.

beta.1 also re-adds legacy `CachedProp` as deprecated, so
`react-native-nitro-image@0.15.1` - whose generated code still uses
`CachedProp::isDirty`/`::value` - compiles again. That was what broke
Build Android on beta.0.

* fix: Drop `react-native-nitro-modules` override

Superseded by #4165 - marking the peer dependency optional stops the
package manager from resolving a second, stable Nitro next to the
pre-release, so the root override is no longer needed.

Verified from a clean node_modules: exactly one Nitro copy
(0.37.0-beta.1) and `bun install --frozen-lockfile` passes.

* feat: Upgrade Nitro to 0.37.0 and Nitro Image to 0.15.2

Nitro 0.37.0 and nitrogen 0.37.0 are now stable; nitrogen's generated
output is identical to 0.37.0-beta.1, so no spec changes were needed.

Nitro Image 0.15.2 is regenerated with nitrogen 0.37.0 (no more
deprecated `CachedProp`) and marks its `react-native-nitro-modules`
peer dependency as optional.
`targetResolution` (and `previewImageTargetSize`) are `Size` objects that
users almost always pass as inline object literals:

```tsx
const photoOutput = usePhotoOutput({
  targetResolution: { width: 1920, height: 1080 },
})
```

Those literals get a fresh identity on every render, so the `useMemo(...)`
inside `usePhotoOutput` / `useVideoOutput` / `useFrameOutput` /
`useDepthOutput` misses its cache and creates a brand new `CameraOutput`
every time.

That is not just wasteful, it self-perpetuates: a new output changes the
`outputs` array, which re-runs the `useCameraController` effect, which
re-configures the `CameraSession`, which calls `setController(...)`, which
renders again, which creates yet another output. The session ends up in an
endless reconfigure loop and takes the app down with it within seconds.

Memoize `Size` props by value (`width`/`height`) via a new
`useMemoizedSize(...)` internal hook so the outputs are only re-created
when the requested resolution actually changes.

Also adds a Harness test that re-renders a component with inline
`targetResolution` literals and asserts that the outputs keep their
identity and that the session is configured exactly once, while changing
the actual resolution values still re-configures it.
…4167)

`useCameraController` kept the user's `constraints` stable by putting
`JSON.stringify(constraints)` into the `useMemo` dependency array. That
works for plain constraints like `{ fps: 60 }`, but it silently breaks for
`{ resolutionBias: someOutput }`.

Nitro `HybridObject`s are created via `Object.create(prototype)` and hold
every property on their shared prototype, so the JS object itself has no own
keys. `JSON.stringify(...)` therefore serializes *every* `CameraOutput` to
`{}` (release) or `{"__type":"HybridObject<CameraPhotoOutput>"}` (debug) -
two different outputs of the same type produce the exact same string. Any
change that only re-points a `resolutionBias` at a different output is
invisible to the memo, and the session is never re-configured.

Replace the stringification with an explicit deep comparison that compares
object literals and arrays by value and everything else (i.e. `HybridObject`s)
by identity. That also drops a full JSON serialization from every render.

Also adds two Harness tests: one that re-renders with an inline `constraints`
array and asserts the session is configured exactly once (and re-configured
once more when the constraint values actually change), and one that asserts
re-pointing a `resolutionBias` constraint at a different output of the same
type does re-configure the session.
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.