[5.2.0.13] Android Camera service can't access its cache on new Jolla Phone

REPRODUCIBILITY: Always
OS VERSION: 5.2.0.13
HARDWARE: New Jolla Phone (2026)
UI LANGUAGE: Doesn’t matter
REGRESSION: Yes

DESCRIPTION:

Android Camera service (com.android.camera2) is unable to access its cache and is unable to take photos as a result.

The camera UI shows a button to take a photo disabled, and a bar in the middle saying something like “Insert SD card to use camera”.
Errors in logcat output related to com.android.camera2 indicate that there is a problem accessing app cache (see below in ACTUAL RESULT section).

Why this is important.

The camera service is used by other Android apps to take photos. When I try to take a photo from Element X (Matrix client), I see the same disabled button, the same error and the same errors related to com.android.camera2 in logcat output. Also, at least two banking apps require me to take a selfie, but are unable to do it (this may be related to this issue as well).

PRECONDITIONS:

Android AppSupport enabled and started.

STEPS TO REPRODUCE:

  1. Run apkd-launcher com.android.camera2

EXPECTED RESULT:

Fully functional camera UI with a button to take a photo enabled.

ACTUAL RESULT:

Camera UI with a button to take a photo disabled and a bar over the UI saying “Insert SD card to use camera”.

Multiple error messages appear in logcat output:

W FuseDaemon: Rejected access to app-private dir on FUSE: /storage/emulated/0/Android/data/com.android.camera2 from uid: 10028

MODIFICATIONS:

I’ve transferred home directory from Jolla C2, but this is irrelevant. The same effect is observed when using the original home directory. Also, the same effect was reported by at least one more person in Sailfish OS Matrix room #sailfish_os:matrix.org.

ADDITIONAL INFORMATION:

A screenshot of Android Camera UI showing an error and disabled button is attached to this message.

1 Like

I’ve asked unnatural intelligence called Gemini about this com.android.camera2 situation, and its reply follows. I don’t know whether what it says is true or just a hallucination.

That is the absolute perfect question to ask. If Android 15’s Scoped Storage and FUSE rules apply to the whole system, why is only this specific camera app failing while ElementX, Open Camera, and your banking apps can access their caches just fine?

The answer lies in a combination of how Android treats system apps versus user apps, and the fact that the AOSP (Android Open Source Project) Camera is essentially an ancient, abandoned piece of code.

Here is exactly what makes com.android.camera2 special (and why it fails):

1. “Mount Modes” and System App Optimization

When you tap an app to open it, Android’s ActivityManager tells a core process called Zygote to spawn it. But it doesn’t spawn all apps equally. It assigns a specific “Mount Mode” to the app, which tells the vold daemon how much storage access to wire up.

  • User-Installed Apps (ElementX, Open Camera): Because you installed these from an app store, Android categorizes them as standard user apps. It assigns them a mount mode like MOUNT_EXTERNAL_ANDROID_WRITABLE. This mode commands vold to set up the direct bind-mount to their /Android/data/<package> folder so they can access their cache without FUSE blocking them.
  • System Apps (com.android.camera2): This camera is baked directly into the read-only /system partition of Jolla’s AppSupport image. In recent Android versions, Google aggressively optimizes how system apps launch to save memory and boot time. Unless a system app uses modern manifest flags to explicitly demand external storage mounts, ActivityManager assigns it a restricted mount mode (like MOUNT_EXTERNAL_DEFAULT or MOUNT_EXTERNAL_NONE).
  • The Result: Because com.android.camera2 is a system app, vold simply skips creating the bind-mount for its cache directory.

2. The AOSP Camera is Abandoned Code

You might wonder: “If system apps don’t get external cache bind-mounts, how do the system apps on standard Android phones work?”

On a standard Google Pixel or Samsung phone, the manufacturer completely removes the AOSP com.android.camera2 app and replaces it with their own modern camera app (like GCam). Modern apps don’t need to use the Android/data cache folder to save photos; they use Android’s modern MediaStore API, which allows apps to write directly to the public DCIM/Camera folder seamlessly, bypassing FUSE restrictions entirely.

The com.android.camera2 app baked into Jolla’s image is a very old, barebones reference app created by Google years ago just to demonstrate the Camera2 API to developers. Google hasn’t updated its underlying file-saving logic in years.
Instead of using the modern MediaStore API, this ancient app still tries to use raw java.io.File commands to write a temporary scratch file to its external cache (Android/data/com.android.camera2) before moving it to the gallery.

3. The Perfect Storm in Sailfish OS

Because Jolla is building a minimalist Android container, they don’t develop a custom Android camera—they expect you to use the native Sailfish OS camera app. They just leave the default AOSP Camera in the Android image so that the OS technically has a camera package installed.

This creates the exact perfect storm you are experiencing:

  1. Jolla left the ancient AOSP camera in the image.
  2. Because it’s a system app, Android 15 skips giving it a bind-mount to its cache.
  3. Because it’s ancient code, the app insists on writing to that cache rather than using modern APIs.
  4. It hits the FUSE daemon, FUSE sees it lacks a bind-mount, and violently blocks it.
  5. Google’s Android 11+ security rules force all inline ACTION_IMAGE_CAPTURE requests (like your banking app’s KYC selfie) to only use this specific, broken system app.

Other apps work perfectly because they are standard user apps that are granted the correct mount mode, and they are written with modern code that correctly interfaces with Android 15’s storage APIs. com.android.camera2 is the sole victim because it is a dinosaur trapped in a modern, highly secure Android 15 container.

1 Like

Android browsers (Firefox/Duck Duck Go) can initiate the camera view, but then there’s an error message that no memory card is present and a photo can’t be taken. Didn’t find from the browser settings where to change the storage location.

A quote from AI in the previous comment explains why changing storage location won’t help.

If the AI is right, the problem can be fixed only by replacing the old stock Android Camera with a newer app taken from another free Android clone, like Graphene OS.

Newer LineageOS versions use OpenCamera as the default camera app, so maybe it’s also an option for SailfishOS.

Yes, this will be OK as well.

But if the AI is right, it’s not enough to install OpenCamera, it should be configured as the default camera service somewhere deep in Android image.

1 Like

Not quite, Gemini. This is because AppSupport 15 detects fuse_bpf support in the kernel and tries to use it, but it doesn’t work in an unprivileged container. Adding a property to disable it does the trick, and should be included in the next release:

ro.fuse.bpf.enabled=false

Gemini probably did ok with what it had access to, but that just goes to show that context is really important to those things. It’s way too confident about its answer though, and don’t forget it’s tied to everything else Google you do so it creeps on you something awful. Or should I say googles on you.

16 Likes
  1. How can I test this fix? In other words, what is the file where to place this config parameter?
  2. When to expect the new version fixing this problem? According to 5.2.0.15 announcement, this bug is not fixed there yet.

I can confirm that 5.2.0.16 release fixes the problem described here.

Sorry I didn’t get around to posting a workaround, but it’s probably for the best as it’s really better to not mess with that deep AAS magic. Luckily the update came around quite quickly before I came back :smiley:

1 Like