BIND_ABOVE_CLIENT clamps the client's oom_adj to CACHED_APP_MIN_ADJ, so client apps get frozen in the background (Android 15)

Open Beginner friendly
#1,081 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
78/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
java
Domain
mobile-dev

Research direction

Start at lib/src/main/java/com/nextcloud/android/sso/api/AidlNetworkRequest.java:111 and inspect how AidlNetworkRequest.connect() sets the binding flags. Reproduce the background behavior with the provided adb dumpsys command and verify that the binding no longer clamps the client process or freezes a foreground-service client on Android 14/15.

Written by the indexing model from the issue text.

Description

0. Needs triage bug
Summary

AidlNetworkRequest.connect() binds to the Files app's AccountManagerService with Context.BIND_ABOVE_CLIENT:

https://github.com/nextcloud/Android-SingleSignOn/blob/master/lib/src/main/java/com/nextcloud/android/sso/api/AidlNetworkRequest.java#L111

On Android 14/15 this has a side effect on the client: while such a binding exists, ActivityManager clamps the client process's oom adjustment to CACHED_APP_MIN_ADJ (900) whenever the client is not the foreground app — even when it is running a foreground service. The process lands in the cached bucket and is frozen by the cached-app freezer.

For an app with a foreground service this is fatal: the service keeps its notification and is still listed as running, but the process is frozen and does nothing.

Measurements

Device: Fairphone 5, Android 15, build FP5.VT31.C.114.20260804. Client: PhoneTrack 0.1.0 (targetSdk 29), which runs a location-logging foreground service.

dumpsys activity processes <pkg> while the app is in the background, SSO account in use:

oom adj: max=1001 curRaw=250 setRaw=250 cur=900 set=900
cached=true empty=false
mHasForegroundServices=true
hasClientActivities=false hasAboveClient=true
isFrozen=true
mConnections:
  - ConnectionRecord{... CR ABCLT com.nextcloud.client/com.owncloud.android.services.AccountManagerService:@... flags=0x9}

Note curRaw=250, which is what the foreground service earns, versus cur=900.

Logcat, about two minutes after the app goes to the background:

D/ActivityManager: freezing 13709 net.eneiluj.nextcloud.phonetrack
I/am_freeze( 1574): [13709,net.eneiluj.nextcloud.phonetrack]

A follow-on effect: an alarm-triggered startService delivered into the frozen process times out and produces an ANR dialog.

W/ActivityManager: Timeout executing service: ServiceRecord{... .service.WebTrackService}
I/am_anr: [0,13709,...,executing service ..., waited 20008ms]

In the ANR report the process is Frozen: true and every thread sits in do_freezer_trap, so no Java stack is collected.

Comparison

Same device, same app, same 12-minute background run. The only difference is whether the app authenticates through the Files app (SSO) or with a plain server URL plus username and password.

SSO account plain login
hasAboveClient true false
oom adj in background 900 200
am_freeze events 1, after ~2 min 0
recording stops, 10 min gap continuous, every 20 s

With the plain login there is no ConnectionRecord to com.nextcloud.client at all, and the process was still unfrozen hours later.

The practical cost in this case: recording dropped from roughly 9000 points per month to a few dozen, and stayed there for about a year before the cause was found.

Steps to reproduce
  1. Use an app that authenticates through this library and runs a foreground service.
  2. Send it to the background.
  3. adb shell dumpsys activity processes <pkg> | grep -E 'oom adj:|hasAboveClient|isFrozen'
  4. After about two minutes: cur=900, isFrozen=true, and am_freeze for the process in logcat.
Question

Is BIND_ABOVE_CLIENT intentional here? Its documented purpose is to have the client killed before the bound service. For a client binding a helper service in another app, the effect on Android 14+ is that the client counts as cached and gets frozen whenever it is not in the foreground.

Dropping the flag and keeping BIND_AUTO_CREATE would avoid the clamp. If the flag is needed for a specific reason, making it opt-in would let apps with a foreground service bind without it.

Environment
  • Fairphone 5, Android 15, build FP5.VT31.C.114.20260804
  • Client app targetSdk 29; the bundled library version is from the app's 2023 release, but the flag is unchanged in master
  • Tested on this one device and Android version only
Dominant language
Java
Stars
74
Forks
36
Avg merge
1d 6h
Merged PRs (30d)
15

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from nextcloud/Android-SingleSignOn

All issues in nextcloud/Android-SingleSignOn

Similar issues

More Java issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.