Skip to content

Fix ghost notifications and fix "did not then call startForeground()"#12606

Merged
Stypox merged 2 commits intoTeamNewPipe:devfrom
Stypox:do-not-startService-randomly
Sep 30, 2025
Merged

Fix ghost notifications and fix "did not then call startForeground()"#12606
Stypox merged 2 commits intoTeamNewPipe:devfrom
Stypox:do-not-startService-randomly

Conversation

@Stypox
Copy link
Member

@Stypox Stypox commented Sep 6, 2025

What is it?

  • Bugfix (user facing)
  • Feature (user facing)
  • Codebase improvement (dev facing)
  • Meta improvement to the project (dev facing)

Description of the changes in your PR

This PR fixes one way ghost notifications could be produced (although I don't know if there are other ways). This is the call chain that would lead to ghost notifications being created:

  1. the system starts PlayerService to query information from it, without providing SHOULD_START_FOREGROUND_EXTRA=true, so NewPipe does not start the player nor show any notification, as expected
  2. the PlayerHolder::serviceConnection.onServiceConnected() gets called by the system to inform PlayerHolder that the player started
  3. PlayerHolder notifies MainActivity that the player has started (although in fact only the service has started), by sending a ACTION_PLAYER_STARTED broadcast
  4. MainActivity receives the ACTION_PLAYER_STARTED broadcast and brings up the mini-player, but then also tries to make PlayerHolder bind to PlayerService just in case it was not bound yet, but does so using PlayerHolder::startService() instead of the more passive PlayerHolder::tryBindIfNeeded()
  5. PlayerHolder::startService() sends an intent to the PlayerService again, this time with startForegroundService and with SHOULD_START_FOREGROUND_EXTRA=true
  6. the PlayerService receives the intent and due to SHOULD_START_FOREGROUND_EXTRA=true decides to start up the player and show a dummy notification

Steps 3 and 4 are wrong, and this PR fixes them:
3. PlayerHolder will now broadcast ACTION_PLAYER_STARTED when the service connects, only if the player is not-null
4. PlayerHolder::tryBindIfNeeded() is now used to passively try to bind, instead of PlayerHolder::startService()

Fixes the following issue(s)

APK testing

The APK can be found by going to the "Checks" tab below the title. On the left pane, click on "CI", scroll down to "artifacts" and click "app" to download the zip file which contains the debug APK of this PR. You can find more info and a video demonstration on this wiki page.

Testing APK: pr12606.zip

Due diligence

@github-actions github-actions bot added the size/small PRs with less than 50 changed lines label Sep 6, 2025
@Stypox Stypox force-pushed the do-not-startService-randomly branch from 1362612 to a0fcf18 Compare September 6, 2025 11:09
@Stypox Stypox added this to v0.28.x Sep 6, 2025
@Stypox Stypox moved this to In Progress in v0.28.x Sep 6, 2025
@AudricV AudricV added bug Issue is related to a bug player Issues related to any player (main, popup and background) player notification Anything to do with the MediaStyle notification labels Sep 7, 2025
Copy link
Contributor

@TobiGr TobiGr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the changes look reasonable to me. And as per #12489 (comment) they seem to fix the problem.

@github-actions github-actions bot added size/medium PRs with less than 250 changed lines and removed size/small PRs with less than 50 changed lines labels Sep 17, 2025
This commit fixes one way ghost notifications could be produced (although I don't know if there are other ways). This is the call chain that would lead to ghost notifications being created:
1. the system starts `PlayerService` to query information from it, without providing `SHOULD_START_FOREGROUND_EXTRA=true`, so NewPipe does not start the player nor show any notification, as expected
2. the `PlayerHolder::serviceConnection.onServiceConnected()` gets called by the system to inform `PlayerHolder` that the player started
3. `PlayerHolder`  notifies `MainActivity` that the player has started (although in fact only the service has started), by sending a `ACTION_PLAYER_STARTED` broadcast
4. `MainActivity` receives the `ACTION_PLAYER_STARTED` broadcast and brings up the mini-player, but then also tries to make `PlayerHolder` bind to `PlayerService` just in case it was not bound yet, but does so using `PlayerHolder::startService()` instead of the more passive `PlayerHolder::tryBindIfNeeded()`
5. `PlayerHolder::startService()` sends an intent to the `PlayerService` again, this time with `startForegroundService` and with `SHOULD_START_FOREGROUND_EXTRA=true`
6. the `PlayerService` receives the intent and due to `SHOULD_START_FOREGROUND_EXTRA=true` decides to start up the player and show a dummy notification

Steps 3 and 4 are wrong, and this commit fixes them:
3. `PlayerHolder` will now broadcast `ACTION_PLAYER_STARTED` when the service connects, only if the player is not-null
4. `PlayerHolder::tryBindIfNeeded()` is now used to passively try to bind, instead of `PlayerHolder::startService()`
This should solve "Context.startForegroundService() did not then call Service.startForeground()" according to TeamNewPipe#12489 (comment)
@Stypox Stypox force-pushed the do-not-startService-randomly branch from bff51c2 to aa2b482 Compare September 17, 2025 09:50
@Stypox
Copy link
Member Author

Stypox commented Sep 17, 2025

@TobiGr the APK that was tested in #12489 (comment) was based on one further commit (see the diff in my comment on the issue), which I now pushed here

Copy link
Contributor

@TobiGr TobiGr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Those changes also LGTM

@Stypox
Copy link
Member Author

Stypox commented Sep 30, 2025

Merging so people can start testing this in nightlies

@Stypox Stypox merged commit e2026dc into TeamNewPipe:dev Sep 30, 2025
6 checks passed
@github-project-automation github-project-automation bot moved this from In Progress to Done in v0.28.x Sep 30, 2025
@Stypox Stypox changed the title Fix ghost notifications Fix ghost notifications and fix "did not then call startForeground()" Oct 1, 2025
@TobiGr TobiGr mentioned this pull request Dec 21, 2025
4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Issue is related to a bug player notification Anything to do with the MediaStyle notification player Issues related to any player (main, popup and background) size/medium PRs with less than 250 changed lines

Projects

Status: Done

Development

Successfully merging this pull request may close these issues.

PlayerService crash: Context.startForegroundService() did not then call Service.startForeground()

3 participants