diff --git a/Python/sysmodule.c b/Python/sysmodule.c
--- a/Python/sysmodule.c
+++ b/Python/sysmodule.c
@@ -22,16 +22,20 @@ Data members:
#include "osdefs.h"
#include
#ifdef MS_WINDOWS
#define WIN32_LEAN_AND_MEAN
#include
#endif /* MS_WINDOWS */
+#ifdef __ANDROID__
+#include
+#endif
+
#ifdef MS_COREDLL
extern void *PyWin_DLLhModule;
/* A string loaded from the DLL at startup: */
extern const char *PyWin_DLLVersionString;
#endif
#ifdef HAVE_LANGINFO_H
#include
@@ -1344,16 +1348,85 @@ sys_is_finalizing(PyObject* self, PyObje
{
return PyBool_FromLong(_Py_Finalizing != NULL);
}
PyDoc_STRVAR(is_finalizing_doc,
"is_finalizing()\n\
Return True if Python is exiting.");
+#ifdef __ANDROID__
+
+static PyObject *
+_Py_property_get(const char* name, char format)
+{
+ char buf[PROP_VALUE_MAX];
+ int len;
+
+ len = __system_property_get(name, buf);
+
+ if (len == 0)
+ {
+ Py_RETURN_NONE;
+ }
+
+ switch (format)
+ {
+ case 'u':
+ return PyUnicode_FromString(buf);
+ case 'l':
+ return PyLong_FromString(buf, NULL, 10);
+ default:
+ PyErr_Format(PyExc_ValueError,
+ "property value format '%c' unsupported", format);
+ return NULL;
+ }
+}
+
+static PyObject *
+sys_getandroidversion(PyObject* self)
+{
+ PyObject *version, *sdk, *codename, *incremental, *boardname, *abi, *ret;
+ version = _Py_property_get("ro.build.version.release", 'u');
+ sdk = _Py_property_get("ro.build.version.sdk", 'l');
+ codename = _Py_property_get("ro.build.version.codename", 'u');
+ incremental = _Py_property_get("ro.build.version.incremental", 'u');
+ boardname = _Py_property_get("ro.product.board", 'u');
+ abi = _Py_property_get("ro.product.cpu.abi", 'u');
+
+ ret = Py_BuildValue("(OO(OO)(OO))",
+ version, sdk, codename, incremental, boardname, abi);
+ Py_DECREF(version);
+ Py_DECREF(sdk);
+ Py_DECREF(codename);
+ Py_DECREF(incremental);
+ Py_DECREF(boardname);
+ Py_DECREF(abi);
+
+ return ret;
+}
+
+PyDoc_STRVAR(getandroidversion_doc,
+"getandroidversion()\n\
+\n\
+Attempt to get the Android version information.\n\
+\n\
+The function checks Android system properties to retrieve info.\n\
+\n\
+Returns a (version, sdk, versioninfo, hardwareinfo) tuple with\n\
+versioninfo being a (codename, incremental) tuple and hardwareinfo\n\
+being a (boardname, abi) tuple.\n\
+\n\
+Values which cannot be determined are set to the defaults\n\
+given as parameters (which sdk defaults to 0 and others default to '').\n\
+"
+);
+#endif
+
+
static PyMethodDef sys_methods[] = {
/* Might as well keep this in alphabetic order */
{"callstats", (PyCFunction)PyEval_GetCallStats, METH_NOARGS,
callstats_doc},
{"_clear_type_cache", sys_clear_type_cache, METH_NOARGS,
sys_clear_type_cache__doc__},
{"_current_frames", sys_current_frames, METH_NOARGS,
@@ -1429,16 +1502,20 @@ static PyMethodDef sys_methods[] = {
{"set_coroutine_wrapper", sys_set_coroutine_wrapper, METH_O,
set_coroutine_wrapper_doc},
{"get_coroutine_wrapper", sys_get_coroutine_wrapper, METH_NOARGS,
get_coroutine_wrapper_doc},
{"set_asyncgen_hooks", (PyCFunction)sys_set_asyncgen_hooks,
METH_VARARGS | METH_KEYWORDS, set_asyncgen_hooks_doc},
{"get_asyncgen_hooks", sys_get_asyncgen_hooks, METH_NOARGS,
get_asyncgen_hooks_doc},
+#ifdef __ANDROID__
+ {"getandroidversion", sys_getandroidversion, METH_NOARGS,
+ getandroidversion_doc},
+#endif
{NULL, NULL} /* sentinel */
};
static PyObject *
list_builtin_module_names(void)
{
PyObject *list = PyList_New(0);
int i;