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

Making a Kivy System app on Android #3075

Open
sebinho opened this issue Oct 19, 2024 · 3 comments
Open

Making a Kivy System app on Android #3075

sebinho opened this issue Oct 19, 2024 · 3 comments

Comments

@sebinho
Copy link

sebinho commented Oct 19, 2024

Let me explain what I am trying to do. I have an Orange Pi 5 Plus on which I am running Android 12. I did build a Kivy application that is working well (Kivy can be used to make Applications using Python). But some very specific reasons, I would like to make this application a system app.

When I installed the application normally with no special privileges, it works well. When I recompile Android12 and integrate the app on the product partition, it does not work.

When I launch the application, I first get an error message displayed on the scree saying: Could not extract /product/priv-app/myapp/lib/arm64/libpybundle data.

Then when I look at logcat, I see FATAL exception related to UnsatisfiedLinkError: No implementation found for void org.libsdl.app.SDLActivity.nativeSetenv.

Here is the log I get.

10-19 23:06:46.136   610  3321 I ActivityTaskManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10200000 cmp=org.test.myapp/org.kivy.android.PythonActivity bnds=[1276,609][1592,761]} from uid 10079
10-19 23:06:46.171   610   667 I ActivityManager: Start proc 3338:org.test.myapp/1000 for pre-top-activity {org.test.myapp/org.kivy.android.PythonActivity}
--------- beginning of main
10-19 23:06:46.248  3338  3338 V GraphicsEnvironment: ANGLE Developer option for 'org.test.myapp' set to: 'default'
10-19 23:06:46.248  3338  3338 V GraphicsEnvironment: ANGLE GameManagerService for org.test.myapp: false
--------- beginning of crash
10-19 23:06:46.369  3338  3338 E AndroidRuntime: FATAL EXCEPTION: SDLActivity
10-19 23:06:46.369  3338  3338 E AndroidRuntime: Process: org.test.myapp, PID: 3338
10-19 23:06:46.369  3338  3338 E AndroidRuntime: java.lang.UnsatisfiedLinkError: No implementation found for void org.libsdl.app.SDLActivity.nativeSetenv(java.lang.String, java.lang.String) (tried Java_org_libsdl_app_SDLActivity_nativeSetenv and Java_org_libsdl_app_SDLActivity_nativeSetenv__Ljava_lang_String_2Ljava_lang_String_2)
10-19 23:06:46.369  3338  3338 E AndroidRuntime:    at org.libsdl.app.SDLActivity.nativeSetenv(Native Method)
10-19 23:06:46.369  3338  3338 E AndroidRuntime:    at org.kivy.android.PythonActivity$UnpackFilesTask.onPostExecute(PythonActivity.java:158)
10-19 23:06:46.369  3338  3338 E AndroidRuntime:    at org.kivy.android.PythonActivity$UnpackFilesTask.onPostExecute(PythonActivity.java:102)
10-19 23:06:46.369  3338  3338 E AndroidRuntime:    at android.os.AsyncTask.finish(AsyncTask.java:771)
10-19 23:06:46.369  3338  3338 E AndroidRuntime:    at android.os.AsyncTask.access$900(AsyncTask.java:199)
10-19 23:06:46.369  3338  3338 E AndroidRuntime:    at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:788)
10-19 23:06:46.369  3338  3338 E AndroidRuntime:    at android.os.Handler.dispatchMessage(Handler.java:106)
10-19 23:06:46.369  3338  3338 E AndroidRuntime:    at android.os.Looper.loopOnce(Looper.java:201)
10-19 23:06:46.369  3338  3338 E AndroidRuntime:    at android.os.Looper.loop(Looper.java:288)
10-19 23:06:46.369  3338  3338 E AndroidRuntime:    at android.app.ActivityThread.main(ActivityThread.java:7870)
10-19 23:06:46.369  3338  3338 E AndroidRuntime:    at java.lang.reflect.Method.invoke(Native Method)
10-19 23:06:46.369  3338  3338 E AndroidRuntime:    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:548)
10-19 23:06:46.369  3338  3338 E AndroidRuntime:    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1003)
10-19 23:06:46.370   610  2995 W ActivityTaskManager:   Force finishing activity org.test.myapp/org.kivy.android.PythonActivity
10-19 23:06:46.393   610  1339 I ActivityManager: Process org.test.myapp (pid 3338) has died: fg  TOP 
10-19 23:06:46.393   610  1050 I WindowManager: WIN DEATH: Window{bf9e3f6 u0 org.test.myapp/org.kivy.android.PythonActivity}
10-19 23:06:46.393   610  1050 W InputManager-JNI: Input channel object 'bf9e3f6 org.test.myapp/org.kivy.android.PythonActivity (client)' was disposed without first being removed with the input manager!
10-19 23:06:46.394   610   702 I WindowManager: WIN DEATH: Window{138fccd u0 org.test.myapp/org.kivy.android.PythonActivity}
10-19 23:06:46.394   610   702 W InputManager-JNI: Input channel object '138fccd org.test.myapp/org.kivy.android.PythonActivity (client)' was disposed without first being removed with the input manager!
10-19 23:06:46.413   610   661 W InputManager-JNI: Input channel object 'af93b09 Splash Screen org.test.myapp (client)' was disposed without first being removed with the input manager!
10-19 23:06:46.871   610   660 W ActivityTaskManager: Activity top resumed state loss timeout for ActivityRecord{b390ac2 u0 org.test.myapp/org.kivy.android.PythonActivity t-1 f}}

