Implement __isOSVersionAtLeast for Android
authorStephen Hines <srhines@google.com>
Tue, 15 Sep 2020 19:50:42 +0000 (12:50 -0700)
committerStephen Hines <srhines@google.com>
Tue, 15 Sep 2020 19:54:06 +0000 (12:54 -0700)
Add the implementation of __isOSVersionAtLeast for Android. Currently,
only the major version is checked against the API level of the platform
which is an integer. The API level is retrieved by reading the system
property ro.build.version.sdk (and optionally ro.build.version.codename
to see if the platform is released or not).

Patch by jiyong@google.com

Bug: 150860940
Bug: 134795810
Test: m

Reviewed By: srhines

Differential Revision: https://reviews.llvm.org/D86596

compiler-rt/lib/builtins/os_version_check.c

index 3794b97..fbc68f5 100644 (file)
@@ -216,6 +216,44 @@ int32_t __isOSVersionAtLeast(int32_t Major, int32_t Minor, int32_t Subminor) {
   return Subminor <= GlobalSubminor;
 }
 
+#elif __ANDROID__
+
+#include <pthread.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/system_properties.h>
+
+static int SdkVersion;
+static int IsPreRelease;
+
+static void readSystemProperties(void) {
+  char buf[PROP_VALUE_MAX];
+
+  if (__system_property_get("ro.build.version.sdk", buf) == 0) {
+    // When the system property doesn't exist, defaults to future API level.
+    SdkVersion = __ANDROID_API_FUTURE__;
+  } else {
+    SdkVersion = atoi(buf);
+  }
+
+  if (__system_property_get("ro.build.version.codename", buf) == 0) {
+    IsPreRelease = 1;
+  } else {
+    IsPreRelease = strcmp(buf, "REL") != 0;
+  }
+  return;
+}
+
+int32_t __isOSVersionAtLeast(int32_t Major, int32_t Minor, int32_t Subminor) {
+  (int32_t) Minor;
+  (int32_t) Subminor;
+  static pthread_once_t once = PTHREAD_ONCE_INIT;
+  pthread_once(&once, readSystemProperties);
+
+  return SdkVersion >= Major ||
+         (IsPreRelease && Major == __ANDROID_API_FUTURE__);
+}
+
 #else
 
 // Silence an empty translation unit warning.