OxygenCobalt / Auxio

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

Tasker plugin #754

Open OxygenCobalt opened 1 month ago

OxygenCobalt commented 1 month ago

Self-explanatory, implement a tasker plugin so users don't have to forge intents to start Auxio independently. Docs.

etyarews commented 1 month ago

Well, might as well throw a wish list. And due to ambiguity, I need to explain things as if someone has never used Tasker.

Tasker has, broadly speaking, the concept of:

  1. Contexts: Auxio tells Tasker something is happening/has happened. There's two types: States (thing is happening) and Events (Thing happened)
  2. Actions: Tasker tells Auxio to do something. Most of the items in my wishlist can be repurposed as shortcuts. Playback ones are what I consider basic Tasker integration, and those should also have equivalent as shortcuts, I will put a bunch of ideas here with customization to ridiculous degrees, but just basic functionality is actually needed.

When you use a Plug-in Context/Action, usually what happens is that the app opens a fullscreen activity containing configs for that Plug-in Context/Action. This means that, for instance, you don't need an action for each playback option, a single playback action could allow the user to select what type of playback they want Auxio to execute.

Actions

Contexts

States: Something is happening on Auxio and you want Tasker to do something while the thing happens or stops happening. I can see two vaguely useful states:

Events: Basically something happened. Some states should have events variations because it really helps Task users, while other events can't be states.

OxygenCobalt commented 1 month ago

Okay, I'll need some time to process this.

I think all of these are fine minus Load Library. In Auxio all tasker commands would be queued and then executed once loading and state restore completes. I think instead you just execute your first command and then block on the "Library Loading" state and "Playback initialized" state until it's done, if that's possible.

Biggest issues I see is making sure the lifecycle is sensible and marshalling data around. I need to make sure it's usable by Auxio (i.e UID to use) while also being human-readable (include some extra metadata).

What strikes me is that this is very close to the surface provided by the Media3 API. Given my desire to make sure Auxio doesn't do too much, I wonder if this would be better as an external app that exposes Media or Media3 actions in any app as a generic tasker plugin @etyarews. But that's a lot harder to manage. I think I might start at bare minimum basic playback commands through #753 and a basic tasker plugin, then look into further extensions as they become useful.

OxygenCobalt commented 1 month ago

Re-marking as a maybe due to me needing more time to reflect. Don't worry, this isn't an outright rejection. I'm generally erring closer to this being a good idea since tasker is a "standard" automation tool, and it might provide solid infrastructure if Google decides to introduce their own automation tool a la iOS shortcuts.

etyarews commented 1 month ago

Yeah, this is more of a wishlist, a best case scenario for Tasker integration .

A more realistic expectation is just having an action to Play, which would satisfy most of the users. Actually, depending on the implementation, a single Static Shortcut would be more than enough.

Heck, if there's an ADB command to start playback that's more than enough. Pausing can be done through the notification.

I'm not actually sure if Tasker implementation of Media Controls is up to date. It actually works on pretty much everything once the player has started(I'm making Tasker open Auxio, wait a few seconds then start playback, which sucks because it doesn't work on a locked device), any issues it might have are swept under the rug as users don't expect most media apps to work from a cold boot after Android 11(?)

OxygenCobalt commented 1 month ago

I'm not actually sure if Tasker implementation of Media Controls is up to date. It actually works on pretty much everything once the player has started(I'm making Tasker open Auxio, wait a few seconds then start playback, which sucks because it doesn't work on a locked device), any issues it might have are swept under the rug as users don't expect most media apps to work from a cold boot after Android 11(?)

Tasker uses the very old MediaButtonIntent API that has existed since like Android Froyo I think. What Tasker should do is create a MediaController, bind to the app, and make more complicated requests. But given that Tasker has so much technical debt as is from it's UI and general behavior, I really don't want to make a patch for it.

etyarews commented 1 month ago

Eeeh, Tasker is very slowly getting a redesign to M3, and I'm the designer of that project. I've sent a message to the dev regarding the MediaController thing.

OxygenCobalt commented 3 weeks ago

I've decided that exposing a raw service API would be far easier to mess up than if I define some tasker actions, so I'll do this instead. I just have to work out lifecycle details though such that it's impossible for a tasker user to trigger a foreground crash.

OxygenCobalt commented 18 hours ago

Okay, I have arrived at an MVP tasker setup:

Action: Prepare Playback State: Available -> Whether Auxio's Service is 100% initialized

Implicit assumptions: You will call Prepare Playback, Block Until Available is True, and then immediately send some playback action that will trigger Auxio to foreground. If you don't, then expect Auxio to crash.

You can just use MediaButtons from then on, hopefully.

Since Tasker is for enthusiasts, I think it's fine to not have very many guardrails. I'll make it more robust if one day Google decides "hm... i wanna copy ios shortcuts...".

OxygenCobalt commented 17 hours ago

Wait, are you aware of any Tasker actions that take a long time to execute @etyarews? Perhaps I can just collapse it into one action by just looping until it's available.

etyarews commented 14 hours ago

Quite a number of actions can take a while to finish, specially if they involve the internet in some capacity.

A somewhat good rule of thumb is that it shouldn't take more than 30s to run an action. But honestly, the initial plan isn't that bad, but yeah, it it would be better to be a single action.

OxygenCobalt commented 14 hours ago

Okay, here's a build with a Tasker action that might work (I really don't know since I can't buy Tasker) @etyarews:

Auxio_Tasker.zip

etyarews commented 6 hours ago

Ok, it works but it is a pain to know when the service is ready to receive media buttons events.

etyarews commented 6 hours ago

Alright, it appears I need to run the plug-in action two times before it allows me to control Auxio with Media Buttons. I tried putting an wait action between the plug-in action and the media button action, but it doesn't appear to have worked as well as I hoped.

The issue is that the plug-in action only makes Auxio ready to receive media buttons, but there's no way of knowing when Auxio is actually ready. It is missing an state or event.

Either you add an event or state when Auxio is ready, or you refactor the action to immediately start playing.