Does anybody have a clue what is going wrong? Any help would be much appreciated. Thanks

I am expecting the application to run the same way as a user app.

@sebinho
Copy link
Author

sebinho commented Oct 20, 2024

Adding some context to this issue.

When I look at the logcat for when I try to open the application for the first time, I can see that there is an issue when trying to extract the app data. It cannot find the *.so files that are actually contained within the APK. See log below

10-20 12:19:21.271  2332  2361 V PythonActivity: Ready to unpack
10-20 12:19:21.272  2332  2361 V pythonutil: Unpacking private app
10-20 12:19:21.272  2332  2361 V pythonutil: Data version is ef1b7004a93c1d23484e74edb34cf6112ffd2755
10-20 12:19:21.273  2332  2361 V pythonutil: Extracting private assets.
10-20 12:19:21.275  2332  2361 V python  : extracting data/
10-20 12:19:21.276  2332  2361 V python  : extracting data/images/
10-20 12:19:21.276  2332  2361 V python  : extracting data/images/logo_white.png
10-20 12:19:21.278  2332  2361 V python  : extracting data/images/logo_app.png
10-20 12:19:21.279  2332  2361 V python  : extracting data/images/logo_app_loading.png
10-20 12:19:21.281  2332  2361 V python  : extracting listdevices.kv
10-20 12:19:21.281  2332  2361 V python  : extracting main.pyc
10-20 12:19:21.281  2332  2361 V python  : extracting sitecustomize.pyc
10-20 12:19:21.282  2332  2361 V python  : extracting p4a_env_vars.txt
10-20 12:19:21.283  2332  2361 V pythonutil: Unpacking /product/priv-app/myapp/lib/arm64/libpybundle app
10-20 12:19:21.283  2332  2361 V pythonutil: Data version is ef1b7004a93c1d23484e74edb34cf6112ffd2755
10-20 12:19:21.283  2332  2361 V pythonutil: Extracting /product/priv-app/myapp/lib/arm64/libpybundle assets.
10-20 12:19:21.284  2332  2361 E python  : opening up extract tar
10-20 12:19:21.284  2332  2361 E python  : java.io.FileNotFoundException: /product/priv-app/myapp/lib/arm64/libpybundle.so: open failed: ENOENT (No such file or directory)
10-20 12:19:21.284  2332  2361 E python  : 	at libcore.io.IoBridge.open(IoBridge.java:575)
10-20 12:19:21.284  2332  2361 E python  : 	at java.io.FileInputStream.<init>(FileInputStream.java:160)
10-20 12:19:21.284  2332  2361 E python  : 	at java.io.FileInputStream.<init>(FileInputStream.java:115)
10-20 12:19:21.284  2332  2361 E python  : 	at org.renpy.android.AssetExtract.extractTar(AssetExtract.java:43)
10-20 12:19:21.284  2332  2361 E python  : 	at org.kivy.android.PythonUtil.unpackPyBundle(PythonUtil.java:241)
10-20 12:19:21.284  2332  2361 E python  : 	at org.kivy.android.PythonActivity$UnpackFilesTask.doInBackground(PythonActivity.java:108)
10-20 12:19:21.284  2332  2361 E python  : 	at org.kivy.android.PythonActivity$UnpackFilesTask.doInBackground(PythonActivity.java:102)
10-20 12:19:21.284  2332  2361 E python  : 	at android.os.AsyncTask$3.call(AsyncTask.java:394)
10-20 12:19:21.284  2332  2361 E python  : 	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
10-20 12:19:21.284  2332  2361 E python  : 	at android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java:305)
10-20 12:19:21.284  2332  2361 E python  : 	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
10-20 12:19:21.284  2332  2361 E python  : 	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
10-20 12:19:21.284  2332  2361 E python  : 	at java.lang.Thread.run(Thread.java:920)
10-20 12:19:21.284  2332  2361 E python  : Caused by: android.system.ErrnoException: open failed: ENOENT (No such file or directory)
10-20 12:19:21.284  2332  2361 E python  : 	at libcore.io.Linux.open(Native Method)
10-20 12:19:21.284  2332  2361 E python  : 	at libcore.io.ForwardingOs.open(ForwardingOs.java:567)
10-20 12:19:21.284  2332  2361 E python  : 	at libcore.io.BlockGuardOs.open(BlockGuardOs.java:273)
10-20 12:19:21.284  2332  2361 E python  : 	at libcore.io.ForwardingOs.open(ForwardingOs.java:567)
10-20 12:19:21.284  2332  2361 E python  : 	at android.app.ActivityThread$AndroidOs.open(ActivityThread.java:7756)
10-20 12:19:21.284  2332  2361 E python  : 	at libcore.io.IoBridge.open(IoBridge.java:561)
10-20 12:19:21.284  2332  2361 E python  : 	... 12 more

