8000 Merge pull request #269 from alanjds/bootstrap-service · go-bears/python-for-android@05f3f3c · GitHub
[go: up one dir, main page]

Skip to content

Commit 05f3f3c

Browse files
committed
Merge pull request kivy#269 from alanjds/bootstrap-service
Bootstrap improvements, (including Service and BroadcastReceiver support)
2 parents 1e3334b + 1e1bcdf commit 05f3f3c

File tree

5 files changed

+108
-82
lines changed

5 files changed

+108
-82
lines changed

bootstrap/common/templates/AndroidManifest.tmpl.xml

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,19 @@
8282
{% endif %}
8383

8484
{% if service or args.launcher %}
85-
<service android:name="org.renpy.android.PythonService"
85+
<service android:name="{{ args.bootstrap.service_entrypoint }}"
8686
android:process=":PythonService"/>
8787
{% endif %}
8888

89+
{% if args.bootstrap.broadcastreceiver_entrypoint %}
90+
<receiver android:name="{{ args.bootstrap.broadcastreceiver_entrypoint }}" android:enabled="true" >
91+
<intent-filter>
92+
<action android:name ="{{ args.bootstrap.broadcastreceiver_action }}"/>
93+
<category android:name="android.intent.category.DEFAULT" />
94+
</intent-filter>
95+
</receiver>
96+
{% endif %}
97+
8998
{% if args.billing_pubkey %}
9099
<service android:name="org.renpy.android.billing.BillingService"
91100
android:process=":python" />

bootstrap/legacy/bootstrap.properties

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
11
bootstrap.entrypoint=org.renpy.android.PythonActivity
2+
bootstrap.service_entrypoint=org.renpy.android.PythonService

bootstrap/minimal/assets/_bootstrap.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -120,5 +120,8 @@ def load_module(self, fullname):
120120
# Step 4: bootstrap the application !
121121
#
122122

123+
main_module = sys.argv[1]
124+
print 'Bootstrapping module: "%s"' % main_module
125+
123126
import runpy
124-
runpy._run_module_as_main("main", False)
127+
runpy._run_module_as_main(main_module, False)

bootstrap/minimal/jni/main.c

Lines changed: 10 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,87 +1,8 @@
11
#include <jni.h>
2-
#include <errno.h>
3-
#include <android/log.h>
42
#include <android_native_app_glue.h>
53

6-
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "python", __VA_ARGS__))
7-
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "python", __VA_ARGS__))
4+
#include "utils.c"
85

9-
#define PY_SSIZE_T_CLEAN
10-
#include "Python.h"
11-
#ifndef Py_PYTHON_H
12-
#error Python headers needed to compile C extensions, please install development version of Python.
13-
#endif
14-
15-
struct android_app *g_state = NULL;
16-
17-
18-
static PyObject *androidembed_poll(PyObject *self, PyObject *args) {
19-
int indent;
20-
int events;
21-
struct android_poll_source *source;
22-
int timeout;
23-
24-
if (!PyArg_ParseTuple(args, "i", &timeout)) {
25-
return NULL;
26-
}
27-
28-
while ((indent = ALooper_pollAll(
29-
timeout, NULL, &events, (void **)&source)) >= 0) {
30-
31-
// Process this event
32-
if (source != NULL) {
33-
source->process(g_state, source);
34-
}
35-
36-
// Check if we are exiting.
37-
if (g_state->destroyRequested != 0) {
38-
Py_RETURN_FALSE;
39-
}
40-
}
41-
42-
Py_RETURN_TRUE;
43-
}
44-
45-
static PyObject *androidembed_log(PyObject *self, PyObject *args) {
46-
char *logstr = NULL;
47-
if (!PyArg_ParseTuple(args, "s", &logstr)) {
48-
return NULL;
49-
}
50-
__android_log_print(ANDROID_LOG_INFO, "python", "%s", logstr);
51-
Py_RETURN_NONE;
52-
}
53-
54-
static PyMethodDef AndroidEmbedMethods[] = {
55-
{"log", androidembed_log, METH_VARARGS, "Log on android platform"},
56-
{"poll", androidembed_poll, METH_VARARGS, "Poll the android events"},
57-
{NULL, NULL, 0, NULL}
58-
};
59-
60-
PyMODINIT_FUNC initandroidembed(void) {
61-
(void) Py_InitModule("androidembed", AndroidEmbedMethods);
62-
}
63-
64-
int asset_extract(AAssetManager *am, char *src_file, char *dst_file) {
65-
FILE *fhd = fopen(dst_file, "wb");
66-
if (fhd == NULL) {
67-
LOGW("Unable to open descriptor for %s (errno=%d:%s)",
68-
dst_file, errno, strerror(errno));
69-
return -1;
70-
}
71-
72-
AAsset *asset = AAssetManager_open(am, src_file, AASSET_MODE_BUFFER);
73-
if (asset == NULL) {
74-
LOGW("Unable to open asset %s", src_file);
75-
return -1;
76-
}
77-
78-
off_t l = AAsset_getLength(asset);
79-
fwrite(AAsset_getBuffer(asset),l, 1, fhd);
80-
fclose(fhd);
81-
AAsset_close(asset);
82-
83-
return 0;
84-
}
856

