Skip to content

Commit 1918373

Browse files
qwandorGerrit Code Review
authored andcommitted
Merge changes I4dc1263b,Ie147ab00 into main
* changes: Add method to get bundle value from bundle. Add methods to insert string, vectors and bundles.
2 parents 713a276 + de68aaa commit 1918373

1 file changed

Lines changed: 258 additions & 17 deletions

File tree

libs/binder/rust/src/persistable_bundle.rs

Lines changed: 258 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,10 +23,14 @@ use crate::{
2323
use binder_ndk_sys::{
2424
APersistableBundle, APersistableBundle_delete, APersistableBundle_dup,
2525
APersistableBundle_erase, APersistableBundle_getBoolean, APersistableBundle_getDouble,
26-
APersistableBundle_getInt, APersistableBundle_getLong, APersistableBundle_isEqual,
27-
APersistableBundle_new, APersistableBundle_putBoolean, APersistableBundle_putDouble,
28-
APersistableBundle_putInt, APersistableBundle_putLong, APersistableBundle_readFromParcel,
29-
APersistableBundle_size, APersistableBundle_writeToParcel,
26+
APersistableBundle_getInt, APersistableBundle_getLong, APersistableBundle_getPersistableBundle,
27+
APersistableBundle_isEqual, APersistableBundle_new, APersistableBundle_putBoolean,
28+
APersistableBundle_putBooleanVector, APersistableBundle_putDouble,
29+
APersistableBundle_putDoubleVector, APersistableBundle_putInt, APersistableBundle_putIntVector,
30+
APersistableBundle_putLong, APersistableBundle_putLongVector,
31+
APersistableBundle_putPersistableBundle, APersistableBundle_putString,
32+
APersistableBundle_putStringVector, APersistableBundle_readFromParcel, APersistableBundle_size,
33+
APersistableBundle_writeToParcel,
3034
};
3135
use std::ffi::{CString, NulError};
3236
use std::ptr::{null_mut, NonNull};
@@ -60,7 +64,7 @@ impl PersistableBundle {
6064
let key = CString::new(key)?;
6165
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
6266
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
63-
// to be valid for the lifetime of `key`.
67+
// to be valid for the duration of this call.
6468
Ok(unsafe { APersistableBundle_erase(self.0.as_ptr(), key.as_ptr()) != 0 })
6569
}
6670

@@ -73,7 +77,7 @@ impl PersistableBundle {
7377
let key = CString::new(key)?;
7478
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
7579
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
76-
// to be valid for the lifetime of `key`.
80+
// to be valid for the duration of this call.
7781
unsafe {
7882
APersistableBundle_putBoolean(self.0.as_ptr(), key.as_ptr(), value);
7983
}
@@ -89,7 +93,7 @@ impl PersistableBundle {
8993
let key = CString::new(key)?;
9094
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
9195
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
92-
// to be valid for the lifetime of `key`.
96+
// to be valid for the duration of this call.
9397
unsafe {
9498
APersistableBundle_putInt(self.0.as_ptr(), key.as_ptr(), value);
9599
}
@@ -105,7 +109,7 @@ impl PersistableBundle {
105109
let key = CString::new(key)?;
106110
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
107111
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
108-
// to be valid for the lifetime of `key`.
112+
// to be valid for the duration of this call.
109113
unsafe {
110114
APersistableBundle_putLong(self.0.as_ptr(), key.as_ptr(), value);
111115
}
@@ -121,13 +125,182 @@ impl PersistableBundle {
121125
let key = CString::new(key)?;
122126
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
123127
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
124-
// to be valid for the lifetime of `key`.
128+
// to be valid for the duration of this call.
125129
unsafe {
126130
APersistableBundle_putDouble(self.0.as_ptr(), key.as_ptr(), value);
127131
}
128132
Ok(())
129133
}
130134

135+
/// Inserts a key-value pair into the bundle.
136+
///
137+
/// If the key is already present then its value will be overwritten by the given value.
138+
///
139+
/// Returns an error if the key or value contains a NUL character.
140+
pub fn insert_string(&mut self, key: &str, value: &str) -> Result<(), NulError> {
141+
let key = CString::new(key)?;
142+
let value = CString::new(value)?;
143+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
144+
// lifetime of the `PersistableBundle`. The pointer returned by `CStr::as_ptr` is guaranteed
145+
// to be valid for the duration of this call.
146+
unsafe {
147+
APersistableBundle_putString(self.0.as_ptr(), key.as_ptr(), value.as_ptr());
148+
}
149+
Ok(())
150+
}
151+
152+
/// Inserts a key-value pair into the bundle.
153+
///
154+
/// If the key is already present then its value will be overwritten by the given value.
155+
///
156+
/// Returns an error if the key contains a NUL character.
157+
pub fn insert_bool_vec(&mut self, key: &str, value: &[bool]) -> Result<(), NulError> {
158+
let key = CString::new(key)?;
159+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
160+
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
161+
// to be valid for the duration of this call, and likewise the pointer returned by
162+
// `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
163+
// duration of the call.
164+
unsafe {
165+
APersistableBundle_putBooleanVector(
166+
self.0.as_ptr(),
167+
key.as_ptr(),
168+
value.as_ptr(),
169+
value.len().try_into().unwrap(),
170+
);
171+
}
172+
Ok(())
173+
}
174+
175+
/// Inserts a key-value pair into the bundle.
176+
///
177+
/// If the key is already present then its value will be overwritten by the given value.
178+
///
179+
/// Returns an error if the key contains a NUL character.
180+
pub fn insert_int_vec(&mut self, key: &str, value: &[i32]) -> Result<(), NulError> {
181+
let key = CString::new(key)?;
182+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
183+
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
184+
// to be valid for the duration of this call, and likewise the pointer returned by
185+
// `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
186+
// duration of the call.
187+
unsafe {
188+
APersistableBundle_putIntVector(
189+
self.0.as_ptr(),
190+
key.as_ptr(),
191+
value.as_ptr(),
192+
value.len().try_into().unwrap(),
193+
);
194+
}
195+
Ok(())
196+
}
197+
198+
/// Inserts a key-value pair into the bundle.
199+
///
200+
/// If the key is already present then its value will be overwritten by the given value.
201+
///
202+
/// Returns an error if the key contains a NUL character.
203+
pub fn insert_long_vec(&mut self, key: &str, value: &[i64]) -> Result<(), NulError> {
204+
let key = CString::new(key)?;
205+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
206+
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
207+
// to be valid for the duration of this call, and likewise the pointer returned by
208+
// `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
209+
// duration of the call.
210+
unsafe {
211+
APersistableBundle_putLongVector(
212+
self.0.as_ptr(),
213+
key.as_ptr(),
214+
value.as_ptr(),
215+
value.len().try_into().unwrap(),
216+
);
217+
}
218+
Ok(())
219+
}
220+
221+
/// Inserts a key-value pair into the bundle.
222+
///
223+
/// If the key is already present then its value will be overwritten by the given value.
224+
///
225+
/// Returns an error if the key contains a NUL character.
226+
pub fn insert_double_vec(&mut self, key: &str, value: &[f64]) -> Result<(), NulError> {
227+
let key = CString::new(key)?;
228+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
229+
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
230+
// to be valid for the duration of this call, and likewise the pointer returned by
231+
// `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
232+
// duration of the call.
233+
unsafe {
234+
APersistableBundle_putDoubleVector(
235+
self.0.as_ptr(),
236+
key.as_ptr(),
237+
value.as_ptr(),
238+
value.len().try_into().unwrap(),
239+
);
240+
}
241+
Ok(())
242+
}
243+
244+
/// Inserts a key-value pair into the bundle.
245+
///
246+
/// If the key is already present then its value will be overwritten by the given value.
247+
///
248+
/// Returns an error if the key contains a NUL character.
249+
pub fn insert_string_vec<'a, T: ToString + 'a>(
250+
&mut self,
251+
key: &str,
252+
value: impl IntoIterator<Item = &'a T>,
253+
) -> Result<(), NulError> {
254+
let key = CString::new(key)?;
255+
// We need to collect the new `CString`s into something first so that they live long enough
256+
// for their pointers to be valid for the `APersistableBundle_putStringVector` call below.
257+
let c_strings = value
258+
.into_iter()
259+
.map(|s| CString::new(s.to_string()))
260+
.collect::<Result<Vec<_>, NulError>>()?;
261+
let char_pointers = c_strings.iter().map(|s| s.as_ptr()).collect::<Vec<_>>();
262+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
263+
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
264+
// to be valid for the duration of this call, and likewise the pointer returned by
265+
// `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
266+
// duration of the call.
267+
unsafe {
268+
APersistableBundle_putStringVector(
269+
self.0.as_ptr(),
270+
key.as_ptr(),
271+
char_pointers.as_ptr(),
272+
char_pointers.len().try_into().unwrap(),
273+
);
274+
}
275+
Ok(())
276+
}
277+
278+
/// Inserts a key-value pair into the bundle.
279+
///
280+
/// If the key is already present then its value will be overwritten by the given value.
281+
///
282+
/// Returns an error if the key contains a NUL character.
283+
pub fn insert_persistable_bundle(
284+
&mut self,
285+
key: &str,
286+
value: &PersistableBundle,
287+
) -> Result<(), NulError> {
288+
let key = CString::new(key)?;
289+
// SAFETY: The wrapped `APersistableBundle` pointers are guaranteed to be valid for the
290+
// lifetime of the `PersistableBundle`s. The pointer returned by `CStr::as_ptr` is
291+
// guaranteed to be valid for the duration of this call, and
292+
// `APersistableBundle_putPersistableBundle` does a deep copy so that is all that is
293+
// required.
294+
unsafe {
295+
APersistableBundle_putPersistableBundle(
296+
self.0.as_ptr(),
297+
key.as_ptr(),
298+
value.0.as_ptr(),
299+
);
300+
}
301+
Ok(())
302+
}
303+
131304
/// Gets the boolean value associated with the given key.
132305
///
133306
/// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
@@ -137,8 +310,8 @@ impl PersistableBundle {
137310
let mut value = false;
138311
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
139312
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
140-
// to be valid for the lifetime of `key`. The value pointer must be valid because it comes
141-
// from a reference.
313+
// to be valid for the duration of this call. The value pointer must be valid because it
314+
// comes from a reference.
142315
if unsafe { APersistableBundle_getBoolean(self.0.as_ptr(), key.as_ptr(), &mut value) } {
143316
Ok(Some(value))
144317
} else {
@@ -155,8 +328,8 @@ impl PersistableBundle {
155328
let mut value = 0;
156329
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
157330
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
158-
// to be valid for the lifetime of `key`. The value pointer must be valid because it comes
159-
// from a reference.
331+
// to be valid for the duration of this call. The value pointer must be valid because it
332+
// comes from a reference.
160333
if unsafe { APersistableBundle_getInt(self.0.as_ptr(), key.as_ptr(), &mut value) } {
161334
Ok(Some(value))
162335
} else {
@@ -173,8 +346,8 @@ impl PersistableBundle {
173346
let mut value = 0;
174347
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
175348
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
176-
// to be valid for the lifetime of `key`. The value pointer must be valid because it comes
177-
// from a reference.
349+
// to be valid for the duration of this call. The value pointer must be valid because it
350+
// comes from a reference.
178351
if unsafe { APersistableBundle_getLong(self.0.as_ptr(), key.as_ptr(), &mut value) } {
179352
Ok(Some(value))
180353
} else {
@@ -191,14 +364,36 @@ impl PersistableBundle {
191364
let mut value = 0.0;
192365
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
193366
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
194-
// to be valid for the lifetime of `key`. The value pointer must be valid because it comes
195-
// from a reference.
367+
// to be valid for the duration of this call. The value pointer must be valid because it
368+
// comes from a reference.
196369
if unsafe { APersistableBundle_getDouble(self.0.as_ptr(), key.as_ptr(), &mut value) } {
197370
Ok(Some(value))
198371
} else {
199372
Ok(None)
200373
}
201374
}
375+
376+
/// Gets the `PersistableBundle` value associated with the given key.
377+
///
378+
/// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
379+
/// in the bundle.
380+
pub fn get_persistable_bundle(&self, key: &str) -> Result<Option<Self>, NulError> {
381+
let key = CString::new(key)?;
382+
let mut value = null_mut();
383+
// SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
384+
// lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
385+
// to be valid for the lifetime of `key`. The value pointer must be valid because it comes
386+
// from a reference.
387+
if unsafe {
388+
APersistableBundle_getPersistableBundle(self.0.as_ptr(), key.as_ptr(), &mut value)
389+
} {
390+
Ok(Some(Self(NonNull::new(value).expect(
391+
"APersistableBundle_getPersistableBundle returned true but didn't set outBundle",
392+
))))
393+
} else {
394+
Ok(None)
395+
}
396+
}
202397
}
203398

204399
// SAFETY: The underlying *APersistableBundle can be moved between threads.
@@ -339,4 +534,50 @@ mod test {
339534
assert_eq!(bundle.get_double("double"), Ok(None));
340535
assert_eq!(bundle.size(), 0);
341536
}
537+
538+
#[test]
539+
fn insert_string() {
540+
let mut bundle = PersistableBundle::new();
541+
assert_eq!(bundle.insert_string("string", "foo"), Ok(()));
542+
assert_eq!(bundle.size(), 1);
543+
}
544+
545+
#[test]
546+
fn insert_vec() {
547+
let mut bundle = PersistableBundle::new();
548+
549+
assert_eq!(bundle.insert_bool_vec("bool", &[]), Ok(()));
550+
assert_eq!(bundle.insert_int_vec("int", &[42]), Ok(()));
551+
assert_eq!(bundle.insert_long_vec("long", &[66, 67, 68]), Ok(()));
552+
assert_eq!(bundle.insert_double_vec("double", &[123.4]), Ok(()));
553+
assert_eq!(bundle.insert_string_vec("string", &["foo", "bar", "baz"]), Ok(()));
554+
assert_eq!(
555+
bundle.insert_string_vec(
556+
"string",
557+
&[&"foo".to_string(), &"bar".to_string(), &"baz".to_string()]
558+
),
559+
Ok(())
560+
);
561+
assert_eq!(
562+
bundle.insert_string_vec(
563+
"string",
564+
&["foo".to_string(), "bar".to_string(), "baz".to_string()]
565+
),
566+
Ok(())
567+
);
568+
569+
assert_eq!(bundle.size(), 5);
570+
}
571+
572+
#[test]
573+
fn insert_get_bundle() {
574+
let mut bundle = PersistableBundle::new();
575+
576+
let mut sub_bundle = PersistableBundle::new();
577+
assert_eq!(sub_bundle.insert_int("int", 42), Ok(()));
578+
assert_eq!(sub_bundle.size(), 1);
579+
assert_eq!(bundle.insert_persistable_bundle("bundle", &sub_bundle), Ok(()));
580+
581+
assert_eq!(bundle.get_persistable_bundle("bundle"), Ok(Some(sub_bundle)));
582+
}
342583
}

0 commit comments

Comments
 (0)