Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add bindings for querying and setting Android System Properties #495

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

MarijnS95
Copy link
Member

The Android System Property API might not be very useful for most apps even though it still provides a read-only view of all properties but no rights to set any. Since this is accessible via the NDK this crate should provide a clean and complete (including UB-free) wrapper implementation either way.

Copy link

@Athosvk Athosvk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks really helpful. The only thing for the raw APIs that have limtis is maybe considering to add some asserts, since those specific errors is not something we can catch from what is returned by the ndk itself

///
/// # Deprecation
/// Deprecated since Android O (API level 26), use [`Property::find()`] with
/// [`Property::read_callback()`] instead which does not have a limit on `value` nor `name` length.
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should the docs here maybe also mention the limit on what the limit on returned value is, like is done for the property name?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's already covered in the first paragraph / "Returns xxx title" of this function?

Perhaps I should remove and `name` here as we've never introduced a limit on name length in this function and as demonstrated elsewhere, there is none for get() (only for __system_property_read()).

Comment on lines 216 to 244
// TODO: should we return the name of ffi::PROP_NAME_MAX?
ffi::__system_property_read(self.0.as_ptr(), std::ptr::null_mut(), value)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Notice that I still have to consider whether to always allocate + move a name here in read_raw() and read().

This may seem silly when using let prop = Property::find(c"we.know.the.name"), but it's the only API to get names out of Property::foreach(|prop| prop.how_to_get_the_name()) before Android O where one can call prop.read_callback() and get the name (without limitations on length).

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The most nice and trivial implementation uses an initialized slice of ffi::PROP_NAME_MAX characters, so that we can safely call CStr::from_bytes_until_nul() and copy into a host allocation. But that requires MSRV 1.69, which must be an acceptable bump but I still haven't set up a proper MSRV policy to follow (besides chugging along with winit).

Copy link
Member Author

@MarijnS95 MarijnS95 Mar 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced this with an ordinary call to CStr::from_ptr() on a MaybeUninit slice, like we do in other places where I described to use CStr::from_bytes_until_nul() when the MSRV is bumped.

Notice also that this doesn't require a NulError for the name, and in hindsight I'm considering to remove it for the value too: the contract with the NDK specifies that it should have written a NUL terminator within the property length limit, and returned the length of the string (excluding NUL terminator). If that's violated, which should pretty much never happen, we might as well unwrap and panic rather than bubbling a "pretty much unreachable" error up to the user to match in thiserror. They will after all want to match on MissingOrEmpty and handle that gracefully.

At least that's the guidance I've been following over the years when deciding to prefer returning Result::Err over a panic!().

@MarijnS95 MarijnS95 force-pushed the system-properties branch 6 times, most recently from 2611db6 to 10d0d78 Compare March 14, 2025 22:28
The Android System Property API might not be very useful for most
apps even though it still provides a read-only view of all properties
but no rights to set any.  Since this is accessible via the NDK this
crate should provide a clean and complete (including UB-free) wrapper
implementation either way.

This requires bumping `thiserror` to `1.0.29` which introduced proper
impl bounds in https://togithub.com/dtolnay/thiserror/pull/148 such that
no `Debug` bound needs to be written anywhere that `GetError<>` is used.
As a second advantage, this error type can still be used with `FromStr`
implementations whose `Err` type does not implement `Error`/`Debug`,
those just cannot be `.unwrap()`ped.
@MarijnS95 MarijnS95 requested a review from Athosvk March 14, 2025 22:33
@MarijnS95 MarijnS95 added this to the 0.10.0 release milestone Mar 14, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants