Skip to content

[camera_web] Fix TypeError when reading the torch capability - #12647

Open
0xharkirat wants to merge 1 commit into
flutter:mainfrom
0xharkirat:fix-camera-web-torch-capability
Open

[camera_web] Fix TypeError when reading the torch capability#12647
0xharkirat wants to merge 1 commit into
flutter:mainfrom
0xharkirat:fix-camera-web-torch-capability

Conversation

@0xharkirat

@0xharkirat 0xharkirat commented Aug 27, 2026

Copy link
Copy Markdown
Contributor

What broke

setFlashMode and takePicture threw on any camera that has a flash.

The Image Capture specification declares sequence<boolean> torch in
MediaTrackCapabilities. package:web is generated from that specification, so
torchNullable was typed JSArray<JSBoolean>?.

No browser ships that shape. Chromium and WebKit both declare a bare boolean torch.
Reading the property threw before the torch could be applied. The error depends on
the compiler:

Compiler Error
DDC TypeError: true: type 'bool' is not a subtype of type 'JSArray<Object?>?'
dart2js NoSuchMethodError: method not found: 'gq'
dart2wasm ArgumentError: Invalid argument(s)

The same line held two more defects:

  • .first gave the wrong answer for [false, true]. A specification-shaped sequence
    lists the values the source accepts, so that means the torch can be turned on.
  • .first threw StateError on an empty sequence.

The fix

Read torch as JSAny? and add canEnableTorch, which accepts either shape and
returns false for anything else.

A sequence is answered with any instead of first, and is only trusted when every
element is a boolean. Anything unrecognised raises torchModeNotSupported instead of
crashing, and prints a debug-only warning so the shape can be reported.

Test matrix

Browser reports Before After
true TypeError torch on
false TypeError torchModeNotSupported
[false, true] wrong answer torch on
[true] torch on torch on
[false] torchModeNotSupported torchModeNotSupported
[] StateError torchModeNotSupported
key absent torchModeNotSupported torchModeNotSupported
'yes' TypeError torchModeNotSupported + warning
['yes'] TypeError torchModeNotSupported + warning

Nine cases are covered by integration tests. Six of them fail without this change.

Devices tested

All nine shapes were run through the real plugin code on each of these. All passed.

Device Browser Result
Moto G56 5G, Android 16 Chrome 151 9 / 9
macOS 26.3 Safari 26.3 9 / 9
iPhone 17 Pro simulator, iOS 26.1 Safari 9 / 9
macOS 26.3 Chrome 151, dart2js and dart2wasm 9 / 9

On the Moto G56 the rear camera reports torch: true as a bare boolean, and the flash
now turns on. The front camera does not report the key at all and raises
torchModeNotSupported as expected.

What was added

  • canEnableTorch on NonStandardFieldsOnMediaTrackCapabilities, which reads either shape.
  • A debug-only debugPrint warning for a shape that is neither, so an unknown browser can
    be reported rather than failing quietly.
  • Nine integration tests covering every shape, plus a check that a recognised shape never warns.
  • A CHANGELOG entry and a version bump to 0.3.5+6.

What was removed

  • The JSArray<JSBoolean>? type on torchNullable, which no browser matches.
  • The ?.toDart.first.toDart ?? false chain in _setTorchMode.

Issues fixed by this PR

Fixes flutter/flutter#191384

Pre-Review Checklist

🤖 Generated with Claude Code

Browsers do not report the `torch` capability in the shape the Image
Capture specification describes. The specification declares
`sequence<boolean> torch`, and `package:web` is generated from it, but
both Chromium and WebKit declare a bare `boolean torch` in their IDL.

`NonStandardFieldsOnMediaTrackCapabilities.torchNullable` mirrored the
specification, so reading it on a camera that has a flash threw before
the torch could ever be applied. It surfaced differently per compiler:
DDC threw a `TypeError`, dart2js a `NoSuchMethodError`, and dart2wasm an
`ArgumentError`. Both `setFlashMode` and `takePicture` reach it.

Reads the capability as `JSAny?` and adds `canEnableTorch`, which
accepts either shape and reports false for anything else, so a browser
that reports something unexpected raises `torchModeNotSupported` rather
than crashing. Reading a sequence now also answers with `any` rather
than `first`, which was both wrong for `[false, true]` and threw a
`StateError` on an empty sequence.

Fixes flutter/flutter#191384

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the camera_web package to handle different browser implementations of the torch capability. In pkg_web_tweaks.dart, torchNullable is changed from JSArray<JSBoolean>? to JSAny? to accommodate both bare booleans and boolean sequences. A new canEnableTorch getter is added to parse these types, and integration tests are introduced to verify the capability parsing across various formats. No review comments were provided, so there is no feedback to address.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

camera package throws when trying to use flashlight on web

1 participant