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

Improve the startup time and method of Python apps #9

Open
Abestanis opened this issue Jun 29, 2015 · 0 comments
Open

Improve the startup time and method of Python apps #9

Abestanis opened this issue Jun 29, 2015 · 0 comments

Comments

@Abestanis
Copy link
Owner

Summary

The current method how the Python app starts and communicates with the Python host works, but it is not very intuitive or fast. If anybody has any advice, feel free to comment or submit a pull request.

Here is an overview on what should happen on the Python app startup, how it's currently implemented and what I don't like about the current implementation:

What should happen

When the user starts the Python app, the Python app has to find a Python interpreter which must provide the paths to the python libraries and the path to the Python home.
If there are multiple Python interpreters installed on the Android device (maybe because of multiple Python versions), the user should be able to choose one of them and set one of them as the default.
The Python app then needs to load these libraries and call a specific native method.
With this implementation, the Python App executes code from an other app. To prevent any security issues, the Python app must be able to ensure that the Python interpreter app has a required permission.

If the method above is used, the user has full control to choose which Python interpreter he wants to use, there are no security issues and the Python files of the Python app are executed in the Python app's process.

Current implementation

Upon startup, the Python app starts an activity with an intent whose action is set to com.python.pythonhost.PYTHON_APP_GET_EXECUTION_INFO. The intent also contains the package of the Python app as a string and the classpath of an activity-class within the Python app.
If there are multiple apps who can receive the intent, Android displays a chooser-dialogue.

When the activity starts, it immediately starts an other activity.
The component of the intent for this new activity is set to the package and classpath given by the Python app. This means that the new activity points to an activity in the Python app.
The intent also contains a list of paths to the Python libraries.
The Python host can only start the new activity if he has the permission com.python.permission.PYTHONHOST. This is caused by the permission tag in the AndroidManifest of the Python app.

Within the new activity, the Python app loads the libraries and executes the native function startApp. This native function is actually defined in the application library, which is an library of the Python host.
As a consequence, this function must be "linked" with a Java class, before the Python app can call startApp. This is done during loading of the application library within the JNI_OnLoad function.
However, in order to register the method to the Java class, the classpath must be known. Since it is not possible to pass any arguments to the JNI_OnLoad function, the classpath gets retrieved via getenv from the environment variable JAVA_PYTHON_MAIN_CLASSPATH.
Unfortunately, Java has no direct way to set an environment variable, instead we need to call setenv via a library that belongs to the Python app.
The classpath is now passed to the JNI_OnLoad function via System.setProperty("python.android.entry.class", ...). There is no native library required.

Drawbacks of the current implementation

  • There are three activities starting, from which two just redirect to the next activity. I don't think we can get rid of the com.python.pythonhost.PYTHON_APP_GET_EXECUTION_INFO activity, without taking away the ability to chose, which Python interpreter to use. However, if we could get the package name of the activity which the user chose, we could check if the chosen app has the required permission via [PackageManager.checkPermission](http://developer.android.com/reference/android/content/pm/PackageManager.html#checkPermission%28java.lang.String, java.lang.String%29). The python App would then not use startActivity, instead it would use startActivityForResult. This way, there are only two activities and the whole process is much more intuitive.
  • It is too slow. I think, if we could change the startup method to the one I proposed in the point above, startup would be much faster.
  • The Python app needs a native library to set the environment variable. This is the only way I know right now to get the classpath to the JNI_OnLoad function of the application library. I would like the Python app to have no own native libraries, because they require the NDK when building the Python App with our PyToApk-Tool.

Thanks in advance for any help!


Python host: This app.
Python interpreter: Any app with a similar functionality like the Python host.
Python app: Our app, wrapped around someone's Python code, built by our PyToApk-Tool.

Abestanis added a commit that referenced this issue Jun 29, 2015
The python host provides the necessary libs to execute Python code.
These libs must be loaded by the Python app. To ensure that there is no
security issue the Python host must have the permission
"com.python.permission.PYTHONHOST".

It's a start, but I think that the starting process of the Python apps
is too complicated, not intuitive and takes too long. If anybody has
advice on that topic, please tell me at issue #9.
Abestanis added a commit to Abestanis/APython_PyApp that referenced this issue Jun 29, 2015
Finally!
It's not perfect, but it works.
If anyone has any advice on how to improve the current startup and
communication system, please head over to Abestanis/APython#9.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant