Skip to content

fix foreground service permission crash + remove phone call permission + fix "requires API level" checks - #5483

Merged
mahibi merged 6 commits into
masterfrom
bugfix/noid/fixForegroundServicePermissionCrash
Oct 22, 2025
Merged

fix foreground service permission crash + remove phone call permission + fix "requires API level" checks#5483
mahibi merged 6 commits into
masterfrom
bugfix/noid/fixForegroundServicePermissionCrash

Conversation

@mahibi

@mahibi mahibi commented Oct 17, 2025

Copy link
Copy Markdown
Collaborator

when record_audio permission was not granted, this crash appeared because foreground service must only be started with the granted permission:

2025-10-17 09:56:01.459 14445-14445 AndroidRuntime          com.nextcloud.talk2                  E  FATAL EXCEPTION: main (Ask Gemini)
                                                                                                    Process: com.nextcloud.talk2, PID: 14445
                                                                                                    java.lang.RuntimeException: Unable to start service com.nextcloud.talk.services.CallForegroundService@a9cff99 with Intent { cmp=com.nextcloud.talk2/com.nextcloud.talk.services.CallForegroundService (has extras) }: java.lang.SecurityException: Starting FGS with type microphone callerApp=ProcessRecord{1b5bf24 14445:com.nextcloud.talk2/u0a397} targetSDK=35 requires permissions: all of the permissions allOf=true [android.permission.FOREGROUND_SERVICE_MICROPHONE] any of the permissions allOf=false [android.permission.CAPTURE_AUDIO_HOTWORD, android.permission.CAPTURE_AUDIO_OUTPUT, android.permission.CAPTURE_MEDIA_OUTPUT, android.permission.CAPTURE_TUNER_AUDIO_INPUT, android.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT, android.permission.RECORD_AUDIO]  and the app must be in the eligible state/exemptions to access the foreground only permission
                                                                                                    	at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:5295)
                                                                                                    	at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(Unknown Source:0)
                                                                                                    	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2580)
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:112)
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:268)
                                                                                                    	at android.os.Looper.loop(Looper.java:384)
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:8921)
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method)
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:907)
                                                                                                    Caused by: java.lang.SecurityException: Starting FGS with type microphone callerApp=ProcessRecord{1b5bf24 14445:com.nextcloud.talk2/u0a397} targetSDK=35 requires permissions: all of the permissions allOf=true [android.permission.FOREGROUND_SERVICE_MICROPHONE] any of the permissions allOf=false [android.permission.CAPTURE_AUDIO_HOTWORD, android.permission.CAPTURE_AUDIO_OUTPUT, android.permission.CAPTURE_MEDIA_OUTPUT, android.permission.CAPTURE_TUNER_AUDIO_INPUT, android.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT, android.permission.RECORD_AUDIO]  and the app must be in the eligible state/exemptions to access the foreground only permission
                                                                                                    	at android.os.Parcel.createExceptionOrNull(Parcel.java:3242)
                                                                                                    	at android.os.Parcel.createException(Parcel.java:3226)
                                                                                                    	at android.os.Parcel.readException(Parcel.java:3209)
                                                                                                    	at android.os.Parcel.readException(Parcel.java:3151)
                                                                                                    	at android.app.IActivityManager$Stub$Proxy.setServiceForeground(IActivityManager.java:7326)
                                                                                                    	at android.app.Service.startForeground(Service.java:863)
                                                                                                    	at com.nextcloud.talk.services.CallForegroundService.onStartCommand(CallForegroundService.kt:38)
                                                                                                    	at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:5277)
                                                                                                    	at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(Unknown Source:0) 
                                                                                                    	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2580) 
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:112) 
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:268) 
                                                                                                    	at android.os.Looper.loop(Looper.java:384) 
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:8921) 
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method) 
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580) 
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:907) 
                                                                                                    Caused by: android.os.RemoteException: Remote stack trace:
                                                                                                    	at com.android.server.am.ActiveServices.validateForegroundServiceType(ActiveServices.java:2921)
                                                                                                    	at com.android.server.am.ActiveServices.setServiceForegroundInnerLocked(ActiveServices.java:2605)
                                                                                                    	at com.android.server.am.ActiveServices.setServiceForegroundLocked(ActiveServices.java:1859)
                                                                                                    	at com.android.server.am.ActivityManagerService.setServiceForeground(ActivityManagerService.java:14552)
                                                                                                    	at android.app.IActivityManager$Stub.onTransact$setServiceForeground$(IActivityManager.java:12183)

