Skip to content

Remove broadcastControl static variable - #15

Open
wise86-android wants to merge 2 commits into
Staacks:mainfrom
wise86-android:removeBroadcastControlVar
Open

Remove broadcastControl static variable#15
wise86-android wants to merge 2 commits into
Staacks:mainfrom
wise86-android:removeBroadcastControlVar

Conversation

@wise86-android

Copy link
Copy Markdown

this pr:

  • upgrade the some libs and the android gradle plugin
  • remove unused library (androidx.media)
  • move some constant in the companion object
  • remove the usage of a static variable to share the settings status

@wise86-android
wise86-android force-pushed the removeBroadcastControlVar branch from 0bc3c1d to 96d2cc2 Compare August 21, 2025 20:08
@Staacks

Staacks commented Aug 24, 2025

Copy link
Copy Markdown
Owner

Thanks for the contribution, but unfortunately I do not entirely understand all the points. I am relatively new to Kotlin, so maybe you could help me understand some of your changes:

  • Why would you move constants to the companion object? I have to admit that I put them where they were out of intuition from other languages, but I have now done some research and found some arguments against putting them in the companion object. After all, most arguments seem to be rather academic here, but I also do not see a coding style improvemet here. Similar question about putting the PreferencesKeys into the companion object.
  • Why would you remove the static broadcastControl? The point of it was to avoid having to suspend onReceive from the broadcast receiver as it holds the latest state immediately. Admittedly this once again is an intuitive old school decision, but I am not sure that your current solution using runBlocking is better. In fact, I am a bit worried if this is safe as I am neither sure if onReceive is running on the UI thread and if the scope is properly handled in this construct. Can you tell me more?

Also thanks for updating the library version, but I will have to skip this commit. I am currently running a public beta with the old versions and plan to release it soon. Unless there is something urgent in the new versions I would update the libraries when I start working on larger features again, which might be a while before I get around to this project again. I had some nasty surprises with blindly updating libraries in a different project...

@wise86-android

Copy link
Copy Markdown
Author

This PR does not introduce any new features or bug fixes, so please feel free to discard it if you prefer. I also fully agree with waiting until after your next release before merging anything like this.

  1. Constant vs companion

for the boradcast constant is just to give the variable a scope, those variables are used inside that object, so is nice to have it inside the object.

For the PreferencesKey values, the main reason is memory efficiency. When we create multiple instances of the Settings object, each instance also creates its own copy of those constants. This is unnecessary, since they are essentially just identifiers and can safely be shared. By putting them in a companion object (or even a top-level object), they are only allocated once.
Google also uses a similar approach in the DataStore codelab, where PreferencesKeys are placed inside an object to avoid redundant allocations.

  1. Static variables

This part is more a question of style. Personally, I try to avoid static variables because they make it harder to control when and how the value changes. Here it’s just a flag, but adding it to AlphaRemoteService gives that class extra responsibility on top of BLE + notifications.

Regarding threading: you are right, onReceive runs on the main thread, but the documentation says broadcast receivers can run for up to 10 seconds before causing an ANR (and are usually already bound by ~5 seconds due to main thread limits). Since we’re only reading a boolean, this should be well within the safe range. goAsync could be used to move work off the main thread, but the same execution limit still applies, so it will only complicate the code.

What I don’t really get is the purpose of the flag itself: if I set up another app to triggers the intent, why would I want to block it instead of just letting it complete?

@Staacks

Staacks commented Aug 29, 2025

Copy link
Copy Markdown
Owner

Thanks, the reasoning behind putting these into a companion object makes sense, although it still looks somewhat wrong to me. But the companion object feels weird anyway as I am more used to static Java objects.

About the blocking function, I agree that it should be nearly impossible to run into an issue here, but using a runBlocking here does not feel right.

The point of the flag is security: Allowing any app to control α-Remote and therefore the camera through this leaves all users open to at least some annoying shenanigans from third parties. In practice it might not be relevant as α-Remote is a niche app with very few users, but leaving all users open to any app on their phone sending arbitrary commands to their camera just isn't right. So, since this feature is used by only very few users who then understand how intents work, the flag allows this to be disabled by default unless explicitly activated. Seems to be common practice for several apps that expose potentially disruptive operations through this (for example "Gadget Bridge" which allows controlling Bluetooth connections through their "Intent API"). The big difference to other Broadcast Intents is that this one is not filtered at all, as it should be open to any creative use case.

So, thanks already, I learned a few new things and I will probably merge many of your suggestions next time I work on this project after the upcoming release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants