fix(android): stop ActiveCallService when restarted with no calls metadata (WT-1139) - #367
Merged
Merged
Conversation
…adata (WT-1139) A system restart of the active-call service after a process kill used to leave a half-empty ongoing notification that could not be swiped away, with Hang up having no effect - only force-stopping the app removed it. The service now detects such an empty restart, cleans up any surviving call leg, removes the notification and stops itself; a Hang up tapped on a fresh instance hangs up the specific call it was tapped for instead of tearing everything down. The services document is updated to describe the guarded behavior it previously listed as a known limitation. Verified by the restart tests introduced with the reproduction change, now asserting the corrected behavior, and the full native suite.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Overview
Supersedes #346 with the same change rebuilt as a single commit on top of the current develop.
A START_STICKY restart after a process kill delivers a null intent, leaving
ActiveCallServicewith an empty calls list. TheNotificationManagerstatic list of active calls lives in the:callkeep_coreprocess and died with it, so nothing ever stops the orphaned instance: its ongoing FGS notification stays in the shade, cannot be swiped away, and the Hang up action has no visible effect (tearDownServicetears down the connection services but does not stop this one). The user has to force-stop the app to get rid of the notification. The defect is pinned by the reproduction tests merged in #366; this change flips them to the corrected behavior.Changes
ActiveCallService:onStartCommand: after satisfying thestartForegroundcontract, an instance with no calls metadata logs a WARN, tears down the connection services, removes the notification and stops itself, returningSTART_NOT_STICKY. The teardown matters beyond the notification: if only the main process was killed, a call leg may have survived in:callkeep_core(Telecom keeps that process alive via its own binding), and this restart is the last signal the main process gets about it - without the teardown the device stays stuck in a zombie Telecom call with no UI to end it.StandaloneCallServicefallback, so the guard runs instead of crash-looping the restart.hungUpCallfalls back to theCallMetadatacarried in the Decline PendingIntent extras: a Hang up tap that creates a fresh service instance (the in-memory list is empty after process death) now hangs up the specific call via the normal SIP BYE flow instead of tearing all connections down. The tear-down branch remains only for the truly unknown case (a notification re-posted by a null-intent restart carries no extras).stopSelf(startId)(extracted into atearDownAndStop(startId)helper), so a newer start with real metadata already queued behind the current command (the recovering app re-posting its call list) survives together with its foreground notification."metadata"intent extra key is promoted toActiveCallService.EXTRA_CALLS_METADATA, shared by the writer (NotificationManager.upsertActiveCallsService), the reader and the test.The normal path deliberately stays
START_STICKY: the sticky restart is now the mechanism that delivers the zombie-leg cleanup above, and the guard'sSTART_NOT_STICKYreturn prevents any restart loop (one restart, one cleanup, done).Related cleanups:
IncomingCallService.performAnswerCall: dropped the misleadingSTART_STICKYreturn value - the method is called fromonConnectionEventonly, so the value never reachedonStartCommand(that service deliberately staysSTART_NOT_STICKYeverywhere).background-services.md: the section that described this scenario as an open limitation now describes the guarded behavior, and the Lifecycle / Hang up notes match the code above.Tests
ActiveCallServiceRestartTestreplaces the reproduction version of the file from #366 - the same scenarios now assert the corrected behavior:Full Android native suite: 253 tests, 0 failures.