Additionally i removed foregroundServiceType phoneCall (it must not be used and Lint checks complained)

🏁 Checklist

  • ⛑️ Tests (unit and/or integration) are included or not needed
  • 🔖 Capability is checked or not needed
  • 🔙 Backport requests are created or not needed: /backport to stable-xx.x
  • 📅 Milestone is set
  • 🌸 PR title is meaningful (if it should be in the changelog: is it meaningful to users?)

@mahibi
mahibi requested a review from rapterjet2004 October 17, 2025 08:41
@mahibi mahibi self-assigned this Oct 17, 2025
@mahibi mahibi added the 3. to review Waiting for reviews label Oct 17, 2025
@mahibi
mahibi enabled auto-merge October 17, 2025 13:32
@mahibi
mahibi force-pushed the bugfix/noid/fixForegroundServicePermissionCrash branch from a75c144 to d10dcc9 Compare October 20, 2025 11:04
@mahibi mahibi changed the title fix foreground service permission crash fix foreground service permission crash + add FOREGROUND_SERVICE_PHONE_CALL permission Oct 20, 2025
@mahibi
mahibi force-pushed the bugfix/noid/fixForegroundServicePermissionCrash branch from 32ee3e2 to da08cca Compare October 20, 2025 13:51
@mahibi mahibi changed the title fix foreground service permission crash + add FOREGROUND_SERVICE_PHONE_CALL permission fix foreground service permission crash + remove phone call permission + fix "requires API level" checks Oct 20, 2025
when record_audio permission was not granted, this crash appeared because foreground service must only be started with the granted permission:

2025-10-17 09:56:01.459 14445-14445 AndroidRuntime          com.nextcloud.talk2                  E  FATAL EXCEPTION: main (Ask Gemini)
                                                                                                    Process: com.nextcloud.talk2, PID: 14445
                                                                                                    java.lang.RuntimeException: Unable to start service com.nextcloud.talk.services.CallForegroundService@a9cff99 with Intent { cmp=com.nextcloud.talk2/com.nextcloud.talk.services.CallForegroundService (has extras) }: java.lang.SecurityException: Starting FGS with type microphone callerApp=ProcessRecord{1b5bf24 14445:com.nextcloud.talk2/u0a397} targetSDK=35 requires permissions: all of the permissions allOf=true [android.permission.FOREGROUND_SERVICE_MICROPHONE] any of the permissions allOf=false [android.permission.CAPTURE_AUDIO_HOTWORD, android.permission.CAPTURE_AUDIO_OUTPUT, android.permission.CAPTURE_MEDIA_OUTPUT, android.permission.CAPTURE_TUNER_AUDIO_INPUT, android.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT, android.permission.RECORD_AUDIO]  and the app must be in the eligible state/exemptions to access the foreground only permission
                                                                                                    	at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:5295)
                                                                                                    	at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(Unknown Source:0)
                                                                                                    	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2580)
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:112)
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:268)
                                                                                                    	at android.os.Looper.loop(Looper.java:384)
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:8921)
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method)
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580)
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:907)
                                                                                                    Caused by: java.lang.SecurityException: Starting FGS with type microphone callerApp=ProcessRecord{1b5bf24 14445:com.nextcloud.talk2/u0a397} targetSDK=35 requires permissions: all of the permissions allOf=true [android.permission.FOREGROUND_SERVICE_MICROPHONE] any of the permissions allOf=false [android.permission.CAPTURE_AUDIO_HOTWORD, android.permission.CAPTURE_AUDIO_OUTPUT, android.permission.CAPTURE_MEDIA_OUTPUT, android.permission.CAPTURE_TUNER_AUDIO_INPUT, android.permission.CAPTURE_VOICE_COMMUNICATION_OUTPUT, android.permission.RECORD_AUDIO]  and the app must be in the eligible state/exemptions to access the foreground only permission
                                                                                                    	at android.os.Parcel.createExceptionOrNull(Parcel.java:3242)
                                                                                                    	at android.os.Parcel.createException(Parcel.java:3226)
                                                                                                    	at android.os.Parcel.readException(Parcel.java:3209)
                                                                                                    	at android.os.Parcel.readException(Parcel.java:3151)
                                                                                                    	at android.app.IActivityManager$Stub$Proxy.setServiceForeground(IActivityManager.java:7326)
                                                                                                    	at android.app.Service.startForeground(Service.java:863)
                                                                                                    	at com.nextcloud.talk.services.CallForegroundService.onStartCommand(CallForegroundService.kt:38)
                                                                                                    	at android.app.ActivityThread.handleServiceArgs(ActivityThread.java:5277)
                                                                                                    	at android.app.ActivityThread.-$$Nest$mhandleServiceArgs(Unknown Source:0) 
                                                                                                    	at android.app.ActivityThread$H.handleMessage(ActivityThread.java:2580) 
                                                                                                    	at android.os.Handler.dispatchMessage(Handler.java:112) 
                                                                                                    	at android.os.Looper.loopOnce(Looper.java:268) 
                                                                                                    	at android.os.Looper.loop(Looper.java:384) 
                                                                                                    	at android.app.ActivityThread.main(ActivityThread.java:8921) 
                                                                                                    	at java.lang.reflect.Method.invoke(Native Method) 
                                                                                                    	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:580) 
                                                                                                    	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:907) 
                                                                                                    Caused by: android.os.RemoteException: Remote stack trace:
                                                                                                    	at com.android.server.am.ActiveServices.validateForegroundServiceType(ActiveServices.java:2921)
                                                                                                    	at com.android.server.am.ActiveServices.setServiceForegroundInnerLocked(ActiveServices.java:2605)
                                                                                                    	at com.android.server.am.ActiveServices.setServiceForegroundLocked(ActiveServices.java:1859)
                                                                                                    	at com.android.server.am.ActivityManagerService.setServiceForeground(ActivityManagerService.java:14552)
                                                                                                    	at android.app.IActivityManager$Stub.onTransact$setServiceForeground$(IActivityManager.java:12183)

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
…Type

