Add library to get vendor genfs version

As genfs_contexts depends on vendors, users should be able to read the
genfs versions of vendors to implement fallback mechanism for new
features. This adds a library reading the version.

Bug: 378805380
Test: boot and see logcat
Change-Id: I011e5f41f8765e55f069372b8350e89bca633624
diff --git a/compat/libgenfslabelsversion/Android.bp b/compat/libgenfslabelsversion/Android.bp
new file mode 100644
index 0000000..7f512a7
--- /dev/null
+++ b/compat/libgenfslabelsversion/Android.bp
@@ -0,0 +1,35 @@
+// Copyright (C) 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+package {
+    // See: http://go/android-license-faq
+    // A large-scale-change added 'default_applicable_licenses' to import
+    // all of the 'license_kinds' from "system_sepolicy_license"
+    // to get the below license kinds:
+    //   SPDX-license-identifier-Apache-2.0
+    default_applicable_licenses: ["system_sepolicy_license"],
+}
+
+rust_defaults {
+    name: "libgenfslabelsversion.default",
+    crate_name: "genfslabelsversion",
+    srcs: ["src/lib.rs"],
+    apex_available: ["//apex_available:platform"],
+}
+
+rust_ffi_static {
+    name: "libgenfslabelsversion.ffi",
+    defaults: ["libgenfslabelsversion.default"],
+    export_include_dirs: ["include"],
+}
diff --git a/compat/libgenfslabelsversion/include/genfslabelsversion.h b/compat/libgenfslabelsversion/include/genfslabelsversion.h
new file mode 100644
index 0000000..4c029c8
--- /dev/null
+++ b/compat/libgenfslabelsversion/include/genfslabelsversion.h
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2024 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+int get_genfs_labels_version();
+
+#ifdef __cplusplus
+}
+#endif
diff --git a/compat/libgenfslabelsversion/src/lib.rs b/compat/libgenfslabelsversion/src/lib.rs
new file mode 100644
index 0000000..21619e8
--- /dev/null
+++ b/compat/libgenfslabelsversion/src/lib.rs
@@ -0,0 +1,40 @@
+// Copyright 2024 The Android Open Source Project
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Client library to read genfs labels version of the vendor.
+
+use std::fs;
+
+const GENFS_LABELS_VERSION_TXT_PATH: &str = "/vendor/etc/selinux/genfs_labels_version.txt";
+const DEFAULT_GENFS_LABELS_VERSION: i32 = 202404;
+
+/// Get genfs labels version from the vendor partition.
+///
+/// This function reads the genfs labels version from the file
+/// `/vendor/etc/selinux/genfs_labels_version.txt`. If the file does not exist or
+/// cannot be parsed, it returns a default version of 202404.
+///
+/// # Returns
+///
+/// The genfs labels version as an integer.
+#[no_mangle]
+pub extern "C" fn get_genfs_labels_version() -> i32 {
+    match fs::read_to_string(GENFS_LABELS_VERSION_TXT_PATH) {
+        Ok(contents) => match contents.trim().parse::<i32>() {
+            Ok(version) => version,
+            Err(_) => DEFAULT_GENFS_LABELS_VERSION,
+        },
+        Err(_) => DEFAULT_GENFS_LABELS_VERSION,
+    }
+}