binder/
persistable_bundle.rs

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
17use crate::{
18    binder::AsNative,
19    error::{status_result, StatusCode},
20    impl_deserialize_for_unstructured_parcelable, impl_serialize_for_unstructured_parcelable,
21    parcel::{BorrowedParcel, UnstructuredParcelable},
22};
23use binder_ndk_sys::{
24    APersistableBundle, APersistableBundle_delete, APersistableBundle_dup,
25    APersistableBundle_erase, APersistableBundle_getBoolean, APersistableBundle_getBooleanKeys,
26    APersistableBundle_getBooleanVector, APersistableBundle_getBooleanVectorKeys,
27    APersistableBundle_getDouble, APersistableBundle_getDoubleKeys,
28    APersistableBundle_getDoubleVector, APersistableBundle_getDoubleVectorKeys,
29    APersistableBundle_getInt, APersistableBundle_getIntKeys, APersistableBundle_getIntVector,
30    APersistableBundle_getIntVectorKeys, APersistableBundle_getLong,
31    APersistableBundle_getLongKeys, APersistableBundle_getLongVector,
32    APersistableBundle_getLongVectorKeys, APersistableBundle_getPersistableBundle,
33    APersistableBundle_getPersistableBundleKeys, APersistableBundle_getString,
34    APersistableBundle_getStringKeys, APersistableBundle_getStringVector,
35    APersistableBundle_getStringVectorKeys, APersistableBundle_isEqual, APersistableBundle_new,
36    APersistableBundle_putBoolean, APersistableBundle_putBooleanVector,
37    APersistableBundle_putDouble, APersistableBundle_putDoubleVector, APersistableBundle_putInt,
38    APersistableBundle_putIntVector, APersistableBundle_putLong, APersistableBundle_putLongVector,
39    APersistableBundle_putPersistableBundle, APersistableBundle_putString,
40    APersistableBundle_putStringVector, APersistableBundle_readFromParcel, APersistableBundle_size,
41    APersistableBundle_writeToParcel, APERSISTABLEBUNDLE_ALLOCATOR_FAILED,
42    APERSISTABLEBUNDLE_KEY_NOT_FOUND,
43};
44use std::ffi::{c_char, c_void, CStr, CString, NulError};
45use std::ptr::{null_mut, slice_from_raw_parts_mut, NonNull};
46use zerocopy::FromZeros;
47
48/// A mapping from string keys to values of various types.
49#[derive(Debug)]
50pub struct PersistableBundle(NonNull<APersistableBundle>);
51
52impl PersistableBundle {
53    /// Creates a new `PersistableBundle`.
54    pub fn new() -> Self {
55        // SAFETY: APersistableBundle_new doesn't actually have any safety requirements.
56        let bundle = unsafe { APersistableBundle_new() };
57        Self(NonNull::new(bundle).expect("Allocated APersistableBundle was null"))
58    }
59
60    /// Returns the number of mappings in the bundle.
61    pub fn size(&self) -> usize {
62        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
63        // lifetime of the `PersistableBundle`.
64        unsafe { APersistableBundle_size(self.0.as_ptr()) }
65            .try_into()
66            .expect("APersistableBundle_size returned a negative size")
67    }
68
69    /// Removes any entry with the given key.
70    ///
71    /// Returns an error if the given key contains a NUL character, otherwise returns whether there
72    /// was any entry to remove.
73    pub fn remove(&mut self, key: &str) -> Result<bool, NulError> {
74        let key = CString::new(key)?;
75        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
76        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
77        // to be valid for the duration of this call.
78        Ok(unsafe { APersistableBundle_erase(self.0.as_ptr(), key.as_ptr()) != 0 })
79    }
80
81    /// Inserts a key-value pair into the bundle.
82    ///
83    /// If the key is already present then its value will be overwritten by the given value.
84    ///
85    /// Returns an error if the key contains a NUL character.
86    pub fn insert_bool(&mut self, key: &str, value: bool) -> Result<(), NulError> {
87        let key = CString::new(key)?;
88        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
89        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
90        // to be valid for the duration of this call.
91        unsafe {
92            APersistableBundle_putBoolean(self.0.as_ptr(), key.as_ptr(), value);
93        }
94        Ok(())
95    }
96
97    /// Inserts a key-value pair into the bundle.
98    ///
99    /// If the key is already present then its value will be overwritten by the given value.
100    ///
101    /// Returns an error if the key contains a NUL character.
102    pub fn insert_int(&mut self, key: &str, value: i32) -> Result<(), NulError> {
103        let key = CString::new(key)?;
104        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
105        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
106        // to be valid for the duration of this call.
107        unsafe {
108            APersistableBundle_putInt(self.0.as_ptr(), key.as_ptr(), value);
109        }
110        Ok(())
111    }
112
113    /// Inserts a key-value pair into the bundle.
114    ///
115    /// If the key is already present then its value will be overwritten by the given value.
116    ///
117    /// Returns an error if the key contains a NUL character.
118    pub fn insert_long(&mut self, key: &str, value: i64) -> Result<(), NulError> {
119        let key = CString::new(key)?;
120        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
121        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
122        // to be valid for the duration of this call.
123        unsafe {
124            APersistableBundle_putLong(self.0.as_ptr(), key.as_ptr(), value);
125        }
126        Ok(())
127    }
128
129    /// Inserts a key-value pair into the bundle.
130    ///
131    /// If the key is already present then its value will be overwritten by the given value.
132    ///
133    /// Returns an error if the key contains a NUL character.
134    pub fn insert_double(&mut self, key: &str, value: f64) -> Result<(), NulError> {
135        let key = CString::new(key)?;
136        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
137        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
138        // to be valid for the duration of this call.
139        unsafe {
140            APersistableBundle_putDouble(self.0.as_ptr(), key.as_ptr(), value);
141        }
142        Ok(())
143    }
144
145    /// Inserts a key-value pair into the bundle.
146    ///
147    /// If the key is already present then its value will be overwritten by the given value.
148    ///
149    /// Returns an error if the key or value contains a NUL character.
150    pub fn insert_string(&mut self, key: &str, value: &str) -> Result<(), NulError> {
151        let key = CString::new(key)?;
152        let value = CString::new(value)?;
153        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
154        // lifetime of the `PersistableBundle`. The pointer returned by `CStr::as_ptr` is guaranteed
155        // to be valid for the duration of this call.
156        unsafe {
157            APersistableBundle_putString(self.0.as_ptr(), key.as_ptr(), value.as_ptr());
158        }
159        Ok(())
160    }
161
162    /// Inserts a key-value pair into the bundle.
163    ///
164    /// If the key is already present then its value will be overwritten by the given value.
165    ///
166    /// Returns an error if the key contains a NUL character.
167    pub fn insert_bool_vec(&mut self, key: &str, value: &[bool]) -> Result<(), NulError> {
168        let key = CString::new(key)?;
169        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
170        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
171        // to be valid for the duration of this call, and likewise the pointer returned by
172        // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
173        // duration of the call.
174        unsafe {
175            APersistableBundle_putBooleanVector(
176                self.0.as_ptr(),
177                key.as_ptr(),
178                value.as_ptr(),
179                value.len().try_into().unwrap(),
180            );
181        }
182        Ok(())
183    }
184
185    /// Inserts a key-value pair into the bundle.
186    ///
187    /// If the key is already present then its value will be overwritten by the given value.
188    ///
189    /// Returns an error if the key contains a NUL character.
190    pub fn insert_int_vec(&mut self, key: &str, value: &[i32]) -> Result<(), NulError> {
191        let key = CString::new(key)?;
192        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
193        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
194        // to be valid for the duration of this call, and likewise the pointer returned by
195        // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
196        // duration of the call.
197        unsafe {
198            APersistableBundle_putIntVector(
199                self.0.as_ptr(),
200                key.as_ptr(),
201                value.as_ptr(),
202                value.len().try_into().unwrap(),
203            );
204        }
205        Ok(())
206    }
207
208    /// Inserts a key-value pair into the bundle.
209    ///
210    /// If the key is already present then its value will be overwritten by the given value.
211    ///
212    /// Returns an error if the key contains a NUL character.
213    pub fn insert_long_vec(&mut self, key: &str, value: &[i64]) -> Result<(), NulError> {
214        let key = CString::new(key)?;
215        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
216        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
217        // to be valid for the duration of this call, and likewise the pointer returned by
218        // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
219        // duration of the call.
220        unsafe {
221            APersistableBundle_putLongVector(
222                self.0.as_ptr(),
223                key.as_ptr(),
224                value.as_ptr(),
225                value.len().try_into().unwrap(),
226            );
227        }
228        Ok(())
229    }
230
231    /// Inserts a key-value pair into the bundle.
232    ///
233    /// If the key is already present then its value will be overwritten by the given value.
234    ///
235    /// Returns an error if the key contains a NUL character.
236    pub fn insert_double_vec(&mut self, key: &str, value: &[f64]) -> Result<(), NulError> {
237        let key = CString::new(key)?;
238        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
239        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
240        // to be valid for the duration of this call, and likewise the pointer returned by
241        // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
242        // duration of the call.
243        unsafe {
244            APersistableBundle_putDoubleVector(
245                self.0.as_ptr(),
246                key.as_ptr(),
247                value.as_ptr(),
248                value.len().try_into().unwrap(),
249            );
250        }
251        Ok(())
252    }
253
254    /// Inserts a key-value pair into the bundle.
255    ///
256    /// If the key is already present then its value will be overwritten by the given value.
257    ///
258    /// Returns an error if the key contains a NUL character.
259    pub fn insert_string_vec<'a, T: ToString + 'a>(
260        &mut self,
261        key: &str,
262        value: impl IntoIterator<Item = &'a T>,
263    ) -> Result<(), NulError> {
264        let key = CString::new(key)?;
265        // We need to collect the new `CString`s into something first so that they live long enough
266        // for their pointers to be valid for the `APersistableBundle_putStringVector` call below.
267        let c_strings = value
268            .into_iter()
269            .map(|s| CString::new(s.to_string()))
270            .collect::<Result<Vec<_>, NulError>>()?;
271        let char_pointers = c_strings.iter().map(|s| s.as_ptr()).collect::<Vec<_>>();
272        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
273        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
274        // to be valid for the duration of this call, and likewise the pointer returned by
275        // `value.as_ptr()` is guaranteed to be valid for at least `value.len()` values for the
276        // duration of the call.
277        unsafe {
278            APersistableBundle_putStringVector(
279                self.0.as_ptr(),
280                key.as_ptr(),
281                char_pointers.as_ptr(),
282                char_pointers.len().try_into().unwrap(),
283            );
284        }
285        Ok(())
286    }
287
288    /// Inserts a key-value pair into the bundle.
289    ///
290    /// If the key is already present then its value will be overwritten by the given value.
291    ///
292    /// Returns an error if the key contains a NUL character.
293    pub fn insert_persistable_bundle(
294        &mut self,
295        key: &str,
296        value: &PersistableBundle,
297    ) -> Result<(), NulError> {
298        let key = CString::new(key)?;
299        // SAFETY: The wrapped `APersistableBundle` pointers are guaranteed to be valid for the
300        // lifetime of the `PersistableBundle`s. The pointer returned by `CStr::as_ptr` is
301        // guaranteed to be valid for the duration of this call, and
302        // `APersistableBundle_putPersistableBundle` does a deep copy so that is all that is
303        // required.
304        unsafe {
305            APersistableBundle_putPersistableBundle(
306                self.0.as_ptr(),
307                key.as_ptr(),
308                value.0.as_ptr(),
309            );
310        }
311        Ok(())
312    }
313
314    /// Gets the boolean value associated with the given key.
315    ///
316    /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
317    /// in the bundle.
318    pub fn get_bool(&self, key: &str) -> Result<Option<bool>, NulError> {
319        let key = CString::new(key)?;
320        let mut value = false;
321        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
322        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
323        // to be valid for the duration of this call. The value pointer must be valid because it
324        // comes from a reference.
325        if unsafe { APersistableBundle_getBoolean(self.0.as_ptr(), key.as_ptr(), &mut value) } {
326            Ok(Some(value))
327        } else {
328            Ok(None)
329        }
330    }
331
332    /// Gets the i32 value associated with the given key.
333    ///
334    /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
335    /// in the bundle.
336    pub fn get_int(&self, key: &str) -> Result<Option<i32>, NulError> {
337        let key = CString::new(key)?;
338        let mut value = 0;
339        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
340        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
341        // to be valid for the duration of this call. The value pointer must be valid because it
342        // comes from a reference.
343        if unsafe { APersistableBundle_getInt(self.0.as_ptr(), key.as_ptr(), &mut value) } {
344            Ok(Some(value))
345        } else {
346            Ok(None)
347        }
348    }
349
350    /// Gets the i64 value associated with the given key.
351    ///
352    /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
353    /// in the bundle.
354    pub fn get_long(&self, key: &str) -> Result<Option<i64>, NulError> {
355        let key = CString::new(key)?;
356        let mut value = 0;
357        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
358        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
359        // to be valid for the duration of this call. The value pointer must be valid because it
360        // comes from a reference.
361        if unsafe { APersistableBundle_getLong(self.0.as_ptr(), key.as_ptr(), &mut value) } {
362            Ok(Some(value))
363        } else {
364            Ok(None)
365        }
366    }
367
368    /// Gets the f64 value associated with the given key.
369    ///
370    /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
371    /// in the bundle.
372    pub fn get_double(&self, key: &str) -> Result<Option<f64>, NulError> {
373        let key = CString::new(key)?;
374        let mut value = 0.0;
375        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
376        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
377        // to be valid for the duration of this call. The value pointer must be valid because it
378        // comes from a reference.
379        if unsafe { APersistableBundle_getDouble(self.0.as_ptr(), key.as_ptr(), &mut value) } {
380            Ok(Some(value))
381        } else {
382            Ok(None)
383        }
384    }
385
386    /// Gets the string value associated with the given key.
387    ///
388    /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
389    /// in the bundle.
390    pub fn get_string(&self, key: &str) -> Result<Option<String>, NulError> {
391        let key = CString::new(key)?;
392        let mut value = null_mut();
393        let mut allocated_size: usize = 0;
394        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
395        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
396        // to be valid for the lifetime of `key`. The value pointer must be valid because it comes
397        // from a reference.
398        let value_size_bytes = unsafe {
399            APersistableBundle_getString(
400                self.0.as_ptr(),
401                key.as_ptr(),
402                &mut value,
403                Some(string_allocator),
404                (&raw mut allocated_size).cast(),
405            )
406        };
407        match value_size_bytes {
408            APERSISTABLEBUNDLE_KEY_NOT_FOUND => Ok(None),
409            APERSISTABLEBUNDLE_ALLOCATOR_FAILED => {
410                panic!("APersistableBundle_getString failed to allocate string");
411            }
412            _ => {
413                let raw_slice = slice_from_raw_parts_mut(value.cast(), allocated_size);
414                // SAFETY: The pointer was returned from string_allocator, which used
415                // `Box::into_raw`, and we've got the appropriate size back from allocated_size.
416                let boxed_slice: Box<[u8]> = unsafe { Box::from_raw(raw_slice) };
417                assert_eq!(
418                    allocated_size,
419                    usize::try_from(value_size_bytes)
420                        .expect("APersistableBundle_getString returned negative value size")
421                        + 1
422                );
423                let c_string = CString::from_vec_with_nul(boxed_slice.into())
424                    .expect("APersistableBundle_getString returned string missing NUL byte");
425                let string = c_string
426                    .into_string()
427                    .expect("APersistableBundle_getString returned invalid UTF-8");
428                Ok(Some(string))
429            }
430        }
431    }
432
433    /// Gets the vector of `T` associated with the given key.
434    ///
435    /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
436    /// in the bundle.
437    ///
438    /// `get_func` should be one of the `APersistableBundle_get*Vector` functions from
439    /// `binder_ndk_sys`.
440    ///
441    /// # Safety
442    ///
443    /// `get_func` must only require that the pointers it takes are valid for the duration of the
444    /// call. It must allow a null pointer for the buffer, and must return the size in bytes of
445    /// buffer it requires. If it is given a non-null buffer pointer it must write that number of
446    /// bytes to the buffer, which must be a whole number of valid `T` values.
447    unsafe fn get_vec<T: Clone>(
448        &self,
449        key: &str,
450        default: T,
451        get_func: unsafe extern "C" fn(
452            *const APersistableBundle,
453            *const c_char,
454            *mut T,
455            i32,
456        ) -> i32,
457    ) -> Result<Option<Vec<T>>, NulError> {
458        let key = CString::new(key)?;
459        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
460        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
461        // to be valid for the lifetime of `key`. A null pointer is allowed for the buffer.
462        match unsafe { get_func(self.0.as_ptr(), key.as_ptr(), null_mut(), 0) } {
463            APERSISTABLEBUNDLE_KEY_NOT_FOUND => Ok(None),
464            APERSISTABLEBUNDLE_ALLOCATOR_FAILED => {
465                panic!("APersistableBundle_getStringVector failed to allocate string");
466            }
467            required_buffer_size => {
468                let mut value = vec![
469                    default;
470                    usize::try_from(required_buffer_size).expect(
471                        "APersistableBundle_get*Vector returned invalid size"
472                    ) / size_of::<T>()
473                ];
474                // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for
475                // the lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()`
476                // is guaranteed to be valid for the lifetime of `key`. The value buffer pointer is
477                // valid as it comes from the Vec we just allocated.
478                match unsafe {
479                    get_func(
480                        self.0.as_ptr(),
481                        key.as_ptr(),
482                        value.as_mut_ptr(),
483                        (value.len() * size_of::<T>()).try_into().unwrap(),
484                    )
485                } {
486                    APERSISTABLEBUNDLE_KEY_NOT_FOUND => {
487                        panic!("APersistableBundle_get*Vector failed to find key after first finding it");
488                    }
489                    APERSISTABLEBUNDLE_ALLOCATOR_FAILED => {
490                        panic!("APersistableBundle_getStringVector failed to allocate string");
491                    }
492                    _ => Ok(Some(value)),
493                }
494            }
495        }
496    }
497
498    /// Gets the boolean vector value associated with the given key.
499    ///
500    /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
501    /// in the bundle.
502    pub fn get_bool_vec(&self, key: &str) -> Result<Option<Vec<bool>>, NulError> {
503        // SAFETY: APersistableBundle_getBooleanVector fulfils all the safety requirements of
504        // `get_vec`.
505        unsafe { self.get_vec(key, Default::default(), APersistableBundle_getBooleanVector) }
506    }
507
508    /// Gets the i32 vector value associated with the given key.
509    ///
510    /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
511    /// in the bundle.
512    pub fn get_int_vec(&self, key: &str) -> Result<Option<Vec<i32>>, NulError> {
513        // SAFETY: APersistableBundle_getIntVector fulfils all the safety requirements of
514        // `get_vec`.
515        unsafe { self.get_vec(key, Default::default(), APersistableBundle_getIntVector) }
516    }
517
518    /// Gets the i64 vector value associated with the given key.
519    ///
520    /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
521    /// in the bundle.
522    pub fn get_long_vec(&self, key: &str) -> Result<Option<Vec<i64>>, NulError> {
523        // SAFETY: APersistableBundle_getLongVector fulfils all the safety requirements of
524        // `get_vec`.
525        unsafe { self.get_vec(key, Default::default(), APersistableBundle_getLongVector) }
526    }
527
528    /// Gets the f64 vector value associated with the given key.
529    ///
530    /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
531    /// in the bundle.
532    pub fn get_double_vec(&self, key: &str) -> Result<Option<Vec<f64>>, NulError> {
533        // SAFETY: APersistableBundle_getDoubleVector fulfils all the safety requirements of
534        // `get_vec`.
535        unsafe { self.get_vec(key, Default::default(), APersistableBundle_getDoubleVector) }
536    }
537
538    /// Gets the string vector value associated with the given key.
539    ///
540    /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
541    /// in the bundle.
542    pub fn get_string_vec(&self, key: &str) -> Result<Option<Vec<String>>, NulError> {
543        if let Some(value) =
544            // SAFETY: `get_string_vector_with_allocator` fulfils all the safety requirements of
545            // `get_vec`.
546            unsafe { self.get_vec(key, null_mut(), get_string_vector_with_allocator) }?
547        {
548            Ok(Some(
549                value
550                    .into_iter()
551                    .map(|s| {
552                        // SAFETY: The pointer was returned from `string_allocator`, which used
553                        // `Box::into_raw`, and `APersistableBundle_getStringVector` should have
554                        // written valid bytes to it including a NUL terminator in the last
555                        // position.
556                        let string_length = unsafe { CStr::from_ptr(s) }.count_bytes();
557                        let raw_slice = slice_from_raw_parts_mut(s.cast(), string_length + 1);
558                        // SAFETY: The pointer was returned from `string_allocator`, which used
559                        // `Box::into_raw`, and we've got the appropriate size back by checking the
560                        // length of the string.
561                        let boxed_slice: Box<[u8]> = unsafe { Box::from_raw(raw_slice) };
562                        let c_string = CString::from_vec_with_nul(boxed_slice.into()).expect(
563                            "APersistableBundle_getStringVector returned string missing NUL byte",
564                        );
565                        c_string
566                            .into_string()
567                            .expect("APersistableBundle_getStringVector returned invalid UTF-8")
568                    })
569                    .collect(),
570            ))
571        } else {
572            Ok(None)
573        }
574    }
575
576    /// Gets the `PersistableBundle` value associated with the given key.
577    ///
578    /// Returns an error if the key contains a NUL character, or `Ok(None)` if the key doesn't exist
579    /// in the bundle.
580    pub fn get_persistable_bundle(&self, key: &str) -> Result<Option<Self>, NulError> {
581        let key = CString::new(key)?;
582        let mut value = null_mut();
583        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
584        // lifetime of the `PersistableBundle`. The pointer returned by `key.as_ptr()` is guaranteed
585        // to be valid for the lifetime of `key`. The value pointer must be valid because it comes
586        // from a reference.
587        if unsafe {
588            APersistableBundle_getPersistableBundle(self.0.as_ptr(), key.as_ptr(), &mut value)
589        } {
590            Ok(Some(Self(NonNull::new(value).expect(
591                "APersistableBundle_getPersistableBundle returned true but didn't set outBundle",
592            ))))
593        } else {
594            Ok(None)
595        }
596    }
597
598    /// Calls the appropriate `APersistableBundle_get*Keys` function for the given `value_type`,
599    /// with our `string_allocator` and a null context pointer.
600    ///
601    /// # Safety
602    ///
603    /// `out_keys` must either be null or point to a buffer of at least `buffer_size_bytes` bytes,
604    /// properly aligned for `T`, and not otherwise accessed for the duration of the call.
605    unsafe fn get_keys_raw(
606        &self,
607        value_type: ValueType,
608        out_keys: *mut *mut c_char,
609        buffer_size_bytes: i32,
610    ) -> i32 {
611        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
612        // lifetime of the `PersistableBundle`. Our caller guarantees an appropriate value for
613        // `out_keys` and `buffer_size_bytes`.
614        unsafe {
615            match value_type {
616                ValueType::Boolean => APersistableBundle_getBooleanKeys(
617                    self.0.as_ptr(),
618                    out_keys,
619                    buffer_size_bytes,
620                    Some(string_allocator),
621                    null_mut(),
622                ),
623                ValueType::Integer => APersistableBundle_getIntKeys(
624                    self.0.as_ptr(),
625                    out_keys,
626                    buffer_size_bytes,
627                    Some(string_allocator),
628                    null_mut(),
629                ),
630                ValueType::Long => APersistableBundle_getLongKeys(
631                    self.0.as_ptr(),
632                    out_keys,
633                    buffer_size_bytes,
634                    Some(string_allocator),
635                    null_mut(),
636                ),
637                ValueType::Double => APersistableBundle_getDoubleKeys(
638                    self.0.as_ptr(),
639                    out_keys,
640                    buffer_size_bytes,
641                    Some(string_allocator),
642                    null_mut(),
643                ),
644                ValueType::String => APersistableBundle_getStringKeys(
645                    self.0.as_ptr(),
646                    out_keys,
647                    buffer_size_bytes,
648                    Some(string_allocator),
649                    null_mut(),
650                ),
651                ValueType::BooleanVector => APersistableBundle_getBooleanVectorKeys(
652                    self.0.as_ptr(),
653                    out_keys,
654                    buffer_size_bytes,
655                    Some(string_allocator),
656                    null_mut(),
657                ),
658                ValueType::IntegerVector => APersistableBundle_getIntVectorKeys(
659                    self.0.as_ptr(),
660                    out_keys,
661                    buffer_size_bytes,
662                    Some(string_allocator),
663                    null_mut(),
664                ),
665                ValueType::LongVector => APersistableBundle_getLongVectorKeys(
666                    self.0.as_ptr(),
667                    out_keys,
668                    buffer_size_bytes,
669                    Some(string_allocator),
670                    null_mut(),
671                ),
672                ValueType::DoubleVector => APersistableBundle_getDoubleVectorKeys(
673                    self.0.as_ptr(),
674                    out_keys,
675                    buffer_size_bytes,
676                    Some(string_allocator),
677                    null_mut(),
678                ),
679                ValueType::StringVector => APersistableBundle_getStringVectorKeys(
680                    self.0.as_ptr(),
681                    out_keys,
682                    buffer_size_bytes,
683                    Some(string_allocator),
684                    null_mut(),
685                ),
686                ValueType::PersistableBundle => APersistableBundle_getPersistableBundleKeys(
687                    self.0.as_ptr(),
688                    out_keys,
689                    buffer_size_bytes,
690                    Some(string_allocator),
691                    null_mut(),
692                ),
693            }
694        }
695    }
696
697    /// Gets all the keys associated with values of the given type.
698    pub fn keys_for_type(&self, value_type: ValueType) -> Vec<String> {
699        // SAFETY: A null pointer is allowed for the buffer.
700        match unsafe { self.get_keys_raw(value_type, null_mut(), 0) } {
701            APERSISTABLEBUNDLE_ALLOCATOR_FAILED => {
702                panic!("APersistableBundle_get*Keys failed to allocate string");
703            }
704            required_buffer_size => {
705                let required_buffer_size_usize = usize::try_from(required_buffer_size)
706                    .expect("APersistableBundle_get*Keys returned invalid size");
707                assert_eq!(required_buffer_size_usize % size_of::<*mut c_char>(), 0);
708                let mut keys =
709                    vec![null_mut(); required_buffer_size_usize / size_of::<*mut c_char>()];
710                // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for
711                // the lifetime of the `PersistableBundle`. The keys buffer pointer is valid as it
712                // comes from the Vec we just allocated.
713                if unsafe { self.get_keys_raw(value_type, keys.as_mut_ptr(), required_buffer_size) }
714                    == APERSISTABLEBUNDLE_ALLOCATOR_FAILED
715                {
716                    panic!("APersistableBundle_get*Keys failed to allocate string");
717                }
718                keys.into_iter()
719                    .map(|key| {
720                        // SAFETY: The pointer was returned from `string_allocator`, which used
721                        // `Box::into_raw`, and `APersistableBundle_getStringVector` should have
722                        // written valid bytes to it including a NUL terminator in the last
723                        // position.
724                        let string_length = unsafe { CStr::from_ptr(key) }.count_bytes();
725                        let raw_slice = slice_from_raw_parts_mut(key.cast(), string_length + 1);
726                        // SAFETY: The pointer was returned from `string_allocator`, which used
727                        // `Box::into_raw`, and we've got the appropriate size back by checking the
728                        // length of the string.
729                        let boxed_slice: Box<[u8]> = unsafe { Box::from_raw(raw_slice) };
730                        let c_string = CString::from_vec_with_nul(boxed_slice.into())
731                            .expect("APersistableBundle_get*Keys returned string missing NUL byte");
732                        c_string
733                            .into_string()
734                            .expect("APersistableBundle_get*Keys returned invalid UTF-8")
735                    })
736                    .collect()
737            }
738        }
739    }
740
741    /// Returns an iterator over all keys in the bundle, along with the type of their associated
742    /// value.
743    pub fn keys(&self) -> impl Iterator<Item = (String, ValueType)> + use<'_> {
744        [
745            ValueType::Boolean,
746            ValueType::Integer,
747            ValueType::Long,
748            ValueType::Double,
749            ValueType::String,
750            ValueType::BooleanVector,
751            ValueType::IntegerVector,
752            ValueType::LongVector,
753            ValueType::DoubleVector,
754            ValueType::StringVector,
755            ValueType::PersistableBundle,
756        ]
757        .iter()
758        .flat_map(|value_type| {
759            self.keys_for_type(*value_type).into_iter().map(|key| (key, *value_type))
760        })
761    }
762}
763
764/// Wrapper around `APersistableBundle_getStringVector` to pass `string_allocator` and a null
765/// context pointer.
766///
767/// # Safety
768///
769/// * `bundle` must point to a valid `APersistableBundle` which is not modified for the duration of
770///   the call.
771/// * `key` must point to a valid NUL-terminated C string.
772/// * `buffer` must either be null or point to a buffer of at least `buffer_size_bytes` bytes,
773///   properly aligned for `T`, and not otherwise accessed for the duration of the call.
774unsafe extern "C" fn get_string_vector_with_allocator(
775    bundle: *const APersistableBundle,
776    key: *const c_char,
777    buffer: *mut *mut c_char,
778    buffer_size_bytes: i32,
779) -> i32 {
780    // SAFETY: The safety requirements are all guaranteed by our caller according to the safety
781    // documentation above.
782    unsafe {
783        APersistableBundle_getStringVector(
784            bundle,
785            key,
786            buffer,
787            buffer_size_bytes,
788            Some(string_allocator),
789            null_mut(),
790        )
791    }
792}
793
794// SAFETY: The underlying *APersistableBundle can be moved between threads.
795unsafe impl Send for PersistableBundle {}
796
797// SAFETY: The underlying *APersistableBundle can be read from multiple threads, and we require
798// `&mut PersistableBundle` for any operations which mutate it.
799unsafe impl Sync for PersistableBundle {}
800
801impl Default for PersistableBundle {
802    fn default() -> Self {
803        Self::new()
804    }
805}
806
807impl Drop for PersistableBundle {
808    fn drop(&mut self) {
809        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
810        // lifetime of this `PersistableBundle`.
811        unsafe { APersistableBundle_delete(self.0.as_ptr()) };
812    }
813}
814
815impl Clone for PersistableBundle {
816    fn clone(&self) -> Self {
817        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
818        // lifetime of the `PersistableBundle`.
819        let duplicate = unsafe { APersistableBundle_dup(self.0.as_ptr()) };
820        Self(NonNull::new(duplicate).expect("Duplicated APersistableBundle was null"))
821    }
822}
823
824impl PartialEq for PersistableBundle {
825    fn eq(&self, other: &Self) -> bool {
826        // SAFETY: The wrapped `APersistableBundle` pointers are guaranteed to be valid for the
827        // lifetime of the `PersistableBundle`s.
828        unsafe { APersistableBundle_isEqual(self.0.as_ptr(), other.0.as_ptr()) }
829    }
830}
831
832impl UnstructuredParcelable for PersistableBundle {
833    fn write_to_parcel(&self, parcel: &mut BorrowedParcel) -> Result<(), StatusCode> {
834        let status =
835        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
836        // lifetime of the `PersistableBundle`. `parcel.as_native_mut()` always returns a valid
837        // parcel pointer.
838            unsafe { APersistableBundle_writeToParcel(self.0.as_ptr(), parcel.as_native_mut()) };
839        status_result(status)
840    }
841
842    fn from_parcel(parcel: &BorrowedParcel) -> Result<Self, StatusCode> {
843        let mut bundle = null_mut();
844
845        // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
846        // lifetime of the `PersistableBundle`. `parcel.as_native()` always returns a valid parcel
847        // pointer.
848        let status = unsafe { APersistableBundle_readFromParcel(parcel.as_native(), &mut bundle) };
849        status_result(status)?;
850
851        Ok(Self(NonNull::new(bundle).expect(
852            "APersistableBundle_readFromParcel returned success but didn't allocate bundle",
853        )))
854    }
855}
856
857/// Allocates a boxed slice of the given size in bytes, returns a pointer to it and writes its size
858/// to `*context`.
859///
860/// # Safety
861///
862/// `context` must either be null or point to a `usize` to which we can write.
863unsafe extern "C" fn string_allocator(size: i32, context: *mut c_void) -> *mut c_char {
864    let Ok(size) = size.try_into() else {
865        return null_mut();
866    };
867    let Ok(boxed_slice) = <[c_char]>::new_box_zeroed_with_elems(size) else {
868        return null_mut();
869    };
870    if !context.is_null() {
871        // SAFETY: The caller promised that `context` is either null or points to a `usize` to which
872        // we can write, and we just checked that it's not null.
873        unsafe {
874            *context.cast::<usize>() = size;
875        }
876    }
877    Box::into_raw(boxed_slice).cast()
878}
879
880impl_deserialize_for_unstructured_parcelable!(PersistableBundle);
881impl_serialize_for_unstructured_parcelable!(PersistableBundle);
882
883/// The types which may be stored as values in a [`PersistableBundle`].
884#[derive(Clone, Copy, Debug, Eq, PartialEq)]
885pub enum ValueType {
886    /// A `bool`.
887    Boolean,
888    /// An `i32`.
889    Integer,
890    /// An `i64`.
891    Long,
892    /// An `f64`.
893    Double,
894    /// A string.
895    String,
896    /// A vector of `bool`s.
897    BooleanVector,
898    /// A vector of `i32`s.
899    IntegerVector,
900    /// A vector of `i64`s.
901    LongVector,
902    /// A vector of `f64`s.
903    DoubleVector,
904    /// A vector of strings.
905    StringVector,
906    /// A nested `PersistableBundle`.
907    PersistableBundle,
908}
909
910#[cfg(test)]
911mod test {
912    use super::*;
913
914    #[test]
915    fn create_delete() {
916        let bundle = PersistableBundle::new();
917        drop(bundle);
918    }
919
920    #[test]
921    fn duplicate_equal() {
922        let bundle = PersistableBundle::new();
923        let duplicate = bundle.clone();
924        assert_eq!(bundle, duplicate);
925    }
926
927    #[test]
928    fn get_empty() {
929        let bundle = PersistableBundle::new();
930        assert_eq!(bundle.get_bool("foo"), Ok(None));
931        assert_eq!(bundle.get_int("foo"), Ok(None));
932        assert_eq!(bundle.get_long("foo"), Ok(None));
933        assert_eq!(bundle.get_double("foo"), Ok(None));
934        assert_eq!(bundle.get_bool_vec("foo"), Ok(None));
935        assert_eq!(bundle.get_int_vec("foo"), Ok(None));
936        assert_eq!(bundle.get_long_vec("foo"), Ok(None));
937        assert_eq!(bundle.get_double_vec("foo"), Ok(None));
938        assert_eq!(bundle.get_string("foo"), Ok(None));
939    }
940
941    #[test]
942    fn remove_empty() {
943        let mut bundle = PersistableBundle::new();
944        assert_eq!(bundle.remove("foo"), Ok(false));
945    }
946
947    #[test]
948    fn insert_get_primitives() {
949        let mut bundle = PersistableBundle::new();
950
951        assert_eq!(bundle.insert_bool("bool", true), Ok(()));
952        assert_eq!(bundle.insert_int("int", 42), Ok(()));
953        assert_eq!(bundle.insert_long("long", 66), Ok(()));
954        assert_eq!(bundle.insert_double("double", 123.4), Ok(()));
955
956        assert_eq!(bundle.get_bool("bool"), Ok(Some(true)));
957        assert_eq!(bundle.get_int("int"), Ok(Some(42)));
958        assert_eq!(bundle.get_long("long"), Ok(Some(66)));
959        assert_eq!(bundle.get_double("double"), Ok(Some(123.4)));
960        assert_eq!(bundle.size(), 4);
961
962        // Getting the wrong type should return nothing.
963        assert_eq!(bundle.get_int("bool"), Ok(None));
964        assert_eq!(bundle.get_long("bool"), Ok(None));
965        assert_eq!(bundle.get_double("bool"), Ok(None));
966        assert_eq!(bundle.get_bool("int"), Ok(None));
967        assert_eq!(bundle.get_long("int"), Ok(None));
968        assert_eq!(bundle.get_double("int"), Ok(None));
969        assert_eq!(bundle.get_bool("long"), Ok(None));
970        assert_eq!(bundle.get_int("long"), Ok(None));
971        assert_eq!(bundle.get_double("long"), Ok(None));
972        assert_eq!(bundle.get_bool("double"), Ok(None));
973        assert_eq!(bundle.get_int("double"), Ok(None));
974        assert_eq!(bundle.get_long("double"), Ok(None));
975
976        // If they are removed they should no longer be present.
977        assert_eq!(bundle.remove("bool"), Ok(true));
978        assert_eq!(bundle.remove("int"), Ok(true));
979        assert_eq!(bundle.remove("long"), Ok(true));
980        assert_eq!(bundle.remove("double"), Ok(true));
981        assert_eq!(bundle.get_bool("bool"), Ok(None));
982        assert_eq!(bundle.get_int("int"), Ok(None));
983        assert_eq!(bundle.get_long("long"), Ok(None));
984        assert_eq!(bundle.get_double("double"), Ok(None));
985        assert_eq!(bundle.size(), 0);
986    }
987
988    #[test]
989    fn insert_get_string() {
990        let mut bundle = PersistableBundle::new();
991
992        assert_eq!(bundle.insert_string("string", "foo"), Ok(()));
993        assert_eq!(bundle.insert_string("empty", ""), Ok(()));
994        assert_eq!(bundle.size(), 2);
995
996        assert_eq!(bundle.get_string("string"), Ok(Some("foo".to_string())));
997        assert_eq!(bundle.get_string("empty"), Ok(Some("".to_string())));
998    }
999
1000    #[test]
1001    fn insert_get_vec() {
1002        let mut bundle = PersistableBundle::new();
1003
1004        assert_eq!(bundle.insert_bool_vec("bool", &[]), Ok(()));
1005        assert_eq!(bundle.insert_int_vec("int", &[42]), Ok(()));
1006        assert_eq!(bundle.insert_long_vec("long", &[66, 67, 68]), Ok(()));
1007        assert_eq!(bundle.insert_double_vec("double", &[123.4]), Ok(()));
1008        assert_eq!(bundle.insert_string_vec("string", &["foo", "bar", "baz"]), Ok(()));
1009        assert_eq!(
1010            bundle.insert_string_vec(
1011                "string",
1012                &[&"foo".to_string(), &"bar".to_string(), &"baz".to_string()]
1013            ),
1014            Ok(())
1015        );
1016        assert_eq!(
1017            bundle.insert_string_vec(
1018                "string",
1019                &["foo".to_string(), "bar".to_string(), "baz".to_string()]
1020            ),
1021            Ok(())
1022        );
1023
1024        assert_eq!(bundle.size(), 5);
1025
1026        assert_eq!(bundle.get_bool_vec("bool"), Ok(Some(vec![])));
1027        assert_eq!(bundle.get_int_vec("int"), Ok(Some(vec![42])));
1028        assert_eq!(bundle.get_long_vec("long"), Ok(Some(vec![66, 67, 68])));
1029        assert_eq!(bundle.get_double_vec("double"), Ok(Some(vec![123.4])));
1030        assert_eq!(
1031            bundle.get_string_vec("string"),
1032            Ok(Some(vec!["foo".to_string(), "bar".to_string(), "baz".to_string()]))
1033        );
1034    }
1035
1036    #[test]
1037    fn insert_get_bundle() {
1038        let mut bundle = PersistableBundle::new();
1039
1040        let mut sub_bundle = PersistableBundle::new();
1041        assert_eq!(sub_bundle.insert_int("int", 42), Ok(()));
1042        assert_eq!(sub_bundle.size(), 1);
1043        assert_eq!(bundle.insert_persistable_bundle("bundle", &sub_bundle), Ok(()));
1044
1045        assert_eq!(bundle.get_persistable_bundle("bundle"), Ok(Some(sub_bundle)));
1046    }
1047
1048    #[test]
1049    fn get_keys() {
1050        let mut bundle = PersistableBundle::new();
1051
1052        assert_eq!(bundle.keys_for_type(ValueType::Boolean), Vec::<String>::new());
1053        assert_eq!(bundle.keys_for_type(ValueType::Integer), Vec::<String>::new());
1054        assert_eq!(bundle.keys_for_type(ValueType::StringVector), Vec::<String>::new());
1055
1056        assert_eq!(bundle.insert_bool("bool1", false), Ok(()));
1057        assert_eq!(bundle.insert_bool("bool2", true), Ok(()));
1058        assert_eq!(bundle.insert_int("int", 42), Ok(()));
1059
1060        assert_eq!(
1061            bundle.keys_for_type(ValueType::Boolean),
1062            vec!["bool1".to_string(), "bool2".to_string()]
1063        );
1064        assert_eq!(bundle.keys_for_type(ValueType::Integer), vec!["int".to_string()]);
1065        assert_eq!(bundle.keys_for_type(ValueType::StringVector), Vec::<String>::new());
1066
1067        assert_eq!(
1068            bundle.keys().collect::<Vec<_>>(),
1069            vec![
1070                ("bool1".to_string(), ValueType::Boolean),
1071                ("bool2".to_string(), ValueType::Boolean),
1072                ("int".to_string(), ValueType::Integer),
1073            ]
1074        );
1075    }
1076}