So it seems that it cannot find libpybundle.so but it is contained within my APK. Here is the content of my APK file:

.
├── AndroidManifest.xml
├── assets
│   └── private.tar
├── classes2.dex
├── classes3.dex
├── classes4.dex
├── classes5.dex
├── classes.dex
├── lib
│   └── arm64
│       ├── libaddition.so
│       ├── libcrypto1.1.so
│       ├── libffi.so
│       ├── libmain.so
│       ├── libpybundle.so
│       ├── libpython3.11.so
│       ├── libSDL2_image.so
│       ├── libSDL2_mixer.so
│       ├── libSDL2.so
│       ├── libSDL2_ttf.so
│       ├── libsqlite3.so
│       └── libssl1.1.so
├── META-INF
│   ├── CERT.RSA
│   ├── CERT.SF
│   ├── com
│   │   └── android
│   │       └── build
│   │           └── gradle
│   │               └── app-metadata.properties
│   └── MANIFEST.MF
├── res
│   ├── drawable
│   │   └── presplash.jpg
│   ├── drawable-hdpi-v4
│   │   └── ic_launcher.png
│   ├── drawable-mdpi-v4
│   │   └── ic_launcher.png
│   ├── drawable-xhdpi-v4
│   │   └── ic_launcher.png
│   ├── drawable-xxhdpi-v4
│   │   └── ic_launcher.png
│   ├── layout
│   │   ├── chooser_item.xml
│   │   ├── main.xml
│   │   ├── project_chooser.xml
│   │   └── project_empty.xml
│   ├── mipmap
│   │   └── icon.png
│   └── xml
│       └── device_filter.xml
└── resources.arsc

As I mentioned originally, the app is working well when simply installed using adb install myapp.apk, so when it is located in the /data/ user space.
But it does not work if I try to make it a system app. To make it a system app, I added the following section in the AndroidManifest.xml:

coreApp="true"
android:sharedUserId="android.uid.system"

Any idea what is going wrong? Not sure that anybody ever tried to make a Kivy application a system app...

@T-Dynamos
Copy link
Contributor

I think your android system supports multiple abis try apk with armebai-v7a.

@sebinho
Copy link
Author

sebinho commented Oct 21, 2024

thanks for your proposal.
I was able to find a fix for this issue. But I could not find a way to make it a system app while baking it directly into the super.img partition.

I had to build my application like a normal user application. Then I install it with adb install appname.apk. Finally I had to manually make it a system application with the following commands (using adb).

$ adb root
$ adb remount
$ adb shell mount -o rw,remount /system
$ adb shell
# Now find where your app is installed, typically in /data/app/~~XXXXXXX~~/appnameXXX/
# Example: ~~05uHorpdBvctQMKGK8P-PQ==/pl.solidexplorer2-SM049IQ_DyHHyV829yTloA==/
$ mkdir /system/priv-app/myapp
$ cp -rf /data/app/~~XXXXXXX~~/appnameXXX/* /system/priv-app/myapp

Once this is done, make sure to uninstall the original app and then reboot the system.

$ adb shell mount -o ro,remount /system
$ adb reboot

Hopefully this can be of help to others in the future. But I could not find a way to properly integrate the app directly onto Android partition.

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

No branches or pull requests

2 participants