1414 * limitations under the License.
1515 */
1616
17+ use 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+ } ;
1723use binder_ndk_sys:: {
1824 APersistableBundle , APersistableBundle_delete , APersistableBundle_dup ,
19- APersistableBundle_isEqual , APersistableBundle_new , APersistableBundle_size ,
25+ APersistableBundle_isEqual , APersistableBundle_new , APersistableBundle_readFromParcel ,
26+ APersistableBundle_size , APersistableBundle_writeToParcel ,
2027} ;
21- use std:: ptr:: NonNull ;
28+ use std:: ptr:: { null_mut , NonNull } ;
2229
2330/// A mapping from string keys to values of various types.
2431#[ derive( Debug ) ]
@@ -42,6 +49,13 @@ impl PersistableBundle {
4249 }
4350}
4451
52+ // SAFETY: The underlying *APersistableBundle can be moved between threads.
53+ unsafe impl Send for PersistableBundle { }
54+
55+ // SAFETY: The underlying *APersistableBundle can be read from multiple threads, and we require
56+ // `&mut PersistableBundle` for any operations which mutate it.
57+ unsafe impl Sync for PersistableBundle { }
58+
4559impl Default for PersistableBundle {
4660 fn default ( ) -> Self {
4761 Self :: new ( )
@@ -73,6 +87,34 @@ impl PartialEq for PersistableBundle {
7387 }
7488}
7589
90+ impl UnstructuredParcelable for PersistableBundle {
91+ fn write_to_parcel ( & self , parcel : & mut BorrowedParcel ) -> Result < ( ) , StatusCode > {
92+ let status =
93+ // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
94+ // lifetime of the `PersistableBundle`. `parcel.as_native_mut()` always returns a valid
95+ // parcel pointer.
96+ unsafe { APersistableBundle_writeToParcel ( self . 0 . as_ptr ( ) , parcel. as_native_mut ( ) ) } ;
97+ status_result ( status)
98+ }
99+
100+ fn from_parcel ( parcel : & BorrowedParcel ) -> Result < Self , StatusCode > {
101+ let mut bundle = null_mut ( ) ;
102+
103+ // SAFETY: The wrapped `APersistableBundle` pointer is guaranteed to be valid for the
104+ // lifetime of the `PersistableBundle`. `parcel.as_native()` always returns a valid parcel
105+ // pointer.
106+ let status = unsafe { APersistableBundle_readFromParcel ( parcel. as_native ( ) , & mut bundle) } ;
107+ status_result ( status) ?;
108+
109+ Ok ( Self ( NonNull :: new ( bundle) . expect (
110+ "APersistableBundle_readFromParcel returned success but didn't allocate bundle" ,
111+ ) ) )
112+ }
113+ }
114+
115+ impl_deserialize_for_unstructured_parcelable ! ( PersistableBundle ) ;
116+ impl_serialize_for_unstructured_parcelable ! ( PersistableBundle ) ;
117+
76118#[ cfg( test) ]
77119mod test {
78120 use super :: * ;
0 commit comments