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

WIP: workmanager and bound services support #2464

Open
wants to merge 35 commits into
base: develop
Choose a base branch
from

Conversation

rnixx
Copy link
Member

@rnixx rnixx commented Jun 16, 2021

This is a work in progress PR addressing upcoming restrictions with foreground services as of android 12.

See https://developer.android.com/about/versions/12/foreground-services

2 major improvements are implemented:

Currently the implementation lives in service_library bootstrap as this is what's needed right now for a project.

Maybe it makes sense to create a dedicated bootstrap for this features, as especially work managers might be very useful if called from a kivy app via jnius (e.g. tracking GPS periodically). Therefor we'd need a mechanism to optionally "merge" several bootstraps, e.g. a kivy app might depend on sdl and workmanager bootstraps or you would like to create a aar library including workmanager feature. We also might just add workmanager and bound service support to common bootstrap, but this implies some more build dependencies (androidx.work:work-runtime, androidx.work:work-multiprocess, androidx.concurrent:concurrent-futures)

While playing around with starting python in main.c, we came along the problem with injecting sys.exit when python ends. When using workmanager workers this would just kill the entire application so we made it optional. If someone can explain why injecting sys.exit is needed at all this would be nice.

TODO

  • Figure out the original need of injecting sys.exit when python ends and whether and when this needs to be kept.
  • Discuss whether to create a dedicated bootstrap for workmanager, or maybe just add it to common bootstraps since workmanager and bound service support are in general useful features
  • If added to common bootstraps, add some convenience API to android recipe to work with services and work managers.
  • Proper python shutdown if system requests workers to stop
  • Cleanup
  • Documentation

@rnixx rnixx requested review from opacam, AndreMiras and inclement June 16, 2021 06:39
@rnixx rnixx requested a review from tshirtman June 16, 2021 06:39
Copy link
Member

@AndreMiras AndreMiras left a comment

Choose a reason for hiding this comment

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

Thank you for looking into it ❤️
I was not aware of the upcoming in foreground services.
I took a first look at the PR and left a couple of comments

'src/main/java/{}/{}Worker.java'.format(
args.package.replace(".", "/"),
name.capitalize()
)
Copy link
Member

Choose a reason for hiding this comment

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

Minor: we could make a one-liner helper function/method that does that, so we have a single source of truth.

def get_target_path(package, name):
    return 'src/main/java/{}/Service{}.java'.format(package.replace(".", "/"), name.capitalize())

@@ -71,7 +71,7 @@ int file_exists(const char *filename) {
}

/* int main(int argc, char **argv) { */
int main(int argc, char *argv[]) {
int main_(int argc, char *argv[], int call_exit) {
Copy link
Member

Choose a reason for hiding this comment

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

What happened to the main?
I've never played with that part, but won't this get linking issues that the main is not exposed?

Copy link
Member Author

Choose a reason for hiding this comment

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

main only gets called from within the JNICALL functions, and my editor complained about the signature. so i renamed it, maybe start_python or so woud better fit.

// * so main() will run main.py from this dir
// */
// main_(1, argv, 0);
// }
Copy link
Member

Choose a reason for hiding this comment

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

Probably because it's still a WIP pull request, but I would not keep any commented out code in the final pull request

Copy link
Member Author

Choose a reason for hiding this comment

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

Sure, i played around with running the python thread within the calling process (which is not the case for services). As long as no concurrent python gets started this works fine, but crashes otherwise. So this approach cannot be used when starting workers from e.g. kivy. It is required to use RemoteWorkerService/RemoteWorker in this case, which again uses a dedicated process. The commented function is a relict and will be removed during cleanup.

@@ -356,7 +358,91 @@ int main(int argc, char *argv[]) {
return ret;
}

JNIEXPORT void JNICALL Java_org_kivy_android_PythonService_nativeStart(
JNIEXPORT int JNICALL Java_org_kivy_android_PythonService_nativeStart(
Copy link
Member

Choose a reason for hiding this comment

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

Only thing that changes between Java_org_kivy_android_PythonService_nativeStart(), Java_org_kivy_android_PythonWorker_nativeStart() and Java_org_kivy_android_PythonBoundService_nativeStart() is the function name.
Maybe we should share the body via a commun function

Copy link
Member Author

Choose a reason for hiding this comment

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

sure

@rtibbles
Copy link

rtibbles commented Apr 6, 2022

I see all tests are passing - does anything else need to be done with this PR before it's ready to go? Very keen to see this merged.

@dbnicholson
Copy link
Contributor

Any objections if I rebase this and polish it up? We'd like to be able to use this functionality.

@misl6
Copy link
Member

misl6 commented Apr 26, 2022

Any objections if I rebase this and polish it up? We'd like to be able to use this functionality.

Unless @rnixx wants to take care of it, I don't see any blocking.

@AndreMiras considering that you already started the review, any thoughts?

@AndreMiras
Copy link
Member

Sure go for it. I'm not as active as I used to be for test/reviews unfortunately

@rnixx
Copy link
Member Author

rnixx commented Dec 20, 2022

@misl6 @dbnicholson @zworkb

Sorry for leaving this PR abandoned for so long. Of course if have no problem if the work done so far gets picked up by someone else.

Referring to #2613

We had the use case to use p4a for a service only inside a native Kotlin application. In an accepted solutions this case ideally continues to work.

Referring the removal of the bound service - honestly i am a little out of our original context right now - this need to be double checked about the original intention.

@Bastian82
Copy link

Bastian82 commented Jan 19, 2023

Hi,
Any update on that ? WorkManager is crucial for having jobs not being stoped by android...

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.

7 participants