867
void android_main(struct android_app* state) {
878
app_dummy();
@@ -145,6 +66,15 @@ void android_main(struct android_app* state) {
14566
return;
14667
}
14768

69+
// pass a module name as argument: _bootstrap.py use it as the main module
70+
int argc;
71+
char * argv[2];
72+
argc = 2;
73+
argv[0] = "_bootstrap.py";
74+
argv[1] = "main";
75+
76+
PySys_SetArgv(argc, argv);
77+
14878
// run the python bootstrap
14979
LOGI("Run _bootstrap.py >>>");
15080
FILE *fhd = fopen(bootstrap_fn, "rb");

bootstrap/minimal/jni/utils.c

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
#include <errno.h>
2+
#include <android/log.h>
3+
4+
#define LOGI(...) ((void)__android_log_print(ANDROID_LOG_INFO, "python", __VA_ARGS__))
5+
#define LOGW(...) ((void)__android_log_print(ANDROID_LOG_WARN, "python", __VA_ARGS__))
6+
7+
#define PY_SSIZE_T_CLEAN
8+
#include "Python.h"
9+
#ifndef Py_PYTHON_H
10+
#error Python headers needed to compile C extensions, please install development version of Python.
11+
#endif
12+
13+
14+
struct android_app *g_state = NULL;
15+
16+
17+
static PyObject *androidembed_poll(PyObject *self, PyObject *args) {
18+
int indent;
19+
int events;
20+
struct android_poll_source *source;
21+
int timeout;
22+
23+
if (!PyArg_ParseTuple(args, "i", &timeout)) {
24+
return NULL;
25+
}
26+
27+
while ((indent = ALooper_pollAll(
28+
timeout, NULL, &events, (void **)&source)) >= 0) {
29+
30+
// Process this event
31+
if (source != NULL) {
32+
source->process(g_state, source);
33+
}
34+
35+
// Check if we are exiting.
36+
if (g_state->destroyRequested != 0) {
37+
Py_RETURN_FALSE;
38+
}
39+
}
40+
41+
Py_RETURN_TRUE;
42+
}
43+
44+
static PyObject *androidembed_log(PyObject *self, PyObject *args) {
45+
char *logstr = NULL;
46+
if (!PyArg_ParseTuple(args, "s", &logstr)) {
47+
return NULL;
48+
}
49+
__android_log_print(ANDROID_LOG_INFO, "python", "%s", logstr);
50+
Py_RETURN_NONE;
51+
}
52+
53+
static PyMethodDef AndroidEmbedMethods[] = {
54+
{"log", androidembed_log, METH_VARARGS, "Log on android platform"},
55+
{"poll", androidembed_poll, METH_VARARGS, "Poll the android events"},
56+
{NULL, NULL, 0, NULL}
57+
};
58+
59+
PyMODINIT_FUNC initandroidembed(void) {
60+
(void) Py_InitModule("androidembed", AndroidEmbedMethods);
61+
}
62+
63+
int asset_extract(AAssetManager *am, char *src_file, char *dst_file) {
64+
FILE *fhd = fopen(dst_file, "wb");
65+
if (fhd == NULL) {
66+
LOGW("Unable to open descriptor for %s (errno=%d:%s)",
67+
dst_file, errno, strerror(errno));
68+
return -1;
69+
}
70+
71+
AAsset *asset = AAssetManager_open(am, src_file, AASSET_MODE_BUFFER);
72+
if (asset == NULL) {
73+
LOGW("Unable to open asset %s", src_file);
74+
return -1;
75+
}
76+
77+
off_t l = AAsset_getLength(asset);
78+
fwrite(AAsset_getBuffer(asset),l, 1, fhd);
79+
fclose(fhd);
80+
AAsset_close(asset);
81+
82+
return 0;
83+
}

0 commit comments

Comments
 (0)
0