This should resolve the (misleading?) lint error:
To call Service.startForeground(), the <service> element of manifest file must have the foregroundServiceType attribute specified

and FOREGROUND_SERVICE_TYPE_PHONE_CALL is only for default dialer apps which is not needed in our case.

Also, avoid android version complains regarding service types:

Field requires API level 30 (current min is 26): android.content.pm.ServiceInfo#FOREGROUND_SERVICE_TYPE_CAMERA

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
just a test if this fixes the "Error: The operation was canceled."

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
just a test if this fixes the "Error: The operation was canceled."

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
To devs it's the same, but the change appeases Lint because it fits the analyzer’s limited static-flow model

If this does not work out again, last quite bad option here may be to suppress

Also remove useless check for version Q

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
@mahibi
mahibi force-pushed the bugfix/noid/fixForegroundServicePermissionCrash branch from c8027dd to 633cfb0 Compare October 22, 2025 11:40
for now i give up to understand the warning

 "To call Service.startForeground(), the <service> element of manifest file must have the foregroundServiceType attribute specified"

 From my pov everything is correct!

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
@github-actions

Copy link
Copy Markdown
Contributor

APK file: https://www.kaminsky.me/nc-dev/android-artifacts/5483.apk

qrcode

To test this change/fix you can simply download above APK file and install and test it in parallel to your existing Nextcloud app.

@github-actions

Copy link
Copy Markdown
Contributor

Codacy

Lint

TypemasterPR
Warnings9998
Errors00

SpotBugs

CategoryBaseNew
Bad practice66
Correctness1111
Dodgy code6262
Internationalization33
Malicious code vulnerability33
Performance44
Security11
Total9090

@mahibi
mahibi merged commit 217fd53 into master Oct 22, 2025
15 of 18 checks passed
@mahibi
mahibi deleted the bugfix/noid/fixForegroundServicePermissionCrash branch October 22, 2025 12:56
@mahibi

mahibi commented Oct 22, 2025

Copy link
Copy Markdown
Collaborator Author

Wow finally green CI and merged..
i had much fun with the permissions, seems lint is not smart enough to understand the dynamic foreground service types that are passed to startForeground. So in the end the last option that i took was to suppress it with

@Suppress("ForegroundServiceType")

Other than that i experimented with memory for analysis.yml (just randomly picked this branch as it was just about getting the CI green..)
So 3GB seems to work for other builds as well. PR to have this via android-config repo is nextcloud/android-config#308

mahibi added a commit that referenced this pull request Oct 31, 2025
As there was no good standalone PR for backporting, i do this change directly on stable-22.0

Related PRs:

nextcloud/android-config#308
#5483

Signed-off-by: Marcel Hibbe <dev@mhibbe.de>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

3. to review Waiting for reviews

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants