summaryrefslogtreecommitdiffstats
path: root/Lib/platform.py
diff options
context:
space:
mode:
authorMalcolm Smith <smith@chaquo.com>2024-03-27 16:53:27 (GMT)
committerGitHub <noreply@github.com>2024-03-27 16:53:27 (GMT)
commit74c8568d07719529b874897598d8b3bc25ff0434 (patch)
tree43226bc05462471e4c05c7a160335aa3e752d2ea /Lib/platform.py
parentce00de4c8cd39816f992e749c1074487d93abe9d (diff)
downloadcpython-74c8568d07719529b874897598d8b3bc25ff0434.zip
cpython-74c8568d07719529b874897598d8b3bc25ff0434.tar.gz
cpython-74c8568d07719529b874897598d8b3bc25ff0434.tar.bz2
gh-71042: Add `platform.android_ver` (#116674)
Diffstat (limited to 'Lib/platform.py')
-rwxr-xr-xLib/platform.py46
1 files changed, 46 insertions, 0 deletions
diff --git a/Lib/platform.py b/Lib/platform.py
index 2756f29..df1d987 100755
--- a/Lib/platform.py
+++ b/Lib/platform.py
@@ -542,6 +542,47 @@ def java_ver(release='', vendor='', vminfo=('', '', ''), osinfo=('', '', '')):
return release, vendor, vminfo, osinfo
+
+AndroidVer = collections.namedtuple(
+ "AndroidVer", "release api_level manufacturer model device is_emulator")
+
+def android_ver(release="", api_level=0, manufacturer="", model="", device="",
+ is_emulator=False):
+ if sys.platform == "android":
+ try:
+ from ctypes import CDLL, c_char_p, create_string_buffer
+ except ImportError:
+ pass
+ else:
+ # An NDK developer confirmed that this is an officially-supported
+ # API (https://stackoverflow.com/a/28416743). Use `getattr` to avoid
+ # private name mangling.
+ system_property_get = getattr(CDLL("libc.so"), "__system_property_get")
+ system_property_get.argtypes = (c_char_p, c_char_p)
+
+ def getprop(name, default):
+ # https://android.googlesource.com/platform/bionic/+/refs/tags/android-5.0.0_r1/libc/include/sys/system_properties.h#39
+ PROP_VALUE_MAX = 92
+ buffer = create_string_buffer(PROP_VALUE_MAX)
+ length = system_property_get(name.encode("UTF-8"), buffer)
+ if length == 0:
+ # This API doesn’t distinguish between an empty property and
+ # a missing one.
+ return default
+ else:
+ return buffer.value.decode("UTF-8", "backslashreplace")
+
+ release = getprop("ro.build.version.release", release)
+ api_level = int(getprop("ro.build.version.sdk", api_level))
+ manufacturer = getprop("ro.product.manufacturer", manufacturer)
+ model = getprop("ro.product.model", model)
+ device = getprop("ro.product.device", device)
+ is_emulator = getprop("ro.kernel.qemu", "0") == "1"
+
+ return AndroidVer(
+ release, api_level, manufacturer, model, device, is_emulator)
+
+
### System name aliasing
def system_alias(system, release, version):
@@ -972,6 +1013,11 @@ def uname():
system = 'Windows'
release = 'Vista'
+ # On Android, return the name and version of the OS rather than the kernel.
+ if sys.platform == 'android':
+ system = 'Android'
+ release = android_ver().release
+
vals = system, node, release, version, machine
# Replace 'unknown' values with the more portable ''
_uname_cache = uname_result(*map(_unknown_as_blank, vals))