The Problem

Integrating a camera experience into a Flutter app is often non‑trivial because it requires bridging platform‑specific camera APIs, handling permissions, and managing UI customisation. CamerAwesome attempts to flatten this by providing a plugin with native Android/iOS implementations, but the codebase shows several structural weaknesses that raise the cost of future changes.

What This Does

CamerAwesome is a Flutter plugin that bundles a ready‑made camera UI and exposes native features (photo/video capture, live filters, image analysis, multi‑camera, flash, zoom, etc.) through a Dart API. The repository layout mirrors a typical Flutter plugin:

  • example/lib/main.dart – the entry point for the demo app that exercises the plugin.
  • lib/ – Dart source, including pigeon.dart code‑generated platform bridges and orchestration logic.
  • android/ – Kotlin sources under com.apparence.camerawesome. Key files:
  • CameraAwesomeX.kt – high‑level camera X‑binding, 1426 lines, deeply nested control flow (max indentation 11).
  • CameraXState.kt – state management, duplicated 6‑line blocks (299 repeats across 43 files).
  • Pigeon.kt – code generator configuration, 1426 lines, high branching density (401 branch points).
  • image/YuvToJpgConverter.java – image conversion, deep nesting.
  • ios/ – platform‑specific setup files (Podfile, Xcode project) but no Swift source beyond the generated bridge.

The plugin’s public API lives in lib/pigeon.dart; it routes method‑channel calls to the generated Kotlin/Java counterparts. Features such as photo capture, video recording, and barcode analysis are triggered from example/lib/... example widgets that call CameraAwesome.startVideoRecording(), CameraAwesome.takePhoto(), etc.

How It Is Wired

Execution starts at example/lib/main.dart, which instantiates the CameraAwesome widget. That widget registers the plugin via runApp(CameraAwesomeApp()), which in turn calls the Flutter plugin constructor (CamerawesomePlugin()). The platform channel name is defined in the generated pigeon.dart code and maps to CameraAwesomeMethodChannel on Android and CameraAwesome on iOS.

From the Dart side, calls flow through Pigeon.kt‑generated methods that invoke Kotlin functions such as CameraAwesomeX.startVideoRecording() or CameraXState.updatePreview(). The internal import graph analysis shows 0 circular dependencies across 203 code files (Dart 129, Kotlin 19, Java 13, C 33), but the three oversized files (Pigeon.kt, lib/pigeon.dart, `CameraAwesomeX.kt) act as hubs: changes ripple widely because they contain the bulk of the business logic.

Specific pain points from the static analysis:

  • Deep nesting – CameraAwesomeX.kt, CameraXState.kt, YuvToJpgConverter.java each exceed 32 levels of nesting, making control‑flow hard to follow.
  • Duplicated code – 299 repeated 6‑line blocks appear in CameraXState.kt, OrientationStreamListener.kt, and the integration‑test files, violating DRY.
  • High branching density – 401 branch points across 1426 lines in Pigeon.kt and lib/pigeon.dart.
  • Oversized files – the three files above exceed 1400 lines, exceeding typical maintainability thresholds.
  • Stale TODO/FIXME markers – 7 markers in CameraAwesomeX.kt, 6 in example/integration_test/ui_test.dart, 3 in lib/src/orchestrator/models/analysis/analysis_image.dart, and 4 each in camera_state.dart, awesome_camera_preview.dart, and pigeons/interface.dart.

How To Use It

Setup (from the README):

# Add the package
flutter pub add camerawesome   # adds ^2.0.0-dev.1 to pubspec.yaml

Platform specific steps (excerpt from README):

  • Android – no extra steps beyond the Gradle setup already present; the plugin’s android/build.gradle and example/android/app/build.gradle already reference the required AndroidX components.
  • iOS – add the following to ios/Runner/Info.plist (as the README notes) and ensure the io.flutter.embedded_views_preview flag is set if using the UI preview.

Running the example:

cd example
flutter run               # builds and launches the demo app on a connected device/emulator

The demo showcases the default UI; you can swap to a custom UI by importing custom_awesome_ui.dart and adjusting the CameraAwesome widget parameters.

Real‑World Use

A typical integration: you want a “Scan QR code” screen in your app. Add the dependency, enable the image_analysis feature in the plugin config, and listen to the onImageAnalysis callback. The callback delivers each frame to your barcode‑decoding library (e.g., google_mlkit_barcode_scanning). Because the plugin already handles camera lifecycle, permissions, and preview rotation, you only need to implement the analysis logic in Dart, keeping the native heavy lifting inside CameraAwesomeX.kt and image/YuvToJpgConverter.java.

Code Health & Issues

  • [HIGH] Add a CI/CD workflow – no .github/ CI config exists; every PR merges without an automated build or test gate.
  • [MEDIUM] Large binaries in repo – docs/img/sensors_type.gif (14.9 MB), face_ai.gif (7.1 MB), custom_theme.gif (6.7 MB) and other blobs over 5 MB inflate clone size and CI checkout time.
  • [MEDIUM] Sparse test coverage – only 2 test files against 131 source files (ratio 0.015); many modules lack unit or widget tests.
  • [LOW] Missing convention files – no .editorconfig, .gitattributes, or formatter config; editors may diverge on indentation, line endings, and dart formatting.
  • [HIGH] Deep nesting & duplicated blocks – as detailed above, these increase cognitive load and risk of bugs.
  • [HIGH] Oversized source files – Pigeon.kt, lib/pigeon.dart, CameraAwesomeX.kt exceed 1400 lines, making changes high‑risk.

The Bottom Line

CamerAwesome delivers a functional camera widget out‑of‑the‑box and documents most native features, which is valuable for rapid prototyping. However, the codebase suffers from oversized, deeply nested files, duplicated logic, and an absent CI gate. Teams comfortable with occasional refactoring to flatten control flow and add tests will find it usable; groups needing a battle‑tested, low‑maintenance camera layer may want to evaluate more mature alternatives or plan to invest in the outlined cleanup (CI, LFS for large assets, test expansion, and file‑size reduction).