Skip to content

Commit cea1592

Browse files
committed
Start on Rust bindings for APersistableBundle.
Bug: 389074518 Test: atest libbinder_rs-internal_test Change-Id: I398a9bf921993848c2e4774090413a6f5ef20c34
1 parent 12a57e3 commit cea1592

3 files changed

Lines changed: 97 additions & 0 deletions

File tree

libs/binder/rust/src/lib.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,8 @@ mod binder_async;
9999
mod error;
100100
mod native;
101101
mod parcel;
102+
#[cfg(not(trusty))]
103+
mod persistable_bundle;
102104
mod proxy;
103105
#[cfg(not(any(trusty, android_ndk)))]
104106
mod service;
@@ -113,6 +115,8 @@ pub use crate::binder_async::{BinderAsyncPool, BoxFuture};
113115
pub use binder::{BinderFeatures, FromIBinder, IBinder, Interface, Strong, Weak};
114116
pub use error::{ExceptionCode, IntoBinderResult, Status, StatusCode};
115117
pub use parcel::{ParcelFileDescriptor, Parcelable, ParcelableHolder};
118+
#[cfg(not(trusty))]
119+
pub use persistable_bundle::PersistableBundle;
116120
pub use proxy::{DeathRecipient, SpIBinder, WpIBinder};
117121
#[cfg(not(any(trusty, android_ndk)))]
118122
pub use service::{
Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/*
2+
* Copyright (C) 2025 The Android Open Source Project
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
use binder_ndk_sys::{
18+
APersistableBundle, APersistableBundle_delete, APersistableBundle_dup,
19+
APersistableBundle_isEqual, APersistableBundle_new, APersistableBundle_size,
20+
};
21+
use std::ptr::NonNull;
22+
23+
/// A mapping from string keys to values of various types.
24+
#[derive(Debug)]
25+
pub struct PersistableBundle(NonNull<APersistableBundle>);
26+
27+
impl PersistableBundle {
28+
/// Creates a new `PersistableBundle`.
29+
pub fn new() -> Self {
30+
// SAFETY: APersistableBundle_new doesn't actually have any safety requirements.
31+
let bundle = unsafe { APersistableBundle_new() };
32+
Self(NonNull::new(bundle).expect("Allocated APersistableBundle was null"))
33+
}
34+
35+
/// Returns the number of mappings in the bundle.
36+
pub fn size(&self) -> usize {
37+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
38+
// lifetime of the `PersistableBundle`.
39+
unsafe { APersistableBundle_size(self.0.as_ptr()) }
40+
.try_into()
41+
.expect("APersistableBundle_size returned a negative size")
42+
}
43+
}
44+
45+
impl Default for PersistableBundle {
46+
fn default() -> Self {
47+
Self::new()
48+
}
49+
}
50+
51+
impl Drop for PersistableBundle {
52+
fn drop(&mut self) {
53+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
54+
// lifetime of this `PersistableBundle`.
55+
unsafe { APersistableBundle_delete(self.0.as_ptr()) };
56+
}
57+
}
58+
59+
impl Clone for PersistableBundle {
60+
fn clone(&self) -> Self {
61+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
62+
// lifetime of the `PersistableBundle`.
63+
let duplicate = unsafe { APersistableBundle_dup(self.0.as_ptr()) };
64+
Self(NonNull::new(duplicate).expect("Duplicated APersistableBundle was null"))
65+
}
66+
}
67+
68+
impl PartialEq for PersistableBundle {
69+
fn eq(&self, other: &Self) -> bool {
70+
// SAFETY: The wrapped `APersistableBundle` pointers are guaranteed to be valid for the
71+
// lifetime of the `PersistableBundle`s.
72+
unsafe { APersistableBundle_isEqual(self.0.as_ptr(), other.0.as_ptr()) }
73+
}
74+
}
75+
76+
#[cfg(test)]
77+
mod test {
78+
use super::*;
79+
80+
#[test]
81+
fn create_delete() {
82+
let bundle = PersistableBundle::new();
83+
drop(bundle);
84+
}
85+
86+
#[test]
87+
fn duplicate_equal() {
88+
let bundle = PersistableBundle::new();
89+
let duplicate = bundle.clone();
90+
assert_eq!(bundle, duplicate);
91+
}
92+
}

libs/binder/rust/sys/BinderBindings.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include <android/binder_ibinder.h>
1818
#include <android/binder_parcel.h>
1919
#include <android/binder_status.h>
20+
#include <android/persistable_bundle.h>
2021

2122
/* Platform only */
2223
#if defined(ANDROID_PLATFORM) || defined(__ANDROID_VENDOR__)

0 commit comments

Comments
 (0)