diff options
| author | 2025-01-15 17:40:14 +0000 | |
|---|---|---|
| committer | 2025-01-16 11:23:44 +0000 | |
| commit | cea15921073fbe96c2400f690b5fc164b34e3da1 (patch) | |
| tree | ce6534b6a3fa45a0d06c09cb769d615e2d9dbc28 | |
| parent | 12a57e3f4297cfc69a66fa5951853638fa619e01 (diff) | |
Start on Rust bindings for APersistableBundle.
Bug: 389074518
Test: atest libbinder_rs-internal_test
Change-Id: I398a9bf921993848c2e4774090413a6f5ef20c34
| -rw-r--r-- | libs/binder/rust/src/lib.rs | 4 | ||||
| -rw-r--r-- | libs/binder/rust/src/persistable_bundle.rs | 92 | ||||
| -rw-r--r-- | libs/binder/rust/sys/BinderBindings.hpp | 1 |
3 files changed, 97 insertions, 0 deletions
diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs index e08a76312d..77b80fe1ec 100644 --- a/libs/binder/rust/src/lib.rs +++ b/libs/binder/rust/src/lib.rs @@ -99,6 +99,8 @@ mod binder_async; mod error; mod native; mod parcel; +#[cfg(not(trusty))] +mod persistable_bundle; mod proxy; #[cfg(not(any(trusty, android_ndk)))] mod service; @@ -113,6 +115,8 @@ pub use crate::binder_async::{BinderAsyncPool, BoxFuture}; pub use binder::{BinderFeatures, FromIBinder, IBinder, Interface, Strong, Weak}; pub use error::{ExceptionCode, IntoBinderResult, Status, StatusCode}; pub use parcel::{ParcelFileDescriptor, Parcelable, ParcelableHolder}; +#[cfg(not(trusty))] +pub use persistable_bundle::PersistableBundle; pub use proxy::{DeathRecipient, SpIBinder, WpIBinder}; #[cfg(not(any(trusty, android_ndk)))] pub use service::{ diff --git a/libs/binder/rust/src/persistable_bundle.rs b/libs/binder/rust/src/persistable_bundle.rs new file mode 100644 index 0000000000..c62feb079e --- /dev/null +++ b/libs/binder/rust/src/persistable_bundle.rs @@ -0,0 +1,92 @@ +/* + * Copyright (C) 2025 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. + */ + +use binder_ndk_sys::{ + APersistableBundle, APersistableBundle_delete, APersistableBundle_dup, + APersistableBundle_isEqual, APersistableBundle_new, APersistableBundle_size, +}; +use std::ptr::NonNull; + +/// A mapping from string keys to values of various types. +#[derive(Debug)] +pub struct PersistableBundle(NonNull<APersistableBundle>); + +impl PersistableBundle { + /// Creates a new `PersistableBundle`. + pub fn new() -> Self { + // SAFETY: APersistableBundle_new doesn't actually have any safety requirements. + let bundle = unsafe { APersistableBundle_new() }; + Self(NonNull::new(bundle).expect("Allocated APersistableBundle was null")) + } + + /// Returns the number of mappings in the bundle. + pub fn size(&self) -> usize { + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. + unsafe { APersistableBundle_size(self.0.as_ptr()) } + .try_into() + .expect("APersistableBundle_size returned a negative size") + } +} + +impl Default for PersistableBundle { + fn default() -> Self { + Self::new() + } +} + +impl Drop for PersistableBundle { + fn drop(&mut self) { + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of this `PersistableBundle`. + unsafe { APersistableBundle_delete(self.0.as_ptr()) }; + } +} + +impl Clone for PersistableBundle { + fn clone(&self) -> Self { + // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the + // lifetime of the `PersistableBundle`. + let duplicate = unsafe { APersistableBundle_dup(self.0.as_ptr()) }; + Self(NonNull::new(duplicate).expect("Duplicated APersistableBundle was null")) + } +} + +impl PartialEq for PersistableBundle { + fn eq(&self, other: &Self) -> bool { + // SAFETY: The wrapped `APersistableBundle` pointers are guaranteed to be valid for the + // lifetime of the `PersistableBundle`s. + unsafe { APersistableBundle_isEqual(self.0.as_ptr(), other.0.as_ptr()) } + } +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn create_delete() { + let bundle = PersistableBundle::new(); + drop(bundle); + } + + #[test] + fn duplicate_equal() { + let bundle = PersistableBundle::new(); + let duplicate = bundle.clone(); + assert_eq!(bundle, duplicate); + } +} diff --git a/libs/binder/rust/sys/BinderBindings.hpp b/libs/binder/rust/sys/BinderBindings.hpp index 557f0e895d..deeaa37b94 100644 --- a/libs/binder/rust/sys/BinderBindings.hpp +++ b/libs/binder/rust/sys/BinderBindings.hpp @@ -17,6 +17,7 @@ #include <android/binder_ibinder.h> #include <android/binder_parcel.h> #include <android/binder_status.h> +#include <android/persistable_bundle.h> /* Platform only */ #if defined(ANDROID_PLATFORM) || defined(__ANDROID_VENDOR__) |