OxygenCobalt / Auxio

A simple, rational music player for android
GNU General Public License v3.0
2.15k stars 143 forks source link

Service independence (Starting playback without opening app) #244

Closed etyarews closed 6 months ago

etyarews commented 2 years ago

Describe the feature you want to implement:

While Auxio have Intents, they are limited and don't work unless Auxio is already running in the background. My knowledge of programming is limited, but it appears the latter is caused by the type of intent.

Is your feature request related to a problem? Please describe:

I'm trying to control music playback through Auxio, namely I'm a user of Tasker and sometime between Android 7 and Android 12 it became unreliable to start music playback by just simulating a Media Button press. Intents appear to be the only solution left, and sadly the ones Auxio have are of the broadcast type.

Do other music players handle this? If so, how?

PowerApp actually does have it, they are of the Service type and I'm able to start them even after a reboot, and it has a long list of possible intents that I'm aware of:

Why do you think this will improve everyone's usage of Auxio?

While not useful to the majority of Auxio users, it will be incredibly helpful to the ones that are also Tasker users, and because it isn't a request for a Tasker Plug-in, it has could help users of that can send Intents.

Due Diligence:

OxygenCobalt commented 8 months ago

No, because currently the combined service would stop it's foreground state for 200ms and then start it again, which may be enough for android to consider that the service is now in the "background" and no longer allow it to go foreground again. At least, that's the idea I'm getting from the vague documentation.

etyarews commented 8 months ago

As long as there is a notification it should be fine

OxygenCobalt commented 8 months ago

Yes, and that's the change I have to make where I must hang on an existing notification when I exit foreground @etyarews. That's somewhat difficult since I need to know when some code is not certain that it will go foreground, which in turn requires it to indicate that it won't go foreground, something it is not doing.

etyarews commented 8 months ago

Why exactly do you need to exit foreground? You could start playback as a foreground service and then dismiss the notification

OxygenCobalt commented 8 months ago

You can't dismiss foreground notifications. You can only enter and exit foreground.

etyarews commented 8 months ago

Does media playback controls count as a notification?

OxygenCobalt commented 8 months ago

Yes. Media controls are a horrible shoddy hack built on notifications because Android has 10 layers of legacy cruft.

etyarews commented 8 months ago

But if it counts as a notification then it doesn't get killed for being a foreground service without foreground

OxygenCobalt commented 8 months ago

Basically:

etyarews commented 8 months ago

My confusion is because I don't see why it needs to stop being foreground. Can a foreground service starts another foreground service?

OxygenCobalt commented 8 months ago

Can a foreground service start another foreground service

A foreground service? Yes. A background service? No. To not unify would mean that I would have to create a fake notification no matter what just to have the ability to spin up the music service, which I severely dislike.

etyarews commented 8 months ago

Can't you just:

  1. Start Foreground Service to deal with library.
  2. Create notification to not kill the service
  3. Check if the library is already loaded, if not, then load it
  4. Anyway, when it ends, start Foreground Service to use Playback
  5. Create media notification for the Playback Foreground Service.
  6. Finish the Library Loading Service and dismiss its notification
OxygenCobalt commented 8 months ago

Number 2 is the deal breaker. I do not want a fake notification, I know other music players have pulled it off.

etyarews commented 8 months ago

It is not a fake notification if Auxio genuinely needs to load the library. It also provides feedback about the state of the loading

etyarews commented 8 months ago

Alternatively, if the Media Notification counts as a notification, you can just use that during loading, no? You could remove some buttons and change title to say something like "Now Loading"

OxygenCobalt commented 7 months ago

You might be right about this. I'm going to perform an experiment to see if this background restriction only applies once (i.e once I start foreground, I then have the free ability to go background and foreground whenever I want).

OxygenCobalt commented 7 months ago

Okay, this issue has spun out of control and has turned into a full re-architecture around Media3. If I mitigate the performance issues and figure out if there's a way to integrate space for the long-running music loading task, Media3 should automate most of this absurd notification lifecycle stuff away. I thought I wouldn't do this, but honestly I'm going to have to re-architecture no matter what if I use the low-level primitives and I may as well rip the band-aid off.

etyarews commented 7 months ago

This is getting way out of hand, please make sure if the change to Media3 will allow cold start before starting work on this

OxygenCobalt commented 6 months ago

Yep, this absolutely should @etyarews. I'm primarily doing this because it seemingly automates a lot of the service lifecycle management and should allow cold starts.

OxygenCobalt commented 6 months ago

Okay, here's the first demo of Auxio with an independent service @etyarews:

Auxio_Canary.zip

I'm sorry this took so long. If you can do certain things now, please test them and get back to me. If you need a tasker plugin, I'll need more time.

etyarews commented 6 months ago

Thanks man, really appreciate it.

That said, I'm rather confused how I might be able to control this debug version using Tasker or anything at all, I tried using Media Control, but it doesn't seem to work, just like the normal Auxio version.

Will have to test a bit and see if I'm doing something wrong, if Tasker is doing something wrong, or if it is an issue with Auxio.

OxygenCobalt commented 6 months ago

Okay, I actually took the time to test with tasker, and yeah it just doesn't work since it forwards to a BroadcastReceiver. I have to make a custom command set or a tasker plugin, basically. I'll have to work on that @etyarews.

OxygenCobalt commented 6 months ago

Okay, so @etyarews you could theoretically start a service with a forged MediaButtonIntent. This could possibly work, but the issue is that it would likely come before the service could fully initialize and would functionally be a no-op. I think I'll have to implement my own handling so I am able to tell when I'm able to forward playback actions and when I can't. The service can technically stand on it's own two feet though, so I'm closing it and spinning off the command handling into another issue.

etyarews commented 6 months ago

So, how would you run this service? Tasker can execute shell, and I think it can start with am startservice blablabla

OxygenCobalt commented 6 months ago

I believe you can make a System -> Send Intent action and then specify the intent name, package name, action, to line up with a MediaButtonIntent. This is really hard and fiddly, so while you could mess with that in the mean time I'm going to work on a tasker plugin I think. Tasker's default media controls are horrible @etyarews

etyarews commented 6 months ago

I'm just a little confused due to the wording used, as it implies that Auxio can now start playing music without running in the background, as an independent service was implemented.

But you didn't mention what service needs to be called or how to do it, let's ignore Tasker for a sec here, like, how are you starting this independent service?

OxygenCobalt commented 6 months ago

I'm just a little confused due to the wording used, as it implies that Auxio can now start playing music without running in the background, as an independent service was implemented.

This is true in theory. In practice the workflow to control the independent service now is currently just

This is obviously not ideal. A tasker plugin would be best, followed by easier-to-use custom intents.

But you didn't mention what service needs to be called or how to do it, let's ignore Tasker for a sec here, like, how are you starting this independent service?

Auxio is starting it as it did before, more or less. It doesn't send any commands through intents itself, it largely is still working as before.

To clarify: I reconfigured this issue to focus on a small part of what you wanted. In general, you want tasker/automation support, which requires custom command handling infrastructure, which requires service independence (this issue). Now that that step is done, I'll move on to the rest. Sorry for not being clear here @etyarews