### Get SELinux Context for System Property Source: https://context7.com/topjohnwu/system_properties/llms.txt Retrieves the SELinux context string for a given system property. Returns nullptr on failure. Used for enforcing access controls. ```c #include #include int main() { const char* ctx = __system_property_get_context("ro.build.version.sdk"); if (ctx) { printf("SELinux context: %s\n", ctx); // Output: SELinux context: u:object_r:build_prop:s0 } else { fprintf(stderr, "Could not determine context\n"); } return 0; } ``` -------------------------------- ### Read Global Property Area Serial Source: https://context7.com/topjohnwu/system_properties/llms.txt Use `__system_property_area_serial()` to get a serial number that increments when any property changes. This allows for efficient checks to see if properties have been modified. ```c #include #include int main() { uint32_t serial_before = __system_property_area_serial(); printf("Serial before: %u\n", serial_before); // ... some time passes, properties may be updated by other processes ... uint32_t serial_after = __system_property_area_serial(); if (serial_after != serial_before) { printf("At least one property changed (serial %u -> %u)\n", serial_before, serial_after); } else { printf("No properties changed\n"); } return 0; } ``` -------------------------------- ### Get System Property Serial Number Source: https://context7.com/topjohnwu/system_properties/llms.txt Use `__system_property_serial` to retrieve the current serial number of a property. This is useful for change detection, as the serial increments on update. Prefer `__system_property_read_callback` for atomic reads. ```c++ #include #include int main() { const prop_info* pi = __system_property_find("debug.myapp.config"); if (!pi) return 1; uint32_t last_serial = __system_property_serial(pi); printf("Initial serial: %u\n", last_serial); // Poll for changes (in production prefer __system_property_wait) while (true) { uint32_t current_serial = __system_property_serial(pi); if (current_serial != last_serial) { printf("Property changed! new serial=%u\n", current_serial); last_serial = current_serial; break; } } return 0; } ``` -------------------------------- ### Initialize System Properties for Writing (init only) Source: https://context7.com/topjohnwu/system_properties/llms.txt The `__system_property_area_init()` function sets up the writable shared-memory property area. This function is intended only for the `init` process or equivalent, as it requires write access to `/dev/__properties__/`. ```c #include #include // Called once during early boot by init to create the writable property area int setup_property_service() { int ret = __system_property_area_init(); if (ret != 0) { fprintf(stderr, "__system_property_area_init failed\n"); return -1; } // Now init can add the first properties const char* name = "ro.build.type"; const char* value = "user"; int add_ret = __system_property_add(name, strlen(name), value, strlen(value)); if (add_ret != 0) { fprintf(stderr, "Failed to add property\n"); } return add_ret; } ``` -------------------------------- ### __system_properties_init Source: https://context7.com/topjohnwu/system_properties/llms.txt Initializes the system properties area for reading. This function is typically called automatically during libc initialization and should not be called directly by user code. ```APIDOC ## __system_properties_init — Initialize the property area for reading ### Description Called automatically during `libc` initialization. User code should never need to call this directly. Initializes the system properties area in read-only mode by mapping `/dev/__properties__/`. Returns `0` on success, `-1` on failure. ### Usage Example ```c #include #include // Only needed in environments where libc initialization is bypassed // (e.g., custom bootstrapping or unit tests that manage the property area directly). int custom_bootstrap() { int ret = __system_properties_init(); if (ret != 0) { fprintf(stderr, "__system_properties_init failed\n"); return ret; } // Now safe to call __system_property_get, __system_property_find, etc. char value[PROP_VALUE_MAX]; __system_property_get("ro.build.version.sdk", value); printf("SDK: %s\n", value); return 0; } ``` ``` -------------------------------- ### Find and Read Property Info using __system_property_find and __system_property_read_callback Source: https://context7.com/topjohnwu/system_properties/llms.txt Cache a property lookup result using `__system_property_find` for efficiency, especially in loops. Then, use `__system_property_read_callback` with the obtained handle to read the property's name, value, and serial number. ```c #include #include int main() { // Cache the lookup result — expensive operation, do once const prop_info* pi = __system_property_find("ro.product.model"); if (pi == nullptr) { fprintf(stderr, "Property not found\n"); return 1; } // Use the cached handle for subsequent reads via read_callback __system_property_read_callback(pi, [](void* cookie, const char* name, const char* value, uint32_t serial) { printf("name=%s value=%s serial=%u\n", name, value, serial); // Output: name=ro.product.model value=Pixel 8 serial=2 }, nullptr /* cookie */); return 0; } ``` -------------------------------- ### Iterate Over All System Properties Source: https://context7.com/topjohnwu/system_properties/llms.txt Use `__system_property_foreach` to invoke a callback for every property in the system. This is useful for dumping all properties or performing bulk analysis. Returns `0` on success, `-1` on failure. ```c++ #include #include #include struct ForeachCookie { int count; const char* prefix; }; static void print_prop(const prop_info* pi, void* cookie) { auto* ctx = static_cast(cookie); // Use read_callback to get name + value atomically __system_property_read_callback(pi, [](void* c, const char* name, const char* value, uint32_t /*serial*/) { auto* ctx2 = static_cast(c); if (strncmp(name, ctx2->prefix, strlen(ctx2->prefix)) == 0) { printf(" [%s] = [%s]\n", name, value); ctx2->count++; } }, ctx); } int main() { ForeachCookie ctx = { .count = 0, .prefix = "ro.build." }; int ret = __system_property_foreach(print_prop, &ctx); // Output (example): // [ro.build.version.sdk] = [35] // [ro.build.version.release] = [15] // [ro.build.id] = [AP4A.250405.002] // ... printf("Found %d properties with prefix 'ro.build.'\n", ctx.count); // ret == 0 return ret; } ``` -------------------------------- ### Initialize System Properties for Reading Source: https://context7.com/topjohnwu/system_properties/llms.txt The `__system_properties_init()` function initializes the system properties area in read-only mode. It is typically called automatically during `libc` initialization and should not be called directly by user code unless bypassing standard initialization. ```c #include #include // Only needed in environments where libc initialization is bypassed // (e.g., custom bootstrapping or unit tests that manage the property area directly). int custom_bootstrap() { int ret = __system_properties_init(); if (ret != 0) { fprintf(stderr, "__system_properties_init failed\n"); return ret; } // Now safe to call __system_property_get, __system_property_find, etc. char value[PROP_VALUE_MAX]; __system_property_get("ro.build.version.sdk", value); printf("SDK: %s\n", value); return 0; } ``` -------------------------------- ### __system_property_foreach Source: https://context7.com/topjohnwu/system_properties/llms.txt Iterates over all system properties and invokes a callback function for each property. This is useful for tasks such as dumping all properties or performing bulk analysis. Returns 0 on success and -1 on failure. ```APIDOC ## __system_property_foreach ### Description Invokes a callback for every property in the system property area. Useful for dumping all properties or performing bulk analysis. Returns `0` on success, `-1` on failure. ### Parameters - `callback` (void (*)(const prop_info*, void*)): A callback function to be invoked for each property. It receives a pointer to the `prop_info` structure and a user-defined cookie. - `cookie` (void*): A user-defined pointer passed to the callback function. ### Return Value - `int`: `0` on success, `-1` on failure. ### Example ```c #include #include #include struct ForeachCookie { int count; const char* prefix; }; static void print_prop(const prop_info* pi, void* cookie) { auto* ctx = static_cast(cookie); // Use read_callback to get name + value atomically __system_property_read_callback(pi, [](void* c, const char* name, const char* value, uint32_t /*serial*/) { auto* ctx2 = static_cast(c); if (strncmp(name, ctx2->prefix, strlen(ctx2->prefix)) == 0) { printf(" [%s] = [%s]\n", name, value); ctx2->count++; } }, ctx); } int main() { ForeachCookie ctx = { .count = 0, .prefix = "ro.build." }; int ret = __system_property_foreach(print_prop, &ctx); // Output (example): // [ro.build.version.sdk] = [35] // [ro.build.version.release] = [15] // [ro.build.id] = [AP4A.250405.002] // ... printf("Found %d properties with prefix 'ro.build.'\n", ctx.count); // ret == 0 return ret; } ``` ``` -------------------------------- ### __system_property_find — Look up a `prop_info` handle Source: https://context7.com/topjohnwu/system_properties/llms.txt Returns an opaque `const prop_info*` handle for the named property, or `nullptr` if not found. The returned pointer is stable for the lifetime of the property area. ```APIDOC ## __system_property_find ### Description Returns an opaque `const prop_info*` handle for the named property, or `nullptr` if not found. The returned pointer is stable for the lifetime of the property area (it is never freed). Cache this handle to avoid repeated lookup overhead when reading a property in a loop. ### Method `__system_property_find(const char *name)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```c #include #include int main() { // Cache the lookup result — expensive operation, do once const prop_info* pi = __system_property_find("ro.product.model"); if (pi == nullptr) { fprintf(stderr, "Property not found\n"); return 1; } // Use the cached handle for subsequent reads via read_callback __system_property_read_callback(pi, [](void* cookie, const char* name, const char* value, uint32_t serial) { printf("name=%s value=%s serial=%u\n", name, value, serial); // Output: name=ro.product.model value=Pixel 8 serial=2 }, nullptr /* cookie */); return 0; } ``` ### Response #### Success Response - **return value** (`const prop_info*`) - An opaque handle to the property information, or `nullptr` if the property is not found. #### Response Example None explicitly provided, but the example shows usage with `__system_property_read_callback`. ``` -------------------------------- ### __system_property_area_init Source: https://context7.com/topjohnwu/system_properties/llms.txt Initializes the property area for writing. This function is intended for the `init` process only and sets up the writable shared-memory property area. ```APIDOC ## __system_property_area_init — Initialize the property area for writing (init only) ### Description Sets up the writable shared-memory property area. Only callable by the process that owns `/dev/__properties__/` with write access — in practice, the `init` process. Returns `0` on success, `-1` on failure. Normal application code must never call this. ### Usage Example ```c #include #include // Called once during early boot by init to create the writable property area int setup_property_service() { int ret = __system_property_area_init(); if (ret != 0) { fprintf(stderr, "__system_property_area_init failed\n"); return -1; } // Now init can add the first properties const char* name = "ro.build.type"; const char* value = "user"; int add_ret = __system_property_add(name, strlen(name), value, strlen(value)); if (add_ret != 0) { fprintf(stderr, "Failed to add property\n"); } return add_ret; } ``` ``` -------------------------------- ### __system_property_get_context Source: https://context7.com/topjohnwu/system_properties/llms.txt Retrieves the SELinux context string associated with a given system property. This is crucial for the property service to enforce access controls. If the property does not exist or an error occurs, it returns nullptr. ```APIDOC ## __system_property_get_context — Get the SELinux context for a property ### Description Returns the SELinux context string associated with the named property (e.g., `"u:object_r:build_prop:s0"`), or `nullptr` on failure. Used by the property service to enforce access controls. ### Method (Internal C function, not directly mapped to HTTP) ### Parameters - **name** (`const char*`) - Required - The name of the property to query. ### Return Value - **const char*** - A pointer to the SELinux context string, or `nullptr` if the context cannot be retrieved. ``` -------------------------------- ### __system_property_set — Write a system property Source: https://context7.com/topjohnwu/system_properties/llms.txt Sets or creates a system property. For protocol version 2, `ro.*` properties may exceed `PROP_VALUE_MAX`; all other properties must be under 92 bytes. Returns 0 on success, -1 on failure. ```APIDOC ## __system_property_set ### Description Sets or creates a system property by sending a request to the property service daemon over a Unix domain socket. For protocol version 2, `ro.*` properties may exceed `PROP_VALUE_MAX`; all other properties must stay under 92 bytes. Returns `0` on success, `-1` on failure. ### Method `__system_property_set(const char *name, const char *value)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```c #include #include int main() { // Set a mutable property (value must be < PROP_VALUE_MAX = 92 bytes) int ret = __system_property_set("debug.myapp.loglevel", "verbose"); if (ret != 0) { fprintf(stderr, "Failed to set property\n"); return 1; } // Attempt to set with a NULL value — treated as empty string "" ret = __system_property_set("debug.myapp.loglevel", NULL); // ret == 0; property is now "" // Attempt to set a value that is too long for a non-ro property char long_value[200]; memset(long_value, 'x', sizeof(long_value) - 1); long_value[199] = '\0'; ret = __system_property_set("debug.myapp.bigval", long_value); // ret == -1 because strlen >= PROP_VALUE_MAX and name doesn't start with "ro." return 0; } ``` ### Response #### Success Response (0) Indicates the property was successfully set or created. #### Error Response (-1) Indicates failure to set the property (e.g., value too long for non-`ro.` properties). #### Response Example None explicitly provided, but return value indicates success (0) or failure (-1). ``` -------------------------------- ### Look up context and type for a property name Source: https://context7.com/topjohnwu/system_properties/llms.txt Parses the serialized trie at /dev/__properties__/property_info to resolve SELinux context and type label for a property name. Used internally by the property service to enforce per-property access policies. Requires including property_info_parser/property_info_parser.h. ```cpp #include #include using android::properties::PropertyInfoAreaFile; int main() { PropertyInfoAreaFile info_file; if (!info_file.LoadDefaultPath()) { fprintf(stderr, "Failed to load property info area\n"); return 1; } const char* context = nullptr; const char* type = nullptr; info_file->GetPropertyInfo("ro.build.version.sdk", &context, &type); printf("Property: ro.build.version.sdk\n"); printf(" context: %s\n", context ? context : "(none)"); printf(" type: %s\n", type ? type : "(none)"); // Output: // Property: ro.build.version.sdk // context: u:object_r:build_prop:s0 // type: (none) // Iterate over all contexts printf("Total contexts: %u\n", info_file->num_contexts()); for (uint32_t i = 0; i < info_file->num_contexts(); i++) { printf(" [%u] %s\n", i, info_file->context(i)); } return 0; } ``` -------------------------------- ### Set a System Property using __system_property_set Source: https://context7.com/topjohnwu/system_properties/llms.txt Use `__system_property_set` to write or update a system property. Ensure mutable property values do not exceed `PROP_VALUE_MAX` (92 bytes). Passing `NULL` for the value effectively sets an empty string. ```c #include #include int main() { // Set a mutable property (value must be < PROP_VALUE_MAX = 92 bytes) int ret = __system_property_set("debug.myapp.loglevel", "verbose"); if (ret != 0) { fprintf(stderr, "Failed to set property\n"); return 1; } // Attempt to set with a NULL value — treated as empty string "" ret = __system_property_set("debug.myapp.loglevel", NULL); // ret == 0; property is now "" // Attempt to set a value that is too long for a non-ro property char long_value[200]; memset(long_value, 'x', sizeof(long_value) - 1); long_value[199] = '\0'; ret = __system_property_set("debug.myapp.bigval", long_value); // ret == -1 because strlen >= PROP_VALUE_MAX and name doesn't start with "ro." return 0; } ``` -------------------------------- ### __system_property_update Source: https://context7.com/topjohnwu/system_properties/llms.txt Updates the value of an existing system property. This function is intended for use by the init process only and requires a valid prop_info* obtained from __system_property_find. The new value must be less than PROP_VALUE_MAX (92 bytes). It utilizes futex notifications to wake any threads waiting on property changes. ```APIDOC ## __system_property_update — Update an existing property value (init only) ### Description Updates the value of an existing property given a `prop_info*` previously obtained from `__system_property_find`. Can only be called by the init process. Value must be less than `PROP_VALUE_MAX` (92 bytes). Uses futex notifications to wake any threads blocked in `__system_property_wait`. Returns `0` on success, `-1` on failure. ### Method (Internal C function, not directly mapped to HTTP) ### Parameters - **pi** (`prop_info*`) - Required - Pointer to the property information obtained from `__system_property_find`. - **new_value** (`const char*`) - Required - The new value for the property. - **len** (`unsigned int`) - Required - The length of the `new_value`. ### Return Value - **0** on success. - **-1** on failure. ``` -------------------------------- ### Reload System Properties from Disk (Zygote only, API 35+) Source: https://context7.com/topjohnwu/system_properties/llms.txt Reloads system properties from disk. Intended for the Zygote process and must be called from the main thread. Pointers obtained from `__system_property_find` may become invalid after this call. ```c #include #include // Called by Zygote after forking to pick up new properties int zygote_reinitialize_properties() { // Must be called on the main thread only int ret = __system_properties_zygote_reload(); if (ret != 0) { fprintf(stderr, "Property reload failed\n"); return ret; } // All previously cached prop_info* pointers are now potentially invalid. // Re-look up any cached handles: const prop_info* pi = __system_property_find("ro.product.model"); if (pi) { char value[PROP_VALUE_MAX]; __system_property_get("ro.product.model", value); printf("Model after reload: %s\n", value); } return 0; } ``` -------------------------------- ### Add New Property (init only) Source: https://context7.com/topjohnwu/system_properties/llms.txt Use `__system_property_add()` to add a new property to the writable area. This function is restricted to processes with write access, typically `init`. It returns an error if the area is full or if name/value lengths are invalid. ```c #include #include #include // Called by init during early boot int add_build_properties() { struct { const char* name; const char* value; } props[] = { { "ro.product.manufacturer", "Google" }, { "ro.product.model", "Pixel 8" }, { "ro.build.version.sdk", "35" }, { "persist.sys.locale", "en-US" }, }; for (auto& p : props) { unsigned int namelen = strlen(p.name); unsigned int valuelen = strlen(p.value); int ret = __system_property_add(p.name, namelen, p.value, valuelen); if (ret != 0) { fprintf(stderr, "Failed to add %s\n", p.name); return ret; } printf("Added: [%s] = [%s]\n", p.name, p.value); } return 0; } ``` -------------------------------- ### __system_property_get — Read a property value by name (deprecated shortcut) Source: https://context7.com/topjohnwu/system_properties/llms.txt Looks up a property by name and copies its value into the provided buffer. The buffer must be at least `PROP_VALUE_MAX` (92) bytes. Returns the length of the value, or 0 if the property does not exist. Deprecated for `ro.*` properties that may hold long values. ```APIDOC ## __system_property_get ### Description Looks up a property by name and copies its value into the provided buffer. The buffer must be at least `PROP_VALUE_MAX` (92) bytes. Returns the length of the value, or `0` if the property does not exist. Deprecated for `ro.*` properties that may hold long values — use `__system_property_read_callback` instead. ### Method `__system_property_get(const char *name, char *value)` ### Parameters #### Path Parameters None #### Query Parameters None #### Request Body None ### Request Example ```c #include #include int main() { char value[PROP_VALUE_MAX]; // 92 bytes int len = __system_property_get("ro.build.version.sdk", value); if (len > 0) { printf("SDK version: %s (length=%d)\n", value, len); // Output: SDK version: 35 (length=2) } else { printf("Property not found\n"); } // Read a property that doesn't exist — value is set to "" and 0 is returned len = __system_property_get("nonexistent.property", value); // len == 0, value[0] == '\0' return 0; } ``` ### Response #### Success Response - **return value** (int) - The length of the property value. If the property does not exist, returns 0. #### Response Example ```json { "example": "// If property 'ro.build.version.sdk' exists and its value is '35':\n// len = 2\n// value = \"35\"\n// If property 'nonexistent.property' does not exist:\n// len = 0\n// value = \"\"" } ``` ``` -------------------------------- ### Read a System Property using __system_property_get Source: https://context7.com/topjohnwu/system_properties/llms.txt Retrieve a system property's value using `__system_property_get`. The provided buffer must be at least `PROP_VALUE_MAX` (92 bytes). This function is deprecated for `ro.*` properties that might contain long values. ```c #include #include int main() { char value[PROP_VALUE_MAX]; // 92 bytes int len = __system_property_get("ro.build.version.sdk", value); if (len > 0) { printf("SDK version: %s (length=%d)\n", value, len); // Output: SDK version: 35 (length=2) } else { printf("Property not found\n"); } // Read a property that doesn't exist — value is set to "" and 0 is returned len = __system_property_get("nonexistent.property", value); // len == 0, value[0] == '\0' return 0; } ``` -------------------------------- ### Wait for System Property Change Source: https://context7.com/topjohnwu/system_properties/llms.txt Use `__system_property_wait` to block until a property changes or a timeout occurs. Pass `nullptr` for `pi` to wait for any property change, and `nullptr` for `relative_timeout` to wait indefinitely. Available since API level 26. ```c++ #include #include #include int main() { const prop_info* pi = __system_property_find("sys.boot_completed"); if (!pi) return 1; uint32_t serial = __system_property_serial(pi); struct timespec timeout = { .tv_sec = 30, .tv_nsec = 0 }; // 30-second timeout uint32_t new_serial; bool changed = __system_property_wait(pi, serial, &new_serial, &timeout); if (changed) { char value[PROP_VALUE_MAX]; __system_property_get("sys.boot_completed", value); printf("sys.boot_completed changed to: %s (serial=%u)\n", value, new_serial); } else { printf("Timed out waiting for sys.boot_completed\n"); } // Wait on ANY property change using nullptr pi uint32_t global_serial = __system_property_area_serial(); __system_property_wait(nullptr, global_serial, &new_serial, nullptr /* wait forever */); printf("Some property changed, new global serial: %u\n", new_serial); return 0; } ``` -------------------------------- ### Update System Property Value (init only) Source: https://context7.com/topjohnwu/system_properties/llms.txt Updates an existing system property. Only callable by the init process. The new value must be less than PROP_VALUE_MAX (92 bytes). ```c++ #include #include #include // Called by init's property service when a setprop request arrives int update_property(const char* name, const char* new_value) { // Cast away const — Update requires a mutable prop_info* (init only) prop_info* pi = const_cast(__system_property_find(name)); if (!pi) { fprintf(stderr, "Property '%s' not found\n", name); return -1; } unsigned int len = strlen(new_value); if (len >= PROP_VALUE_MAX) { fprintf(stderr, "Value too long: %u >= %d\n", len, PROP_VALUE_MAX); return -1; } int ret = __system_property_update(pi, new_value, len); if (ret == 0) { printf("Updated [%s] -> [%s]\n", name, new_value); } return ret; } ``` -------------------------------- ### __system_properties_zygote_reload Source: https://context7.com/topjohnwu/system_properties/llms.txt Reloads system properties from disk. This function is exclusively for the Zygote process and must be invoked from the main thread. Calling this may invalidate previously obtained pointers from `__system_property_find`. This feature is available from API level 35 onwards. ```APIDOC ## __system_properties_zygote_reload — Reload properties from disk (Zygote only, API level 35+) ### Description Reloads the system property area from disk. Only intended for the Zygote process and must be called from the main thread. Pointers previously obtained from `__system_property_find` may be invalidated. Available since API level 35. ### Method (Internal C function, not directly mapped to HTTP) ### Parameters None. ### Return Value - **0** on success. - **Non-zero** on failure. ``` -------------------------------- ### Read System Property Atomically with Callback Source: https://context7.com/topjohnwu/system_properties/llms.txt Use `__system_property_read_callback` for atomic reads of property name, value, and serial. This is preferred for `ro.*` properties, especially those exceeding 92 bytes. Available since API level 26. ```c++ #include #include #include struct ReadResult { std::string name; std::string value; uint32_t serial; }; static void read_cb(void* cookie, const char* name, const char* value, uint32_t serial) { auto* result = static_cast(cookie); result->name = name; result->value = value; result->serial = serial; } int main() { const prop_info* pi = __system_property_find("ro.build.fingerprint"); if (!pi) return 1; ReadResult result; __system_property_read_callback(pi, read_cb, &result); printf("fingerprint: %s\n", result.value.c_str()); printf("serial: %u\n", result.serial); // Output (example): // fingerprint: google/oriole/oriole:15/AP4A.250405.002/13028774:user/release-keys // serial: 4 return 0; } ``` -------------------------------- ### __system_property_read_callback Source: https://context7.com/topjohnwu/system_properties/llms.txt Reads the name, value, and serial number of a system property atomically. This is the preferred method for reading properties, especially those with values exceeding 92 bytes, as it ensures a consistent snapshot. Available since API level 26. ```APIDOC ## __system_property_read_callback ### Description Invokes a caller-supplied callback with the property's name, value, and serial number, read as a consistent snapshot. This is the preferred read path, especially for `ro.*` properties whose values may exceed 92 bytes. Available since API level 26. ### Parameters - `pi` (const prop_info*): Pointer to the property information obtained via `__system_property_find`. - `callback` (void (*)(void*, const char*, const char*, uint32_t)): A callback function to be invoked with the property's name, value, and serial number. - `cookie` (void*): A user-defined pointer passed to the callback function. ### Return Value This function does not explicitly return a value, but the callback function will be invoked with the property details. ### Example ```c #include #include #include struct ReadResult { std::string name; std::string value; uint32_t serial; }; static void read_cb(void* cookie, const char* name, const char* value, uint32_t serial) { auto* result = static_cast(cookie); result->name = name; result->value = value; result->serial = serial; } int main() { const prop_info* pi = __system_property_find("ro.build.fingerprint"); if (!pi) return 1; ReadResult result; __system_property_read_callback(pi, read_cb, &result); printf("fingerprint: %s\n", result.value.c_str()); printf("serial: %u\n", result.serial); // Output (example): // fingerprint: google/oriole/oriole:15/AP4A.250405.002/13028774:user/release-keys // serial: 4 return 0; } ``` ``` -------------------------------- ### __system_property_add Source: https://context7.com/topjohnwu/system_properties/llms.txt Adds a new property to the writable property area. This function is restricted to processes with write access, typically the `init` process. ```APIDOC ## __system_property_add — Add a new property (init only) ### Description Adds a new property to the writable property area. Can only be called by the process with write access (typically `init`). For `ro.*` properties, the value may exceed `PROP_VALUE_MAX`. Returns `0` on success, `-1` if the area is full or the name/value lengths are invalid. ### Usage Example ```c #include #include #include // Called by init during early boot int add_build_properties() { struct { const char* name; const char* value; } props[] = { { "ro.product.manufacturer", "Google" }, { "ro.product.model", "Pixel 8" }, { "ro.build.version.sdk", "35" }, { "persist.sys.locale", "en-US" }, }; for (auto& p : props) { unsigned int namelen = strlen(p.name); unsigned int valuelen = strlen(p.value); int ret = __system_property_add(p.name, namelen, p.value, valuelen); if (ret != 0) { fprintf(stderr, "Failed to add %s\n", p.name); return ret; } printf("Added: [%s] = [%s]\n", p.name, p.value); } return 0; } ``` ``` -------------------------------- ### __system_property_area_serial Source: https://context7.com/topjohnwu/system_properties/llms.txt Reads the global property area serial number. This serial number increments whenever any property in the area changes, allowing for efficient change detection. ```APIDOC ## __system_property_area_serial — Read the global property area serial ### Description Returns the global serial number that increments whenever any property in the area changes. Use this to determine cheaply whether any property may have changed since the last check. ### Usage Example ```c #include #include int main() { uint32_t serial_before = __system_property_area_serial(); printf("Serial before: %u\n", serial_before); // ... some time passes, properties may be updated by other processes ... uint32_t serial_after = __system_property_area_serial(); if (serial_after != serial_before) { printf("At least one property changed (serial %u -> %u)\n", serial_before, serial_after); } else { printf("No properties changed\n"); } return 0; } ``` ``` -------------------------------- ### __system_property_delete Source: https://context7.com/topjohnwu/system_properties/llms.txt Deletes a system property by its name. The `prune` parameter determines whether the property's trie node is completely removed (`true`) or just its value cleared (`false`). This function is restricted to the init process. It returns 0 on success and -1 on failure. ```APIDOC ## __system_property_delete — Delete a property (init only) ### Description Removes a property from the area by name. The `prune` parameter controls whether the trie node is removed (`true`) or only the value cleared (`false`). Only callable by init. Returns `0` on success, `-1` on failure. ### Method (Internal C function, not directly mapped to HTTP) ### Parameters - **name** (`const char*`) - Required - The name of the property to delete. - **prune** (`bool`) - Required - If `true`, removes the trie node; if `false`, only clears the value. ### Return Value - **0** on success. - **-1** on failure. ``` -------------------------------- ### Delete System Property (init only) Source: https://context7.com/topjohnwu/system_properties/llms.txt Removes a property from the system properties area. The `prune` parameter determines if the trie node is removed or just the value cleared. Only callable by init. ```c #include #include // Remove a temporary debug property set during early boot int cleanup_debug_properties() { // prune=true: remove the trie node entirely int ret = __system_property_delete("debug.myapp.bootstrap", true); if (ret == 0) { printf("Property deleted\n"); } else { fprintf(stderr, "Delete failed (property may not exist)\n"); } return ret; } ``` -------------------------------- ### __system_property_serial Source: https://context7.com/topjohnwu/system_properties/llms.txt Retrieves the current serial number of a specific system property. The serial number increments upon property updates, serving as an efficient mechanism for change detection. It is recommended to use `__system_property_read_callback` for atomically reading both the value and serial. ```APIDOC ## __system_property_serial ### Description Returns the current serial number of the given property. The serial number is incremented whenever the property is updated, making it a cheap change-detection mechanism. Prefer `__system_property_read_callback` for reading both the value and serial atomically. ### Parameters - `pi` (const prop_info*): Pointer to the property information obtained via `__system_property_find`. ### Return Value - `uint32_t`: The current serial number of the property. ### Example ```c #include #include int main() { const prop_info* pi = __system_property_find("debug.myapp.config"); if (!pi) return 1; uint32_t last_serial = __system_property_serial(pi); printf("Initial serial: %u\n", last_serial); // Poll for changes (in production prefer __system_property_wait) while (true) { uint32_t current_serial = __system_property_serial(pi); if (current_serial != last_serial) { printf("Property changed! new serial=%u\n", current_serial); last_serial = current_serial; break; } } return 0; } ``` ``` -------------------------------- ### __system_property_wait Source: https://context7.com/topjohnwu/system_properties/llms.txt Blocks the calling thread until a specified system property is updated beyond a given serial number or until a timeout occurs. This function is available since API level 26. If `pi` is null, it waits for any property change. If `relative_timeout` is null, it waits indefinitely. ```APIDOC ## __system_property_wait ### Description Blocks the calling thread until the property identified by `pi` is updated past `old_serial`, or until `relative_timeout` elapses. Pass `nullptr` for `pi` to wait on the global serial (any property change). Pass `nullptr` for `relative_timeout` to wait forever. Returns `true` and writes the new serial into `*new_serial_ptr` on success, or `false` on timeout. Available since API level 26. ### Parameters - `pi` (const prop_info*): Pointer to the property information. If `nullptr`, waits for any property change. - `old_serial` (uint32_t): The serial number to wait beyond. - `new_serial_ptr` (uint32_t*): Pointer to store the new serial number upon successful wait. - `relative_timeout` (const struct timespec*): A pointer to a `timespec` structure specifying the maximum time to wait. If `nullptr`, waits indefinitely. ### Return Value - `bool`: `true` if the property changed before the timeout, `false` otherwise. ### Example ```c #include #include #include int main() { const prop_info* pi = __system_property_find("sys.boot_completed"); if (!pi) return 1; uint32_t serial = __system_property_serial(pi); struct timespec timeout = { .tv_sec = 30, .tv_nsec = 0 }; // 30-second timeout uint32_t new_serial; bool changed = __system_property_wait(pi, serial, &new_serial, &timeout); if (changed) { char value[PROP_VALUE_MAX]; __system_property_get("sys.boot_completed", value); printf("sys.boot_completed changed to: %s (serial=%u)\n", value, new_serial); } else { printf("Timed out waiting for sys.boot_completed\n"); } // Wait on ANY property change using nullptr pi uint32_t global_serial = __system_property_area_serial(); __system_property_wait(nullptr, global_serial, &new_serial, nullptr /* wait forever */); printf("Some property changed, new global serial: %u\n", new_serial); return 0; } ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.