Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c2df7a44 authored by Matthew Maurer's avatar Matthew Maurer Committed by Automerger Merge Worker
Browse files

Merge changes Ia2f891c2,Ibbe111b0 am: 53f92888 am: fcad4767 am: a39c2da5...

Merge changes Ia2f891c2,Ibbe111b0 am: 53f92888 am: fcad4767 am: a39c2da5 am: 79642dd9 am: 824a156a

Original change: https://android-review.googlesource.com/c/platform/frameworks/native/+/1397051

Change-Id: Ied921f201ba8f6602cad78f16c1b7ff8c7b0d695
parents 67c30697 824a156a
Loading
Loading
Loading
Loading
+17 −5
Original line number Diff line number Diff line
@@ -3,12 +3,24 @@ rust_library {
    crate_name: "binder",
    srcs: ["src/lib.rs"],
    shared_libs: [
        "libbinder_ndk",
        "libutils",
    ],
    rustlibs: [
        "liblibc",
        "libbinder_ndk_bindgen",
        "libbinder_ndk_sys",
    ],
    host_supported: true,
}

rust_library {
    name: "libbinder_ndk_sys",
    crate_name: "binder_ndk_sys",
    srcs: [
        "sys/lib.rs",
        ":libbinder_ndk_bindgen",
    ],
    shared_libs: [
        "libbinder_ndk",
    ],
    host_supported: true,
}
@@ -16,8 +28,8 @@ rust_library {
rust_bindgen {
    name: "libbinder_ndk_bindgen",
    crate_name: "binder_ndk_bindgen",
    wrapper_src: "BinderBindings.h",
    source_stem: "ndk_bindings",
    wrapper_src: "sys/BinderBindings.h",
    source_stem: "bindings",
    cflags: [
        "-x c++",
    ],
@@ -69,6 +81,6 @@ rust_test {
    ],
    rustlibs: [
        "liblibc",
        "libbinder_ndk_bindgen",
        "libbinder_ndk_sys",
    ],
}
+0 −8
Original line number Diff line number Diff line
@@ -43,14 +43,6 @@ pub fn status_result(status: status_t) -> Result<()> {
    }
}

// impl Display for StatusCode {
//     fn fmt(&self, f: &mut Formatter) -> FmtResult {
//         write!(f, "StatusCode::{:?}", self)
//     }
// }

// impl error::Error for StatusCode {}

fn parse_status_code(code: i32) -> StatusCode {
    match code {
        e if e == StatusCode::OK as i32 => StatusCode::OK,
+1 −1
Original line number Diff line number Diff line
@@ -102,7 +102,7 @@ mod error;
mod native;
mod state;

use binder_ndk_bindgen as sys;
use binder_ndk_sys as sys;

pub mod parcel;

+95 −0
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ use crate::error::{status_result, Result, StatusCode};
use crate::proxy::SpIBinder;
use crate::sys;

use std::cell::RefCell;
use std::convert::TryInto;
use std::mem::ManuallyDrop;
use std::ptr;
@@ -117,6 +118,55 @@ impl Parcel {
        }
    }

    /// Perform a series of writes to the `Parcel`, prepended with the length
    /// (in bytes) of the written data.
    ///
    /// The length `0i32` will be written to the parcel first, followed by the
    /// writes performed by the callback. The initial length will then be
    /// updated to the length of all data written by the callback, plus the
    /// size of the length elemement itself (4 bytes).
    ///
    /// # Examples
    ///
    /// After the following call:
    ///
    /// ```
    /// # use binder::{Binder, Interface, Parcel};
    /// # let mut parcel = Parcel::Owned(std::ptr::null_mut());
    /// parcel.sized_write(|subparcel| {
    ///     subparcel.write(&1u32)?;
    ///     subparcel.write(&2u32)?;
    ///     subparcel.write(&3u32)
    /// });
    /// ```
    ///
    /// `parcel` will contain the following:
    ///
    /// ```ignore
    /// [16i32, 1u32, 2u32, 3u32]
    /// ```
    pub fn sized_write<F>(&mut self, f: F) -> Result<()>
    where for<'a>
        F: Fn(&'a WritableSubParcel<'a>) -> Result<()>
    {
        let start = self.get_data_position();
        self.write(&0i32)?;
        {
            let subparcel = WritableSubParcel(RefCell::new(self));
            f(&subparcel)?;
        }
        let end = self.get_data_position();
        unsafe {
            self.set_data_position(start)?;
        }
        assert!(end >= start);
        self.write(&(end - start))?;
        unsafe {
            self.set_data_position(end)?;
        }
        Ok(())
    }

    /// Returns the current position in the parcel data.
    pub fn get_data_position(&self) -> i32 {
        unsafe {
@@ -143,6 +193,16 @@ impl Parcel {
    }
}

/// A segment of a writable parcel, used for [`Parcel::sized_write`].
pub struct WritableSubParcel<'a>(RefCell<&'a mut Parcel>);

impl<'a> WritableSubParcel<'a> {
    /// Write a type that implements [`Serialize`] to the sub-parcel.
    pub fn write<S: Serialize + ?Sized>(&self, parcelable: &S) -> Result<()> {
        parcelable.serialize(&mut *self.0.borrow_mut())
    }
}

// Data deserialization methods
impl Parcel {
    /// Attempt to read a type that implements [`Deserialize`] from this
@@ -445,3 +505,38 @@ fn test_utf8_utf16_conversions() {
    );
    assert_eq!(parcel.read::<Vec<String>>().unwrap(), [s1, s2, s3]);
}

#[test]
fn test_sized_write() {
    use crate::binder::Interface;
    use crate::native::Binder;

    let mut service = Binder::new(()).as_binder();
    let mut parcel = Parcel::new_for_test(&mut service).unwrap();
    let start = parcel.get_data_position();

    let arr = [1i32, 2i32, 3i32];

    parcel.sized_write(|subparcel| {
        subparcel.write(&arr[..])
    }).expect("Could not perform sized write");

    // i32 sub-parcel length + i32 array length + 3 i32 elements
    let expected_len = 20i32;

    assert_eq!(parcel.get_data_position(), start + expected_len);

    unsafe {
        parcel.set_data_position(start).unwrap();
    }

    assert_eq!(
        expected_len,
        parcel.read().unwrap(),
    );

    assert_eq!(
        parcel.read::<Vec<i32>>().unwrap(),
        &arr,
    );
}
+20 −0
Original line number Diff line number Diff line
@@ -122,6 +122,14 @@ impl AssociateClass for SpIBinder {
    }
}

impl PartialEq for SpIBinder {
    fn eq(&self, other: &Self) -> bool {
        ptr::eq(self.0, other.0)
    }
}

impl Eq for SpIBinder {}

impl Clone for SpIBinder {
    fn clone(&self) -> Self {
        unsafe {
@@ -363,6 +371,18 @@ impl WpIBinder {
        assert!(!ptr.is_null());
        Self(ptr)
    }

    /// Promote this weak reference to a strong reference to the binder object.
    pub fn promote(&self) -> Option<SpIBinder> {
        unsafe {
            // Safety: `WpIBinder` always contains a valid weak reference, so we
            // can pass this pointer to `AIBinder_Weak_promote`. Returns either
            // null or an AIBinder owned by the caller, both of which are valid
            // to pass to `SpIBinder::from_raw`.
            let ptr = sys::AIBinder_Weak_promote(self.0);
            SpIBinder::from_raw(ptr)
        }
    }
}

/// Rust wrapper around DeathRecipient objects.
Loading