Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 41 additions & 29 deletions pythonforandroid/bootstraps/sdl2/build/jni/src/start.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@
#include "SDL_opengles2.h"

#define ENTRYPOINT_MAXLEN 128
#define LOG(x) __android_log_write(ANDROID_LOG_INFO, "python", (x))
#define LOG(n, x) __android_log_write(ANDROID_LOG_INFO, (n), (x))
#define LOGP(x) LOG("python", (x))

static PyObject *androidembed_log(PyObject *self, PyObject *args) {
char *logstr = NULL;
if (!PyArg_ParseTuple(args, "s", &logstr)) {
return NULL;
}
LOG(logstr);
LOG(getenv("PYTHON_NAME"), logstr);
Py_RETURN_NONE;
}

Expand Down Expand Up @@ -70,20 +71,27 @@ int main(int argc, char *argv[]) {

char *env_argument = NULL;
char *env_entrypoint = NULL;
char *env_logname = NULL;
char entrypoint[ENTRYPOINT_MAXLEN];
int ret = 0;
FILE *fd;

/* AND: Several filepaths are hardcoded here, these must be made
configurable */
/* AND: P4A uses env vars...not sure what's best */
LOG("Initialize Python for Android");
LOGP("Initialize Python for Android");
env_argument = getenv("ANDROID_ARGUMENT");
setenv("ANDROID_APP_PATH", env_argument, 1);
env_entrypoint = getenv("ANDROID_ENTRYPOINT");
env_logname = getenv("PYTHON_NAME");

if (env_logname == NULL) {
env_logname = "python";
setenv("PYTHON_NAME", "python", 1);
}

LOG("Changing directory to the one provided by ANDROID_ARGUMENT");
LOG(env_argument);
LOGP("Changing directory to the one provided by ANDROID_ARGUMENT");
LOGP(env_argument);
chdir(env_argument);

Py_SetProgramName(L"android_python");
Expand All @@ -94,31 +102,31 @@ int main(int argc, char *argv[]) {
PyImport_AppendInittab("androidembed", initandroidembed);
#endif

LOG("Preparing to initialize python");
LOGP("Preparing to initialize python");

if (dir_exists("crystax_python/")) {
LOG("crystax_python exists");
LOGP("crystax_python exists");
char paths[256];
snprintf(paths, 256,
"%s/crystax_python/stdlib.zip:%s/crystax_python/modules",
env_argument, env_argument);
/* snprintf(paths, 256, "%s/stdlib.zip:%s/modules", env_argument,
* env_argument); */
LOG("calculated paths to be...");
LOG(paths);
LOGP("calculated paths to be...");
LOGP(paths);

#if PY_MAJOR_VERSION >= 3
wchar_t *wchar_paths = Py_DecodeLocale(paths, NULL);
Py_SetPath(wchar_paths);
#else
char *wchar_paths = paths;
LOG("Can't Py_SetPath in python2, so crystax python2 doesn't work yet");
LOGP("Can't Py_SetPath in python2, so crystax python2 doesn't work yet");
exit(1);
#endif

LOG("set wchar paths...");
LOGP("set wchar paths...");
} else {
LOG("crystax_python does not exist");
LOGP("crystax_python does not exist");
}

Py_Initialize();
Expand All @@ -127,11 +135,11 @@ int main(int argc, char *argv[]) {
PySys_SetArgv(argc, argv);
#endif

LOG("Initialized python");
LOGP("Initialized python");

/* ensure threads will work.
*/
LOG("AND: Init threads");
LOGP("AND: Init threads");
PyEval_InitThreads();

#if PY_MAJOR_VERSION < 3
Expand All @@ -147,7 +155,7 @@ int main(int argc, char *argv[]) {
PyRun_SimpleString("import sys, posix\n");
if (dir_exists("lib")) {
/* If we built our own python, set up the paths correctly */
LOG("Setting up python from ANDROID_PRIVATE");
LOGP("Setting up python from ANDROID_PRIVATE");
PyRun_SimpleString("private = posix.environ['ANDROID_PRIVATE']\n"
"argument = posix.environ['ANDROID_ARGUMENT']\n"
"sys.path[:] = [ \n"
Expand Down Expand Up @@ -194,31 +202,31 @@ int main(int argc, char *argv[]) {
PyRun_SimpleString("import site; print site.getsitepackages()\n");
#endif

LOG("AND: Ran string");
LOGP("AND: Ran string");

/* run it !
*/
LOG("Run user program, change dir and execute entrypoint");
LOGP("Run user program, change dir and execute entrypoint");

/* Get the entrypoint, search the .pyo then .py
*/
char *dot = strrchr(env_entrypoint, '.');
if (dot <= 0) {
LOG("Invalid entrypoint, abort.");
LOGP("Invalid entrypoint, abort.");
return -1;
}
if (strlen(env_entrypoint) > ENTRYPOINT_MAXLEN - 2) {
LOG("Entrypoint path is too long, try increasing ENTRYPOINT_MAXLEN.");
LOGP("Entrypoint path is too long, try increasing ENTRYPOINT_MAXLEN.");
return -1;
}
if (!strcmp(dot, ".pyo")) {
if (!file_exists(env_entrypoint)) {
/* fallback on .py */
strcpy(entrypoint, env_entrypoint);
entrypoint[strlen(env_entrypoint) - 1] = '\0';
LOG(entrypoint);
LOGP(entrypoint);
if (!file_exists(entrypoint)) {
LOG("Entrypoint not found (.pyo, fallback on .py), abort");
LOGP("Entrypoint not found (.pyo, fallback on .py), abort");
return -1;
}
} else {
Expand All @@ -232,21 +240,21 @@ int main(int argc, char *argv[]) {
if (!file_exists(entrypoint)) {
/* fallback on pure python version */
if (!file_exists(env_entrypoint)) {
LOG("Entrypoint not found (.py), abort.");
LOGP("Entrypoint not found (.py), abort.");
return -1;
}
strcpy(entrypoint, env_entrypoint);
}
} else {
LOG("Entrypoint have an invalid extension (must be .py or .pyo), abort.");
LOGP("Entrypoint have an invalid extension (must be .py or .pyo), abort.");
return -1;
}
// LOG("Entrypoint is:");
// LOG(entrypoint);
// LOGP("Entrypoint is:");
// LOGP(entrypoint);
fd = fopen(entrypoint, "r");
if (fd == NULL) {
LOG("Open the entrypoint failed");
LOG(entrypoint);
LOGP("Open the entrypoint failed");
LOGP(entrypoint);
return -1;
}

Expand All @@ -268,21 +276,24 @@ int main(int argc, char *argv[]) {
Py_Finalize();
fclose(fd);

LOG("Python for android ended.");
LOGP("Python for android ended.");
return ret;
}

JNIEXPORT void JNICALL Java_org_kivy_android_PythonService_nativeStart(
JNIEnv *env, jobject thiz, jstring j_android_private,
jstring j_android_argument, jstring j_service_entrypoint,
jstring j_python_home, jstring j_python_path, jstring j_arg) {
jstring j_python_name, jstring j_python_home, jstring j_python_path,
jstring j_arg) {
jboolean iscopy;
const char *android_private =
(*env)->GetStringUTFChars(env, j_android_private, &iscopy);
const char *android_argument =
(*env)->GetStringUTFChars(env, j_android_argument, &iscopy);
const char *service_entrypoint =
(*env)->GetStringUTFChars(env, j_service_entrypoint, &iscopy);
const char *python_name =
(*env)->GetStringUTFChars(env, j_python_name, &iscopy);
const char *python_home =
(*env)->GetStringUTFChars(env, j_python_home, &iscopy);
const char *python_path =
Expand All @@ -293,6 +304,7 @@ JNIEXPORT void JNICALL Java_org_kivy_android_PythonService_nativeStart(
setenv("ANDROID_ARGUMENT", android_argument, 1);
setenv("ANDROID_ENTRYPOINT", service_entrypoint, 1);
setenv("PYTHONOPTIMIZE", "2", 1);
setenv("PYTHON_NAME", python_name, 1);
setenv("PYTHONHOME", python_home, 1);
setenv("PYTHONPATH", python_path, 1);
setenv("PYTHON_SERVICE_ARGUMENT", arg, 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class PythonService extends Service implements Runnable {
// Python environment variables
private String androidPrivate;
private String androidArgument;
private String pythonName;
private String pythonHome;
private String pythonPath;
private String serviceEntrypoint;
Expand Down Expand Up @@ -55,6 +56,7 @@ public int onStartCommand(Intent intent, int flags, int startId) {
androidPrivate = extras.getString("androidPrivate");
androidArgument = extras.getString("androidArgument");
serviceEntrypoint = extras.getString("serviceEntrypoint");
pythonName = extras.getString("pythonName");
pythonHome = extras.getString("pythonHome");
pythonPath = extras.getString("pythonPath");
pythonServiceArgument = extras.getString("pythonServiceArgument");
Expand Down Expand Up @@ -93,15 +95,15 @@ public void run(){
this.mService = this;
nativeStart(
androidPrivate, androidArgument,
serviceEntrypoint,
serviceEntrypoint, pythonName,
pythonHome, pythonPath,
pythonServiceArgument);
}

// Native part
public static native void nativeStart(
String androidPrivate, String androidArgument,
String serviceEntrypoint,
String serviceEntrypoint, String pythonName,
String pythonHome, String pythonPath,
String pythonServiceArgument);
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ static public void start(Context ctx, String pythonServiceArgument) {
intent.putExtra("androidPrivate", argument);
intent.putExtra("androidArgument", argument);
intent.putExtra("serviceEntrypoint", "{{ entrypoint }}");
intent.putExtra("pythonName", "{{ name }}");
intent.putExtra("pythonHome", argument);
intent.putExtra("pythonPath", argument + ":" + argument + "/lib");
intent.putExtra("pythonServiceArgument", pythonServiceArgument);
Expand Down