Update SdkLevel and sdk_level.h

Ideally, we would deprecate ApiLevelUtil classes maintained by tradefed
in favor of these utils. Since tradefed drops the prebuilts / sources
into old branches, we should avoid using fixed VERSION_CODES in code.

This makes the util behave similarly to BuildCompat which
understands pre-release builds as well. See https://cs.android.com/androidx/platform/frameworks/support/+/androidx-main:core/core/src/main/java/androidx/core/os/BuildCompat.java.

Bug: 187807290
Test: m
Change-Id: I4f1e34759218df62affbefbe1c6db8782152f033
diff --git a/PREUPLOAD.cfg b/PREUPLOAD.cfg
index fd78ff1..b53cbf1 100644
--- a/PREUPLOAD.cfg
+++ b/PREUPLOAD.cfg
@@ -1,3 +1,12 @@
+[Builtin Hooks]
+bpfmt = true
+clang_format = true
+commit_msg_changeid_field = true
+commit_msg_test_field = true
+
+[Builtin Hooks Options]
+clang_format = --commit ${PREUPLOAD_COMMIT} --style file --extensions c,h,cc,cpp
+
 [Hook Scripts]
 do_not_use_DO_NOT_MERGE = ${REPO_ROOT}/build/soong/scripts/check_do_not_merge.sh ${PREUPLOAD_COMMIT}
 check_java_paths = ${REPO_ROOT}/frameworks/libs/modules-utils/tools/check_java_paths.py
\ No newline at end of file
diff --git a/build/include/android-modules-utils/sdk_level.h b/build/include/android-modules-utils/sdk_level.h
index dfc46a3..6e24430 100644
--- a/build/include/android-modules-utils/sdk_level.h
+++ b/build/include/android-modules-utils/sdk_level.h
@@ -17,20 +17,30 @@
 #pragma once
 
 #include <android-base/properties.h>
+#include <android/api-level.h>
 
 namespace android {
 namespace modules {
 namespace sdklevel {
 
-// Return true iff the running Android SDK is at least "R".
-static inline bool IsAtLeastR() {
-  return android::base::GetIntProperty("ro.build.version.sdk", -1) >= 30;
+// Checks if the codename is a matching or higher version than the device's
+// codename.
+static bool IsAtLeastPreReleaseCodename(const std::string &codename) {
+  const std::string &deviceCodename =
+      android::base::GetProperty("ro.build.version.codename", "");
+  return "REL" != deviceCodename && deviceCodename.compare(codename) >= 0;
 }
 
-// Return true iff the running Android SDK is at least "S".
-static inline bool IsAtLeastS() {
-  return android::base::GetIntProperty("ro.build.version.sdk", -1) >= 31;
-}
+// Checks if the device is running on release version of Android R or newer.
+static inline bool IsAtLeastR() { return android_get_device_api_level() >= 30; }
+
+// Checks if the device is running on a pre-release version of Android S or a
+// release version of Android S or newer.
+static inline bool IsAtLeastS() { return android_get_device_api_level() >= 31; }
+
+// Checks if the device is running on a pre-release version of Android T or a
+// release version of Android T or newer.
+static inline bool IsAtLeastT() { return IsAtLeastPreReleaseCodename("T"); }
 
 } // namespace utils
 } // namespace modules
diff --git a/java/com/android/modules/utils/build/SdkLevel.java b/java/com/android/modules/utils/build/SdkLevel.java
index 8f329b2..49e02e0 100644
--- a/java/com/android/modules/utils/build/SdkLevel.java
+++ b/java/com/android/modules/utils/build/SdkLevel.java
@@ -16,28 +16,53 @@
 
 package com.android.modules.utils.build;
 
-import android.os.Build;
+import static android.os.Build.VERSION.CODENAME;
+import static android.os.Build.VERSION.SDK_INT;
 
 import androidx.annotation.ChecksSdkIntAtLeast;
+import androidx.annotation.NonNull;
 
 /**
- * Utility class to check SDK level.
+ * Utility class to check SDK level on a device.
  *
  * @hide
  */
-public class SdkLevel {
+public final class SdkLevel {
 
     private SdkLevel() {}
 
-    /** Return true iff the running Android SDK is at least "R". */
-    @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.R)
+    /** Checks if the device is running on release version of Android R or newer. */
+    @ChecksSdkIntAtLeast(api = 30 /* Build.VERSION_CODES.R */)
     public static boolean isAtLeastR() {
-        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.R;
+        return SDK_INT >= 30;
     }
 
-    /** Return true iff the running Android SDK is at least "S". */
-    @ChecksSdkIntAtLeast(api = Build.VERSION_CODES.S)
+    /**
+     * Checks if the device is running on a pre-release version of Android S or a release version of
+     * Android S or newer.
+     */
+    @ChecksSdkIntAtLeast(api = 31 /* Build.VERSION_CODES.S */, codename = "S")
     public static boolean isAtLeastS() {
-        return Build.VERSION.SDK_INT >= Build.VERSION_CODES.S;
+        return SDK_INT >= 31;
+    }
+
+    /**
+     * Checks if the device is running on a pre-release version of Android T or a release version of
+     * Android T or newer.
+     */
+    @ChecksSdkIntAtLeast(codename = "T")
+    public static boolean isAtLeastT() {
+        return isAtLeastPreReleaseCodename("T");
+    }
+
+    private static boolean isAtLeastPreReleaseCodename(@NonNull String codename) {
+        // Special case "REL", which means the build is not a pre-release build.
+        if ("REL".equals(CODENAME)) {
+            return false;
+        }
+
+        // Otherwise lexically compare them. Return true if the build codename is equal to or
+        // greater than the requested codename.
+        return CODENAME.compareTo(codename) >= 0;
     }
 }