Skip to content

Devlog

The Fairphone 5 has a hidden dual-camera mode. A 200-line probe found it.

DualShot — front and back camera recording at the same time — only exists because of one question: can the Fairphone 5 physically stream both cameras at once?

Android's official answer is no. FEATURE_CAMERA_CONCURRENT is false on the FP5, and getConcurrentCameraIds() returns an empty set. Every high-level API takes the OS at its word: CameraX will simply refuse to open a second camera. If the project had started from the SDK documentation, it would have ended there.

Probe before building

Instead of trusting the flags, the first artifact of the project was a ~200-line diagnostic APK that did nothing but try: open the back camera, then open the front camera on top of it, raw Camera2, and report what happened.

It worked. The FP5's camera HAL happily streams both cameras concurrently — the capability exists in the silicon and the driver; only the advertised feature flags deny it.

That single round-trip settled the central unknown of the entire project before any product code was written, and it dictated the architecture: everything is raw Camera2. No CameraX, no compat layers — they all believe the flags.

What it became

The probe grew into a fork of Open Camera (GPL-3.0) with a picture-in-picture toggle inside the native photo and video modes:

  • a draggable, pinch-resizable front-camera preview over the main viewfinder,
  • photos composited with the front still at capture time,
  • video spliced live through a small GL compositor sitting between the back camera and the encoder.

Each of those hides its own war story — sideways previews (the SurfaceTexture transform matrix already contains the rotation; adding your own cancels it), five-second clips that muxed as an hour (the FP5's sensor timestamps aren't CLOCK_MONOTONIC), and a silent fallback that cost a full debugging round-trip and produced the project's firmest rule: never degrade silently — every fallback now says why, on screen.

Those get their own posts. The general lesson stands on its own: when the critical unknown is hardware behavior, a throwaway probe is the cheapest experiment you will ever run. Ship it first.