Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Android audio service killed by OS, restart not possible #247

Closed
Sauceee opened this issue Apr 9, 2020 · 8 comments
Closed

Android audio service killed by OS, restart not possible #247

Sauceee opened this issue Apr 9, 2020 · 8 comments
Assignees
Labels

Comments

@Sauceee
Copy link
Contributor

Sauceee commented Apr 9, 2020

Describe the bug
If the android audio background service is killed by the OS, it seems some Resources are not cleaned. This happens constantly when "androidStopForegroundOnPause == true".

Error messages
No direct error message

Minimal reproduction project
Example project with "androidStopForegroundOnPause == true".

To Reproduce
Steps to reproduce the behavior:

  1. Start the audio
  2. Pause audio
  3. Press home button to minimize the app
  4. Wait for the notification to be killed by the OS
  5. Open the app again
  6. Result: Some background task is in a weird state and cannot be restarted

Expected behavior
Expected would be, that the background task is cleared in the same way when the audio service is normally stopped by AudioService.stop

Flutter SDK version
[√] Flutter (Channel stable, v1.12.13+hotfix.9, on Microsoft Windows [Version 10.0.18363.752], locale de-DE)
[√] Android toolchain - develop for Android devices (Android SDK version 29.0.2)
[√] Android Studio (version 3.6)
[√] Connected device (1 available)
• No issues found!

Attempt to fix the problem
I played with the java code a bit and this changes seems to fix the problem for me, I am sure there is a cleaner way to fix it.

Change code in AudioService.java method onDestroy:

	@Override
	public void onDestroy() {
		super.onDestroy();
		if (listener != null) {
			listener.onDestroy();
		}
		instance = null;
	}

Add onDestroy listener function:
void onDestroy();

Add code in AudioServicePlugin.java

		@Override
		public void onDestroy() {
			AudioService.instance.stop();
			if (silenceAudioTrack != null)
				silenceAudioTrack.release();
			if (clientHandler != null) clientHandler.invokeMethod("onStopped");
			backgroundFlutterEngine.destroy();
			backgroundFlutterEngine = null;
			backgroundHandler = null;
		}
@mohammadne
Copy link

I think if you pause audio and press home button, waiting for notification to be killed is not an expected behavior.

@Sauceee
Copy link
Contributor Author

Sauceee commented Apr 9, 2020

But its very likely to happen that some user pauses the audio, minimizes the app and the service will get killed. If the user tries to start the audio again after that, it will fail.

Maybe I do not understand what you mean by expected behavior. It happens, thats the problem, even if its not expected. :)

Edit: Was also only one way to reproduce it. Also happens if the app is in background and the user pauses it in the notification.

@ryanheise ryanheise self-assigned this Apr 10, 2020
@ryanheise
Copy link
Owner

@Sauceee

This is a good point. I don't use this feature myself, although I can see that if anyone did want to use it, there needs to be some way to handle the case where the service is killed while it's paused.

I will leave this open in the hopes that someone wants to contribute a PR.

As part of the solution, what is needed is a way to fire back up the background isolate when the user presses "play" if it is detected that the isolate is not currently running.

This feature could also be related to another desirable feature where if the service is explicitly stopped by the user, we can still keep the media session responsive, so if the user presses the play/pause button on their headset, it will contact the most recently active media session and deliver a play event. In this case, too, we should detect that the background isolate is not currently running and fire it back up.

@Sauceee
Copy link
Contributor Author

Sauceee commented Apr 10, 2020

@ryanheise

What do you think about the code changes I mentioned in the issue, do they make any sense to you?

What I tried to achieve is that if the service gets killed, at least everything is cleaned up like if the user stopped it by himself. Only reliable why I found was onDestroy().

With this changes the user can at least restart the audio normally with the UI, without the mentioned "incomplete" state occurring.

As I read in the Android docs it could happen also in forground, just very unlikely:
It is still theoretically possible for the service to be killed under extreme memory pressure from the current foreground application, but in practice this should not be a concern.

@ryanheise
Copy link
Owner

@Sauceee

I've reviewed your code above and it looks reasonable to me. And of course the onDestroy code could be put in a reusable method since it is shared with the "stop" method channel case.

@Sauceee
Copy link
Contributor Author

Sauceee commented Apr 10, 2020

@ryanheise

Thanks for your review, I made a pull request with a reusable method!

@ryanheise
Copy link
Owner

Merged, thank you!

@github-actions
Copy link

This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs, or use StackOverflow if you need help with audio_service.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Oct 21, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants