diff --git a/libs/binder/rust/Android.bp b/libs/binder/rust/Android.bp
new file mode 100644
index 0000000..16811ee
--- /dev/null
+++ b/libs/binder/rust/Android.bp
@@ -0,0 +1,74 @@
+rust_library {
+    name: "libbinder_rs",
+    crate_name: "binder",
+    srcs: ["src/lib.rs"],
+    shared_libs: [
+        "libbinder_ndk",
+        "libutils",
+    ],
+    rustlibs: [
+        "liblibc",
+        "libbinder_ndk_bindgen",
+    ],
+    host_supported: true,
+}
+
+rust_bindgen {
+    name: "libbinder_ndk_bindgen",
+    crate_name: "binder_ndk_bindgen",
+    wrapper_src: "BinderBindings.h",
+    source_stem: "ndk_bindings",
+    cflags: [
+        "-x c++",
+    ],
+    bindgen_flags: [
+        // Unfortunately the only way to specify the rust_non_exhaustive enum
+        // style for a type is to make it the default
+        "--default-enum-style", "rust_non_exhaustive",
+        // and then specify constified enums for the enums we don't want
+        // rustified
+        "--constified-enum", "android::c_interface::consts::.*",
+
+        "--whitelist-type", "android::c_interface::.*",
+        "--whitelist-type", "AStatus",
+        "--whitelist-type", "AIBinder_Class",
+        "--whitelist-type", "AIBinder",
+        "--whitelist-type", "AIBinder_Weak",
+        "--whitelist-type", "AIBinder_DeathRecipient",
+        "--whitelist-type", "AParcel",
+        "--whitelist-type", "binder_status_t",
+        "--whitelist-function", ".*",
+    ],
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+    host_supported: true,
+
+    // Currently necessary for host builds
+    // TODO(b/31559095): bionic on host should define this
+    target: {
+        host: {
+            cflags: [
+                "-D__INTRODUCED_IN(n)=",
+                "-D__assert(a,b,c)=",
+                // We want all the APIs to be available on the host.
+                "-D__ANDROID_API__=10000",
+            ],
+        },
+    },
+}
+
+rust_test {
+    name: "libbinder_rs-internal_test",
+    crate_name: "binder",
+    srcs: ["src/lib.rs"],
+    test_suites: ["general-tests"],
+    auto_gen_config: true,
+    shared_libs: [
+        "libbinder_ndk",
+    ],
+    rustlibs: [
+        "liblibc",
+        "libbinder_ndk_bindgen",
+    ],
+}
diff --git a/libs/binder/rust/BinderBindings.h b/libs/binder/rust/BinderBindings.h
new file mode 100644
index 0000000..c7a06d9
--- /dev/null
+++ b/libs/binder/rust/BinderBindings.h
@@ -0,0 +1,86 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <android/binder_ibinder.h>
+#include <android/binder_manager.h>
+#include <android/binder_parcel.h>
+#include <android/binder_process.h>
+#include <android/binder_shell.h>
+#include <android/binder_status.h>
+
+namespace android {
+
+namespace c_interface {
+
+// Expose error codes from anonymous enum in binder_status.h
+enum StatusCode {
+    OK = STATUS_OK,
+    UNKNOWN_ERROR = STATUS_UNKNOWN_ERROR,
+    NO_MEMORY = STATUS_NO_MEMORY,
+    INVALID_OPERATION = STATUS_INVALID_OPERATION,
+    BAD_VALUE = STATUS_BAD_VALUE,
+    BAD_TYPE = STATUS_BAD_TYPE,
+    NAME_NOT_FOUND = STATUS_NAME_NOT_FOUND,
+    PERMISSION_DENIED = STATUS_PERMISSION_DENIED,
+    NO_INIT = STATUS_NO_INIT,
+    ALREADY_EXISTS = STATUS_ALREADY_EXISTS,
+    DEAD_OBJECT = STATUS_DEAD_OBJECT,
+    FAILED_TRANSACTION = STATUS_FAILED_TRANSACTION,
+    BAD_INDEX = STATUS_BAD_INDEX,
+    NOT_ENOUGH_DATA = STATUS_NOT_ENOUGH_DATA,
+    WOULD_BLOCK = STATUS_WOULD_BLOCK,
+    TIMED_OUT = STATUS_TIMED_OUT,
+    UNKNOWN_TRANSACTION = STATUS_UNKNOWN_TRANSACTION,
+    FDS_NOT_ALLOWED = STATUS_FDS_NOT_ALLOWED,
+    UNEXPECTED_NULL = STATUS_UNEXPECTED_NULL,
+};
+
+// Expose exception codes from anonymous enum in binder_status.h
+enum ExceptionCode {
+    NONE = EX_NONE,
+    SECURITY = EX_SECURITY,
+    BAD_PARCELABLE = EX_BAD_PARCELABLE,
+    ILLEGAL_ARGUMENT = EX_ILLEGAL_ARGUMENT,
+    NULL_POINTER = EX_NULL_POINTER,
+    ILLEGAL_STATE = EX_ILLEGAL_STATE,
+    NETWORK_MAIN_THREAD = EX_NETWORK_MAIN_THREAD,
+    UNSUPPORTED_OPERATION = EX_UNSUPPORTED_OPERATION,
+    SERVICE_SPECIFIC = EX_SERVICE_SPECIFIC,
+    PARCELABLE = EX_PARCELABLE,
+
+    /**
+     * This is special, and indicates to native binder proxies that the
+     * transaction has failed at a low level.
+     */
+    TRANSACTION_FAILED = EX_TRANSACTION_FAILED,
+};
+
+namespace consts {
+
+enum {
+    FIRST_CALL_TRANSACTION = FIRST_CALL_TRANSACTION,
+    LAST_CALL_TRANSACTION = LAST_CALL_TRANSACTION,
+};
+
+enum {
+    FLAG_ONEWAY = FLAG_ONEWAY,
+};
+
+} // namespace consts
+
+} // namespace c_interface
+
+} // namespace android
diff --git a/libs/binder/rust/TEST_MAPPING b/libs/binder/rust/TEST_MAPPING
new file mode 100644
index 0000000..4470e17
--- /dev/null
+++ b/libs/binder/rust/TEST_MAPPING
@@ -0,0 +1,10 @@
+{
+  "presubmit": [
+    {
+      "name": "libbinder_rs-internal_test"
+    },
+    {
+      "name": "rustBinderTest"
+    }
+  ]
+}
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
new file mode 100644
index 0000000..f5e7509
--- /dev/null
+++ b/libs/binder/rust/src/binder.rs
@@ -0,0 +1,585 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! Trait definitions for binder objects
+
+use crate::error::{status_t, Result};
+use crate::parcel::Parcel;
+use crate::proxy::{DeathRecipient, SpIBinder};
+use crate::sys;
+
+use std::ffi::{c_void, CString};
+use std::os::unix::io::AsRawFd;
+use std::ptr;
+
+/// Binder action to perform.
+///
+/// This must be a number between [`IBinder::FIRST_CALL_TRANSACTION`] and
+/// [`IBinder::LAST_CALL_TRANSACTION`].
+pub type TransactionCode = u32;
+
+/// Additional operation flags.
+///
+/// Can be either 0 for a normal RPC, or [`IBinder::FLAG_ONEWAY`] for a
+/// one-way RPC.
+pub type TransactionFlags = u32;
+
+/// Super-trait for Binder interfaces.
+///
+/// This trait allows conversion of a Binder interface trait object into an
+/// IBinder object for IPC calls. All Binder remotable interface (i.e. AIDL
+/// interfaces) must implement this trait.
+///
+/// This is equivalent `IInterface` in C++.
+pub trait Interface {
+    /// Convert this binder object into a generic [`SpIBinder`] reference.
+    fn as_binder(&self) -> SpIBinder {
+        panic!("This object was not a Binder object and cannot be converted into an SpIBinder.")
+    }
+}
+
+/// A local service that can be remotable via Binder.
+///
+/// An object that implement this interface made be made into a Binder service
+/// via `Binder::new(object)`.
+///
+/// This is a low-level interface that should normally be automatically
+/// generated from AIDL via the [`declare_binder_interface!`] macro. When using
+/// the AIDL backend, users need only implement the high-level AIDL-defined
+/// interface. The AIDL compiler then generates a container struct that wraps
+/// the user-defined service and implements `Remotable`.
+pub trait Remotable: Sync {
+    /// The Binder interface descriptor string.
+    ///
+    /// This string is a unique identifier for a Binder interface, and should be
+    /// the same between all implementations of that interface.
+    fn get_descriptor() -> &'static str;
+
+    /// Handle and reply to a request to invoke a transaction on this object.
+    ///
+    /// `reply` may be [`None`] if the sender does not expect a reply.
+    fn on_transact(&self, code: TransactionCode, data: &Parcel, reply: &mut Parcel) -> Result<()>;
+
+    /// Retrieve the class of this remote object.
+    ///
+    /// This method should always return the same InterfaceClass for the same
+    /// type.
+    fn get_class() -> InterfaceClass;
+}
+
+/// Interface of binder local or remote objects.
+///
+/// This trait corresponds to the interface of the C++ `IBinder` class.
+pub trait IBinder {
+    /// First transaction code available for user commands (inclusive)
+    const FIRST_CALL_TRANSACTION: TransactionCode = sys::FIRST_CALL_TRANSACTION;
+    /// Last transaction code available for user commands (inclusive)
+    const LAST_CALL_TRANSACTION: TransactionCode = sys::LAST_CALL_TRANSACTION;
+
+    /// Corresponds to TF_ONE_WAY -- an asynchronous call.
+    const FLAG_ONEWAY: TransactionFlags = sys::FLAG_ONEWAY;
+
+    /// Is this object still alive?
+    fn is_binder_alive(&self) -> bool;
+
+    /// Send a ping transaction to this object
+    fn ping_binder(&mut self) -> Result<()>;
+
+    /// Dump this object to the given file handle
+    fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()>;
+
+    /// Get a new interface that exposes additional extension functionality, if
+    /// available.
+    fn get_extension(&mut self) -> Result<Option<SpIBinder>>;
+
+    /// Perform a generic operation with the object.
+    ///
+    /// # Arguments
+    /// * `code` - Transaction code for the operation
+    /// * `data` - [`Parcel`] with input data
+    /// * `reply` - Optional [`Parcel`] for reply data
+    /// * `flags` - Transaction flags, e.g. marking the transaction as
+    /// asynchronous ([`FLAG_ONEWAY`](IBinder::FLAG_ONEWAY))
+    fn transact<F: FnOnce(&mut Parcel) -> Result<()>>(
+        &self,
+        code: TransactionCode,
+        flags: TransactionFlags,
+        input_callback: F,
+    ) -> Result<Parcel>;
+
+    /// Register the recipient for a notification if this binder
+    /// goes away. If this binder object unexpectedly goes away
+    /// (typically because its hosting process has been killed),
+    /// then DeathRecipient::binder_died() will be called with a reference
+    /// to this.
+    ///
+    /// You will only receive death notifications for remote binders,
+    /// as local binders by definition can't die without you dying as well.
+    /// Trying to use this function on a local binder will result in an
+    /// INVALID_OPERATION code being returned and nothing happening.
+    ///
+    /// This link always holds a weak reference to its recipient.
+    ///
+    /// You will only receive a weak reference to the dead
+    /// binder. You should not try to promote this to a strong reference.
+    /// (Nor should you need to, as there is nothing useful you can
+    /// directly do with it now that it has passed on.)
+    fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
+
+    /// Remove a previously registered death notification.
+    /// The recipient will no longer be called if this object
+    /// dies.
+    fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()>;
+}
+
+/// Opaque reference to the type of a Binder interface.
+///
+/// This object encapsulates the Binder interface descriptor string, along with
+/// the binder transaction callback, if the class describes a local service.
+///
+/// A Binder remotable object may only have a single interface class, and any
+/// given object can only be associated with one class. Two objects with
+/// different classes are incompatible, even if both classes have the same
+/// interface descriptor.
+#[derive(Copy, Clone, PartialEq, Eq)]
+pub struct InterfaceClass(*const sys::AIBinder_Class);
+
+impl InterfaceClass {
+    /// Get a Binder NDK `AIBinder_Class` pointer for this object type.
+    ///
+    /// Note: the returned pointer will not be constant. Calling this method
+    /// multiple times for the same type will result in distinct class
+    /// pointers. A static getter for this value is implemented in
+    /// [`declare_binder_interface!`].
+    pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
+        let descriptor = CString::new(I::get_descriptor()).unwrap();
+        let ptr = unsafe {
+            // Safety: `AIBinder_Class_define` expects a valid C string, and
+            // three valid callback functions, all non-null pointers. The C
+            // string is copied and need not be valid for longer than the call,
+            // so we can drop it after the call. We can safely assign null to
+            // the onDump and handleShellCommand callbacks as long as the class
+            // pointer was non-null. Rust None for a Option<fn> is guaranteed to
+            // be a NULL pointer. Rust retains ownership of the pointer after it
+            // is defined.
+            let class = sys::AIBinder_Class_define(
+                descriptor.as_ptr(),
+                Some(I::on_create),
+                Some(I::on_destroy),
+                Some(I::on_transact),
+            );
+            if class.is_null() {
+                panic!("Expected non-null class pointer from AIBinder_Class_define!");
+            }
+            sys::AIBinder_Class_setOnDump(class, None);
+            sys::AIBinder_Class_setHandleShellCommand(class, None);
+            class
+        };
+        InterfaceClass(ptr)
+    }
+
+    /// Construct an `InterfaceClass` out of a raw, non-null `AIBinder_Class`
+    /// pointer.
+    ///
+    /// # Safety
+    ///
+    /// This function is safe iff `ptr` is a valid, non-null pointer to an
+    /// `AIBinder_Class`.
+    pub(crate) unsafe fn from_ptr(ptr: *const sys::AIBinder_Class) -> InterfaceClass {
+        InterfaceClass(ptr)
+    }
+}
+
+impl From<InterfaceClass> for *const sys::AIBinder_Class {
+    fn from(class: InterfaceClass) -> *const sys::AIBinder_Class {
+        class.0
+    }
+}
+
+/// Create a function implementing a static getter for an interface class.
+///
+/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
+/// [`Interface`]) must have global, static class that uniquely identifies
+/// it. This macro implements an [`InterfaceClass`] getter to simplify these
+/// implementations.
+///
+/// The type of a structure that implements [`InterfaceClassMethods`] must be
+/// passed to this macro. For local services, this should be `Binder<Self>`
+/// since [`Binder`] implements [`InterfaceClassMethods`].
+///
+/// # Examples
+///
+/// When implementing a local [`Remotable`] service `ExampleService`, the
+/// `get_class` method is required in the [`Remotable`] impl block. This macro
+/// should be used as follows to implement this functionality:
+///
+/// ```rust
+/// impl Remotable for ExampleService {
+///     fn get_descriptor() -> &'static str {
+///         "android.os.IExampleInterface"
+///     }
+///
+///     fn on_transact(
+///         &self,
+///         code: TransactionCode,
+///         data: &Parcel,
+///         reply: &mut Parcel,
+///     ) -> Result<()> {
+///         // ...
+///     }
+///
+///     binder_fn_get_class!(Binder<Self>);
+/// }
+/// ```
+macro_rules! binder_fn_get_class {
+    ($class:ty) => {
+        binder_fn_get_class!($crate::InterfaceClass::new::<$class>());
+    };
+
+    ($constructor:expr) => {
+        fn get_class() -> $crate::InterfaceClass {
+            static CLASS_INIT: std::sync::Once = std::sync::Once::new();
+            static mut CLASS: Option<$crate::InterfaceClass> = None;
+
+            CLASS_INIT.call_once(|| unsafe {
+                // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
+                // variable, and therefore is thread-safe, as it can only occur
+                // once.
+                CLASS = Some($constructor);
+            });
+            unsafe {
+                // Safety: The `CLASS` variable can only be mutated once, above,
+                // and is subsequently safe to read from any thread.
+                CLASS.unwrap()
+            }
+        }
+    };
+}
+
+pub trait InterfaceClassMethods {
+    /// Get the interface descriptor string for this object type.
+    fn get_descriptor() -> &'static str
+    where
+        Self: Sized;
+
+    /// Called during construction of a new `AIBinder` object of this interface
+    /// class.
+    ///
+    /// The opaque pointer parameter will be the parameter provided to
+    /// `AIBinder_new`. Returns an opaque userdata to be associated with the new
+    /// `AIBinder` object.
+    ///
+    /// # Safety
+    ///
+    /// Callback called from C++. The parameter argument provided to
+    /// `AIBinder_new` must match the type expected here. The `AIBinder` object
+    /// will take ownership of the returned pointer, which it will free via
+    /// `on_destroy`.
+    unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void;
+
+    /// Called when a transaction needs to be processed by the local service
+    /// implementation.
+    ///
+    /// # Safety
+    ///
+    /// Callback called from C++. The `binder` parameter must be a valid pointer
+    /// to a binder object of this class with userdata initialized via this
+    /// class's `on_create`. The parcel parameters must be valid pointers to
+    /// parcel objects.
+    unsafe extern "C" fn on_transact(
+        binder: *mut sys::AIBinder,
+        code: u32,
+        data: *const sys::AParcel,
+        reply: *mut sys::AParcel,
+    ) -> status_t;
+
+    /// Called whenever an `AIBinder` object is no longer referenced and needs
+    /// to be destroyed.
+    ///
+    /// # Safety
+    ///
+    /// Callback called from C++. The opaque pointer parameter must be the value
+    /// returned by `on_create` for this class. This function takes ownership of
+    /// the provided pointer and destroys it.
+    unsafe extern "C" fn on_destroy(object: *mut c_void);
+}
+
+/// Interface for transforming a generic SpIBinder into a specific remote
+/// interface trait.
+///
+/// # Example
+///
+/// For Binder interface `IFoo`, the following implementation should be made:
+/// ```no_run
+/// # use binder::{FromIBinder, SpIBinder, Result};
+/// # trait IFoo {}
+/// impl FromIBinder for dyn IFoo {
+///     fn try_from(ibinder: SpIBinder) -> Result<Box<Self>> {
+///         // ...
+///         # Err(binder::StatusCode::OK)
+///     }
+/// }
+/// ```
+pub trait FromIBinder {
+    /// Try to interpret a generic Binder object as this interface.
+    ///
+    /// Returns a trait object for the `Self` interface if this object
+    /// implements that interface.
+    fn try_from(ibinder: SpIBinder) -> Result<Box<Self>>;
+}
+
+/// Trait for transparent Rust wrappers around android C++ native types.
+///
+/// The pointer return by this trait's methods should be immediately passed to
+/// C++ and not stored by Rust. The pointer is valid only as long as the
+/// underlying C++ object is alive, so users must be careful to take this into
+/// account, as Rust cannot enforce this.
+///
+/// # Safety
+///
+/// For this trait to be a correct implementation, `T` must be a valid android
+/// C++ type. Since we cannot constrain this via the type system, this trait is
+/// marked as unsafe.
+pub unsafe trait AsNative<T> {
+    /// Return a pointer to the native version of `self`
+    fn as_native(&self) -> *const T;
+
+    /// Return a mutable pointer to the native version of `self`
+    fn as_native_mut(&mut self) -> *mut T;
+}
+
+unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
+    fn as_native(&self) -> *const T {
+        self.as_ref().map_or(ptr::null(), |v| v.as_native())
+    }
+
+    fn as_native_mut(&mut self) -> *mut T {
+        self.as_mut().map_or(ptr::null_mut(), |v| v.as_native_mut())
+    }
+}
+
+/// Declare typed interfaces for a binder object.
+///
+/// Given an interface trait and descriptor string, create a native and remote
+/// proxy wrapper for this interface. The native service object (`$native`)
+/// implements `Remotable` and will dispatch to the function `$on_transact` to
+/// handle transactions. The typed proxy object (`$proxy`) wraps remote binder
+/// objects for this interface and can optionally contain additional fields.
+///
+/// Assuming the interface trait is `Interface`, `$on_transact` function must
+/// have the following type:
+///
+/// ```
+/// # use binder::{Interface, TransactionCode, Parcel};
+/// # trait Placeholder {
+/// fn on_transact(
+///     service: &dyn Interface,
+///     code: TransactionCode,
+///     data: &Parcel,
+///     reply: &mut Parcel,
+/// ) -> binder::Result<()>;
+/// # }
+/// ```
+///
+/// # Examples
+///
+/// The following example declares the local service type `BnServiceManager` and
+/// a remote proxy type `BpServiceManager` (the `n` and `p` stand for native and
+/// proxy respectively) for the `IServiceManager` Binder interface. The
+/// interfaces will be identified by the descriptor string
+/// "android.os.IServiceManager". The local service will dispatch transactions
+/// using the provided function, `on_transact`.
+///
+/// ```
+/// use binder::{declare_binder_interface, Binder, Interface, TransactionCode, Parcel};
+///
+/// pub trait IServiceManager: Interface {
+///     // remote methods...
+/// }
+///
+/// declare_binder_interface! {
+///     IServiceManager["android.os.IServiceManager"] {
+///         native: BnServiceManager(on_transact),
+///         proxy: BpServiceManager,
+///     }
+/// }
+///
+/// fn on_transact(
+///     service: &dyn IServiceManager,
+///     code: TransactionCode,
+///     data: &Parcel,
+///     reply: &mut Parcel,
+/// ) -> binder::Result<()> {
+///     // ...
+///     Ok(())
+/// }
+///
+/// impl IServiceManager for BpServiceManager {
+///     // parceling/unparceling code for the IServiceManager emitted here
+/// }
+///
+/// impl IServiceManager for Binder<BnServiceManager> {
+///     // Forward calls to local implementation
+/// }
+/// ```
+#[macro_export]
+macro_rules! declare_binder_interface {
+    {
+        $interface:path[$descriptor:expr] {
+            native: $native:ident($on_transact:path),
+            proxy: $proxy:ident,
+        }
+    } => {
+        $crate::declare_binder_interface! {
+            $interface[$descriptor] {
+                native: $native($on_transact),
+                proxy: $proxy {},
+            }
+        }
+    };
+
+    {
+        $interface:path[$descriptor:expr] {
+            native: $native:ident($on_transact:path),
+            proxy: $proxy:ident {
+                $($fname:ident: $fty:ty = $finit:expr),*
+            },
+        }
+    } => {
+        $crate::declare_binder_interface! {
+            $interface[$descriptor] {
+                @doc[concat!("A binder [`Remotable`]($crate::Remotable) that holds an [`", stringify!($interface), "`] object.")]
+                native: $native($on_transact),
+                @doc[concat!("A binder [`Proxy`]($crate::Proxy) that holds an [`", stringify!($interface), "`] remote interface.")]
+                proxy: $proxy {
+                    $($fname: $fty = $finit),*
+                },
+            }
+        }
+    };
+
+    {
+        $interface:path[$descriptor:expr] {
+            @doc[$native_doc:expr]
+            native: $native:ident($on_transact:path),
+
+            @doc[$proxy_doc:expr]
+            proxy: $proxy:ident {
+                $($fname:ident: $fty:ty = $finit:expr),*
+            },
+        }
+    } => {
+        #[doc = $proxy_doc]
+        pub struct $proxy {
+            binder: $crate::SpIBinder,
+            $($fname: $fty,)*
+        }
+
+        impl $crate::Interface for $proxy {
+            fn as_binder(&self) -> $crate::SpIBinder {
+                self.binder.clone()
+            }
+        }
+
+        impl $crate::Proxy for $proxy
+        where
+            $proxy: $interface,
+        {
+            fn get_descriptor() -> &'static str {
+                $descriptor
+            }
+
+            fn from_binder(mut binder: $crate::SpIBinder) -> $crate::Result<Self> {
+                use $crate::AssociateClass;
+                if binder.associate_class(<$native as $crate::Remotable>::get_class()) {
+                    Ok(Self { binder, $($fname: $finit),* })
+                } else {
+                    Err($crate::StatusCode::BAD_TYPE)
+                }
+            }
+        }
+
+        #[doc = $native_doc]
+        #[repr(transparent)]
+        pub struct $native(Box<dyn $interface + Sync + Send + 'static>);
+
+        impl $native {
+            /// Create a new binder service.
+            pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T) -> impl $interface {
+                $crate::Binder::new($native(Box::new(inner)))
+            }
+        }
+
+        impl $crate::Remotable for $native {
+            fn get_descriptor() -> &'static str {
+                $descriptor
+            }
+
+            fn on_transact(&self, code: $crate::TransactionCode, data: &$crate::Parcel, reply: &mut $crate::Parcel) -> $crate::Result<()> {
+                $on_transact(&*self.0, code, data, reply)
+            }
+
+            fn get_class() -> $crate::InterfaceClass {
+                static CLASS_INIT: std::sync::Once = std::sync::Once::new();
+                static mut CLASS: Option<$crate::InterfaceClass> = None;
+
+                CLASS_INIT.call_once(|| unsafe {
+                    // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
+                    // variable, and therefore is thread-safe, as it can only occur
+                    // once.
+                    CLASS = Some($crate::InterfaceClass::new::<$crate::Binder<$native>>());
+                });
+                unsafe {
+                    // Safety: The `CLASS` variable can only be mutated once, above,
+                    // and is subsequently safe to read from any thread.
+                    CLASS.unwrap()
+                }
+            }
+        }
+
+        impl $crate::FromIBinder for dyn $interface {
+            fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<Box<dyn $interface>> {
+                use $crate::AssociateClass;
+                if !ibinder.associate_class(<$native as $crate::Remotable>::get_class()) {
+                    return Err($crate::StatusCode::BAD_TYPE.into());
+                }
+
+                let service: $crate::Result<$crate::Binder<$native>> = std::convert::TryFrom::try_from(ibinder.clone());
+                if let Ok(service) = service {
+                    Ok(Box::new(service))
+                } else {
+                    Ok(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?))
+                }
+            }
+        }
+
+        impl $crate::parcel::Serialize for dyn $interface + '_
+        where
+            $interface: $crate::Interface
+        {
+            fn serialize(&self, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
+                let binder = $crate::Interface::as_binder(self);
+                parcel.write(&binder)
+            }
+        }
+
+        impl $crate::parcel::SerializeOption for dyn $interface + '_ {
+            fn serialize_option(this: Option<&Self>, parcel: &mut $crate::parcel::Parcel) -> $crate::Result<()> {
+                parcel.write(&this.map($crate::Interface::as_binder))
+            }
+        }
+    };
+}
diff --git a/libs/binder/rust/src/error.rs b/libs/binder/rust/src/error.rs
new file mode 100644
index 0000000..289b157
--- /dev/null
+++ b/libs/binder/rust/src/error.rs
@@ -0,0 +1,373 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use crate::binder::AsNative;
+use crate::sys;
+
+use std::error;
+use std::ffi::CStr;
+use std::fmt::{Debug, Display, Formatter, Result as FmtResult};
+use std::result;
+
+pub use sys::binder_status_t as status_t;
+
+/// Low-level status codes from Android `libutils`.
+// All error codes are negative integer values. Derived from the anonymous enum
+// in utils/Errors.h
+pub use sys::android_c_interface_StatusCode as StatusCode;
+
+/// A specialized [`Result`](result::Result) for binder operations.
+pub type Result<T> = result::Result<T, StatusCode>;
+
+/// Convert a low-level status code into an empty result.
+///
+/// An OK status is converted into an `Ok` result, any other status is converted
+/// into an `Err` result holding the status code.
+pub fn status_result(status: status_t) -> Result<()> {
+    match parse_status_code(status) {
+        StatusCode::OK => Ok(()),
+        e => Err(e),
+    }
+}
+
+// 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,
+        e if e == StatusCode::NO_MEMORY as i32 => StatusCode::NO_MEMORY,
+        e if e == StatusCode::INVALID_OPERATION as i32 => StatusCode::INVALID_OPERATION,
+        e if e == StatusCode::BAD_VALUE as i32 => StatusCode::BAD_VALUE,
+        e if e == StatusCode::BAD_TYPE as i32 => StatusCode::BAD_TYPE,
+        e if e == StatusCode::NAME_NOT_FOUND as i32 => StatusCode::NAME_NOT_FOUND,
+        e if e == StatusCode::PERMISSION_DENIED as i32 => StatusCode::PERMISSION_DENIED,
+        e if e == StatusCode::NO_INIT as i32 => StatusCode::NO_INIT,
+        e if e == StatusCode::ALREADY_EXISTS as i32 => StatusCode::ALREADY_EXISTS,
+        e if e == StatusCode::DEAD_OBJECT as i32 => StatusCode::DEAD_OBJECT,
+        e if e == StatusCode::FAILED_TRANSACTION as i32 => StatusCode::FAILED_TRANSACTION,
+        e if e == StatusCode::BAD_INDEX as i32 => StatusCode::BAD_INDEX,
+        e if e == StatusCode::NOT_ENOUGH_DATA as i32 => StatusCode::NOT_ENOUGH_DATA,
+        e if e == StatusCode::WOULD_BLOCK as i32 => StatusCode::WOULD_BLOCK,
+        e if e == StatusCode::TIMED_OUT as i32 => StatusCode::TIMED_OUT,
+        e if e == StatusCode::UNKNOWN_TRANSACTION as i32 => StatusCode::UNKNOWN_TRANSACTION,
+        e if e == StatusCode::FDS_NOT_ALLOWED as i32 => StatusCode::FDS_NOT_ALLOWED,
+        e if e == StatusCode::UNEXPECTED_NULL as i32 => StatusCode::UNEXPECTED_NULL,
+        _ => StatusCode::UNKNOWN_ERROR,
+    }
+}
+
+pub use sys::android_c_interface_ExceptionCode as ExceptionCode;
+
+fn parse_exception_code(code: i32) -> ExceptionCode {
+    match code {
+        e if e == ExceptionCode::NONE as i32 => ExceptionCode::NONE,
+        e if e == ExceptionCode::SECURITY as i32 => ExceptionCode::SECURITY,
+        e if e == ExceptionCode::BAD_PARCELABLE as i32 => ExceptionCode::BAD_PARCELABLE,
+        e if e == ExceptionCode::ILLEGAL_ARGUMENT as i32 => ExceptionCode::ILLEGAL_ARGUMENT,
+        e if e == ExceptionCode::NULL_POINTER as i32 => ExceptionCode::NULL_POINTER,
+        e if e == ExceptionCode::ILLEGAL_STATE as i32 => ExceptionCode::ILLEGAL_STATE,
+        e if e == ExceptionCode::NETWORK_MAIN_THREAD as i32 => {
+            ExceptionCode::NETWORK_MAIN_THREAD
+        }
+        e if e == ExceptionCode::UNSUPPORTED_OPERATION as i32 => {
+            ExceptionCode::UNSUPPORTED_OPERATION
+        }
+        e if e == ExceptionCode::SERVICE_SPECIFIC as i32 => ExceptionCode::SERVICE_SPECIFIC,
+        _ => ExceptionCode::TRANSACTION_FAILED,
+    }
+}
+
+// Safety: `Status` always contains a owning pointer to a valid `AStatus`. The
+// lifetime of the contained pointer is the same as the `Status` object.
+/// High-level binder status object that encapsulates a standard way to keep
+/// track of and chain binder errors along with service specific errors.
+///
+/// Used in AIDL transactions to represent failed transactions.
+pub struct Status(*mut sys::AStatus);
+
+impl Status {
+    /// Create a status object representing a successful transaction.
+    pub fn ok() -> Self {
+        let ptr = unsafe {
+            // Safety: `AStatus_newOk` always returns a new, heap allocated
+            // pointer to an `ASTatus` object, so we know this pointer will be
+            // valid.
+            //
+            // Rust takes ownership of the returned pointer.
+            sys::AStatus_newOk()
+        };
+        Self(ptr)
+    }
+
+    /// Create a status object from a service specific error
+    pub fn new_service_specific_error(err: i32, message: Option<&CStr>) -> Status {
+        let ptr = if let Some(message) = message {
+            unsafe {
+                // Safety: Any i32 is a valid service specific error for the
+                // error code parameter. We construct a valid, null-terminated
+                // `CString` from the message, which must be a valid C-style
+                // string to pass as the message. This function always returns a
+                // new, heap allocated pointer to an `AStatus` object, so we
+                // know the returned pointer will be valid.
+                //
+                // Rust takes ownership of the returned pointer.
+                sys::AStatus_fromServiceSpecificErrorWithMessage(err, message.as_ptr())
+            }
+        } else {
+            unsafe {
+                // Safety: Any i32 is a valid service specific error for the
+                // error code parameter. This function always returns a new,
+                // heap allocated pointer to an `AStatus` object, so we know the
+                // returned pointer will be valid.
+                //
+                // Rust takes ownership of the returned pointer.
+                sys::AStatus_fromServiceSpecificError(err)
+            }
+        };
+        Self(ptr)
+    }
+
+    /// Create a status object from an exception code
+    pub fn new_exception(exception: ExceptionCode, message: Option<&CStr>) -> Status {
+        if let Some(message) = message {
+            let ptr = unsafe {
+                sys::AStatus_fromExceptionCodeWithMessage(exception as i32, message.as_ptr())
+            };
+            Self(ptr)
+        } else {
+            exception.into()
+        }
+    }
+
+    /// Create a status object from a raw `AStatus` pointer.
+    ///
+    /// # Safety
+    ///
+    /// This constructor is safe iff `ptr` is a valid pointer to an `AStatus`.
+    pub(crate) unsafe fn from_ptr(ptr: *mut sys::AStatus) -> Self {
+        Self(ptr)
+    }
+
+    /// Returns `true` if this status represents a successful transaction.
+    pub fn is_ok(&self) -> bool {
+        unsafe {
+            // Safety: `Status` always contains a valid `AStatus` pointer, so we
+            // are always passing a valid pointer to `AStatus_isOk` here.
+            sys::AStatus_isOk(self.as_native())
+        }
+    }
+
+    /// Returns a description of the status.
+    pub fn get_description(&self) -> String {
+        let description_ptr = unsafe {
+            // Safety: `Status` always contains a valid `AStatus` pointer, so we
+            // are always passing a valid pointer to `AStatus_getDescription`
+            // here.
+            //
+            // `AStatus_getDescription` always returns a valid pointer to a null
+            // terminated C string. Rust is responsible for freeing this pointer
+            // via `AStatus_deleteDescription`.
+            sys::AStatus_getDescription(self.as_native())
+        };
+        let description = unsafe {
+            // Safety: `AStatus_getDescription` always returns a valid C string,
+            // which can be safely converted to a `CStr`.
+            CStr::from_ptr(description_ptr)
+        };
+        let description = description.to_string_lossy().to_string();
+        unsafe {
+            // Safety: `description_ptr` was returned from
+            // `AStatus_getDescription` above, and must be freed via
+            // `AStatus_deleteDescription`. We must not access the pointer after
+            // this call, so we copy it into an owned string above and return
+            // that string.
+            sys::AStatus_deleteDescription(description_ptr);
+        }
+        description
+    }
+
+    /// Returns the exception code of the status.
+    pub fn exception_code(&self) -> ExceptionCode {
+        let code = unsafe {
+            // Safety: `Status` always contains a valid `AStatus` pointer, so we
+            // are always passing a valid pointer to `AStatus_getExceptionCode`
+            // here.
+            sys::AStatus_getExceptionCode(self.as_native())
+        };
+        parse_exception_code(code)
+    }
+
+    /// Return a status code representing a transaction failure, or
+    /// `StatusCode::OK` if there was no transaction failure.
+    ///
+    /// If this method returns `OK`, the status may still represent a different
+    /// exception or a service specific error. To find out if this transaction
+    /// as a whole is okay, use [`is_ok`](Self::is_ok) instead.
+    pub fn transaction_error(&self) -> StatusCode {
+        let code = unsafe {
+            // Safety: `Status` always contains a valid `AStatus` pointer, so we
+            // are always passing a valid pointer to `AStatus_getStatus` here.
+            sys::AStatus_getStatus(self.as_native())
+        };
+        parse_status_code(code)
+    }
+
+    /// Return a service specific error if this status represents one.
+    ///
+    /// This function will only ever return a non-zero result if
+    /// [`exception_code`](Self::exception_code) returns
+    /// `ExceptionCode::SERVICE_SPECIFIC`. If this function returns 0, the
+    /// status object may still represent a different exception or status. To
+    /// find out if this transaction as a whole is okay, use
+    /// [`is_ok`](Self::is_ok) instead.
+    pub fn service_specific_error(&self) -> i32 {
+        unsafe {
+            // Safety: `Status` always contains a valid `AStatus` pointer, so we
+            // are always passing a valid pointer to
+            // `AStatus_getServiceSpecificError` here.
+            sys::AStatus_getServiceSpecificError(self.as_native())
+        }
+    }
+
+    /// Calls `op` if the status was ok, otherwise returns an `Err` value of
+    /// `self`.
+    pub fn and_then<T, F>(self, op: F) -> result::Result<T, Status>
+    where
+        F: FnOnce() -> result::Result<T, Status>,
+    {
+        <result::Result<(), Status>>::from(self)?;
+        op()
+    }
+}
+
+impl error::Error for Status {}
+
+impl Display for Status {
+    fn fmt(&self, f: &mut Formatter) -> FmtResult {
+        f.write_str(&self.get_description())
+    }
+}
+
+impl Debug for Status {
+    fn fmt(&self, f: &mut Formatter) -> FmtResult {
+        f.write_str(&self.get_description())
+    }
+}
+
+impl PartialEq for Status {
+    fn eq(&self, other: &Status) -> bool {
+        let self_code = self.exception_code();
+        let other_code = other.exception_code();
+
+        match (self_code, other_code) {
+            (ExceptionCode::NONE, ExceptionCode::NONE) => true,
+            (ExceptionCode::TRANSACTION_FAILED, ExceptionCode::TRANSACTION_FAILED) => {
+                self.transaction_error() == other.transaction_error()
+                    && self.get_description() == other.get_description()
+            }
+            (ExceptionCode::SERVICE_SPECIFIC, ExceptionCode::SERVICE_SPECIFIC) => {
+                self.service_specific_error() == other.service_specific_error()
+                    && self.get_description() == other.get_description()
+            }
+            (e1, e2) => e1 == e2 && self.get_description() == other.get_description(),
+        }
+    }
+}
+
+impl Eq for Status {}
+
+impl From<StatusCode> for Status {
+    fn from(status: StatusCode) -> Status {
+        (status as status_t).into()
+    }
+}
+
+impl From<status_t> for Status {
+    fn from(status: status_t) -> Status {
+        let ptr = unsafe {
+            // Safety: `AStatus_fromStatus` expects any `status_t` integer, so
+            // this is a safe FFI call. Unknown values will be coerced into
+            // UNKNOWN_ERROR.
+            sys::AStatus_fromStatus(status)
+        };
+        Self(ptr)
+    }
+}
+
+impl From<ExceptionCode> for Status {
+    fn from(code: ExceptionCode) -> Status {
+        let ptr = unsafe {
+            // Safety: `AStatus_fromExceptionCode` expects any
+            // `binder_exception_t` (i32) integer, so this is a safe FFI call.
+            // Unknown values will be coerced into EX_TRANSACTION_FAILED.
+            sys::AStatus_fromExceptionCode(code as i32)
+        };
+        Self(ptr)
+    }
+}
+
+// TODO: impl Try for Status when try_trait is stabilized
+// https://github.com/rust-lang/rust/issues/42327
+impl From<Status> for result::Result<(), Status> {
+    fn from(status: Status) -> result::Result<(), Status> {
+        if status.is_ok() {
+            Ok(())
+        } else {
+            Err(status)
+        }
+    }
+}
+
+impl From<Status> for status_t {
+    fn from(status: Status) -> status_t {
+        status.transaction_error() as status_t
+    }
+}
+
+impl Drop for Status {
+    fn drop(&mut self) {
+        unsafe {
+            // Safety: `Status` manages the lifetime of its inner `AStatus`
+            // pointee, so we need to delete it here. We know that the pointer
+            // will be valid here since `Status` always contains a valid pointer
+            // while it is alive.
+            sys::AStatus_delete(self.0);
+        }
+    }
+}
+
+/// # Safety
+///
+/// `Status` always contains a valid pointer to an `AStatus` object, so we can
+/// trivially convert it to a correctly-typed raw pointer.
+///
+/// Care must be taken that the returned pointer is only dereferenced while the
+/// `Status` object is still alive.
+unsafe impl AsNative<sys::AStatus> for Status {
+    fn as_native(&self) -> *const sys::AStatus {
+        self.0
+    }
+
+    fn as_native_mut(&mut self) -> *mut sys::AStatus {
+        self.0
+    }
+}
diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs
new file mode 100644
index 0000000..4b9cccf
--- /dev/null
+++ b/libs/binder/rust/src/lib.rs
@@ -0,0 +1,130 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! Safe Rust interface to Android `libbinder`.
+//!
+//! This crate is primarily designed as an target for a Rust AIDL compiler
+//! backend, and should generally not be used directly by users. It is built on
+//! top of the binder NDK library to be usable by APEX modules, and therefore
+//! only exposes functionality available in the NDK interface.
+//!
+//! # Example
+//!
+//! The following example illustrates how the AIDL backend will use this crate.
+//!
+//! ```
+//! use binder::{
+//!     declare_binder_interface, Binder, IBinder, Interface, Remotable, Parcel, SpIBinder,
+//!     StatusCode, TransactionCode,
+//! };
+//!
+//! // Generated by AIDL compiler
+//! pub trait ITest: Interface {
+//!     fn test(&self) -> binder::Result<String>;
+//! }
+//!
+//! // Creates a new local (native) service object, BnTest, and a remote proxy
+//! // object, BpTest, that are the typed interfaces for their respective ends
+//! // of the binder transaction. Generated by AIDL compiler.
+//! declare_binder_interface! {
+//!     ITest["android.os.ITest"] {
+//!         native: BnTest(on_transact),
+//!         proxy: BpTest,
+//!     }
+//! }
+//!
+//! // Generated by AIDL compiler
+//! fn on_transact(
+//!     service: &dyn ITest,
+//!     code: TransactionCode,
+//!     _data: &Parcel,
+//!     reply: &mut Parcel,
+//! ) -> binder::Result<()> {
+//!     match code {
+//!         SpIBinder::FIRST_CALL_TRANSACTION => {
+//!             reply.write(&service.test()?)?;
+//!             Ok(())
+//!         }
+//!         _ => Err(StatusCode::UNKNOWN_TRANSACTION),
+//!     }
+//! }
+//!
+//! // Generated by AIDL compiler
+//! impl ITest for Binder<BnTest> {
+//!     fn test(&self) -> binder::Result<String> {
+//!         self.0.test()
+//!     }
+//! }
+//!
+//! // Generated by AIDL compiler
+//! impl ITest for BpTest {
+//!     fn test(&self) -> binder::Result<String> {
+//!        let reply = self
+//!            .as_binder()
+//!            .transact(SpIBinder::FIRST_CALL_TRANSACTION, 0, |_| Ok(()))?;
+//!        reply.read()
+//!     }
+//! }
+//!
+//! // User implemented:
+//!
+//! // Local implementation of the ITest remotable interface.
+//! struct TestService;
+//!
+//! impl Interface for TestService {}
+//!
+//! impl ITest for TestService {
+//!     fn test(&self) -> binder::Result<String> {
+//!        Ok("testing service".to_string())
+//!     }
+//! }
+//! ```
+
+#[macro_use]
+mod proxy;
+
+#[macro_use]
+mod binder;
+mod error;
+mod native;
+mod state;
+
+use binder_ndk_bindgen as sys;
+
+pub mod parcel;
+
+pub use crate::binder::{
+    FromIBinder, IBinder, Interface, InterfaceClass, Remotable, TransactionCode, TransactionFlags,
+};
+pub use error::{status_t, ExceptionCode, Result, Status, StatusCode};
+pub use native::add_service;
+pub use native::Binder;
+pub use parcel::Parcel;
+pub use proxy::{get_interface, get_service};
+pub use proxy::{AssociateClass, DeathRecipient, Proxy, SpIBinder, WpIBinder};
+pub use state::{ProcessState, ThreadState};
+
+/// The public API usable outside AIDL-generated interface crates.
+pub mod public_api {
+    pub use super::parcel::ParcelFileDescriptor;
+    pub use super::{add_service, get_interface};
+    pub use super::{
+        ExceptionCode, Interface, ProcessState, SpIBinder, Status, StatusCode,
+    };
+
+    /// Binder result containing a [`Status`] on error.
+    pub type Result<T> = std::result::Result<T, Status>;
+}
diff --git a/libs/binder/rust/src/native.rs b/libs/binder/rust/src/native.rs
new file mode 100644
index 0000000..798fed8
--- /dev/null
+++ b/libs/binder/rust/src/native.rs
@@ -0,0 +1,358 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use crate::binder::{AsNative, Interface, InterfaceClassMethods, Remotable, TransactionCode};
+use crate::error::{status_result, status_t, Result, StatusCode};
+use crate::parcel::{Parcel, Serialize};
+use crate::proxy::SpIBinder;
+use crate::sys;
+
+use std::convert::TryFrom;
+use std::ffi::{c_void, CString};
+use std::mem::ManuallyDrop;
+use std::ops::Deref;
+use std::ptr;
+
+/// Rust wrapper around Binder remotable objects.
+///
+/// Implements the C++ `BBinder` class, and therefore implements the C++
+/// `IBinder` interface.
+#[repr(C)]
+pub struct Binder<T: Remotable> {
+    ibinder: *mut sys::AIBinder,
+    rust_object: *mut T,
+}
+
+impl<T: Remotable> Binder<T> {
+    /// Create a new Binder remotable object.
+    ///
+    /// This moves the `rust_object` into an owned [`Box`] and Binder will
+    /// manage its lifetime.
+    pub fn new(rust_object: T) -> Binder<T> {
+        let class = T::get_class();
+        let rust_object = Box::into_raw(Box::new(rust_object));
+        let ibinder = unsafe {
+            // Safety: `AIBinder_new` expects a valid class pointer (which we
+            // initialize via `get_class`), and an arbitrary pointer
+            // argument. The caller owns the returned `AIBinder` pointer, which
+            // is a strong reference to a `BBinder`. This reference should be
+            // decremented via `AIBinder_decStrong` when the reference lifetime
+            // ends.
+            sys::AIBinder_new(class.into(), rust_object as *mut c_void)
+        };
+        Binder {
+            ibinder,
+            rust_object,
+        }
+    }
+
+    /// Set the extension of a binder interface. This allows a downstream
+    /// developer to add an extension to an interface without modifying its
+    /// interface file. This should be called immediately when the object is
+    /// created before it is passed to another thread.
+    ///
+    /// # Examples
+    ///
+    /// For instance, imagine if we have this Binder AIDL interface definition:
+    ///     interface IFoo { void doFoo(); }
+    ///
+    /// If an unrelated owner (perhaps in a downstream codebase) wants to make a
+    /// change to the interface, they have two options:
+    ///
+    /// 1) Historical option that has proven to be BAD! Only the original
+    ///    author of an interface should change an interface. If someone
+    ///    downstream wants additional functionality, they should not ever
+    ///    change the interface or use this method.
+    ///    ```AIDL
+    ///    BAD TO DO:  interface IFoo {                       BAD TO DO
+    ///    BAD TO DO:      void doFoo();                      BAD TO DO
+    ///    BAD TO DO: +    void doBar(); // adding a method   BAD TO DO
+    ///    BAD TO DO:  }                                      BAD TO DO
+    ///    ```
+    ///
+    /// 2) Option that this method enables!
+    ///    Leave the original interface unchanged (do not change IFoo!).
+    ///    Instead, create a new AIDL interface in a downstream package:
+    ///    ```AIDL
+    ///    package com.<name>; // new functionality in a new package
+    ///    interface IBar { void doBar(); }
+    ///    ```
+    ///
+    ///    When registering the interface, add:
+    ///
+    ///        # use binder::{Binder, Interface};
+    ///        # type MyFoo = ();
+    ///        # type MyBar = ();
+    ///        # let my_foo = ();
+    ///        # let my_bar = ();
+    ///        let mut foo: Binder<MyFoo> = Binder::new(my_foo); // class in AOSP codebase
+    ///        let bar: Binder<MyBar> = Binder::new(my_bar);     // custom extension class
+    ///        foo.set_extension(&mut bar.as_binder());          // use method in Binder
+    ///
+    ///    Then, clients of `IFoo` can get this extension:
+    ///
+    ///        # use binder::{declare_binder_interface, Binder, TransactionCode, Parcel};
+    ///        # trait IBar {}
+    ///        # declare_binder_interface! {
+    ///        #     IBar["test"] {
+    ///        #         native: BnBar(on_transact),
+    ///        #         proxy: BpBar,
+    ///        #     }
+    ///        # }
+    ///        # fn on_transact(
+    ///        #     service: &dyn IBar,
+    ///        #     code: TransactionCode,
+    ///        #     data: &Parcel,
+    ///        #     reply: &mut Parcel,
+    ///        # ) -> binder::Result<()> {
+    ///        #     Ok(())
+    ///        # }
+    ///        # impl IBar for BpBar {}
+    ///        # impl IBar for Binder<BnBar> {}
+    ///        # fn main() -> binder::Result<()> {
+    ///        # let binder = Binder::new(());
+    ///        if let Some(barBinder) = binder.get_extension()? {
+    ///            let bar = BpBar::new(barBinder)
+    ///                .expect("Extension was not of type IBar");
+    ///        } else {
+    ///            // There was no extension
+    ///        }
+    ///        # }
+    pub fn set_extension(&mut self, extension: &mut SpIBinder) -> Result<()> {
+        let status = unsafe {
+            // Safety: `AIBinder_setExtension` expects two valid, mutable
+            // `AIBinder` pointers. We are guaranteed that both `self` and
+            // `extension` contain valid `AIBinder` pointers, because they
+            // cannot be initialized without a valid
+            // pointer. `AIBinder_setExtension` does not take ownership of
+            // either parameter.
+            sys::AIBinder_setExtension(self.as_native_mut(), extension.as_native_mut())
+        };
+        status_result(status)
+    }
+
+    /// Retrieve the interface descriptor string for this object's Binder
+    /// interface.
+    pub fn get_descriptor() -> &'static str {
+        T::get_descriptor()
+    }
+}
+
+impl<T: Remotable> Interface for Binder<T> {
+    /// Converts the local remotable object into a generic `SpIBinder`
+    /// reference.
+    ///
+    /// The resulting `SpIBinder` will hold its own strong reference to this
+    /// remotable object, which will prevent the object from being dropped while
+    /// the `SpIBinder` is alive.
+    fn as_binder(&self) -> SpIBinder {
+        unsafe {
+            // Safety: `self.ibinder` is guaranteed to always be a valid pointer
+            // to an `AIBinder` by the `Binder` constructor. We are creating a
+            // copy of the `self.ibinder` strong reference, but
+            // `SpIBinder::from_raw` assumes it receives an owned pointer with
+            // its own strong reference. We first increment the reference count,
+            // so that the new `SpIBinder` will be tracked as a new reference.
+            sys::AIBinder_incStrong(self.ibinder);
+            SpIBinder::from_raw(self.ibinder).unwrap()
+        }
+    }
+}
+
+impl<T: Remotable> InterfaceClassMethods for Binder<T> {
+    fn get_descriptor() -> &'static str {
+        <T as Remotable>::get_descriptor()
+    }
+
+    /// Called whenever a transaction needs to be processed by a local
+    /// implementation.
+    ///
+    /// # Safety
+    ///
+    /// Must be called with a non-null, valid pointer to a local `AIBinder` that
+    /// contains a `T` pointer in its user data. The `data` and `reply` parcel
+    /// parameters must be valid pointers to `AParcel` objects. This method does
+    /// not take ownership of any of its parameters.
+    ///
+    /// These conditions hold when invoked by `ABBinder::onTransact`.
+    unsafe extern "C" fn on_transact(
+        binder: *mut sys::AIBinder,
+        code: u32,
+        data: *const sys::AParcel,
+        reply: *mut sys::AParcel,
+    ) -> status_t {
+        let res = {
+            let mut reply = Parcel::borrowed(reply).unwrap();
+            let data = Parcel::borrowed(data as *mut sys::AParcel).unwrap();
+            let object = sys::AIBinder_getUserData(binder);
+            let binder: &T = &*(object as *const T);
+            binder.on_transact(code, &data, &mut reply)
+        };
+        match res {
+            Ok(()) => 0i32,
+            Err(e) => e as i32,
+        }
+    }
+
+    /// Called whenever an `AIBinder` object is no longer referenced and needs
+    /// destroyed.
+    ///
+    /// # Safety
+    ///
+    /// Must be called with a valid pointer to a `T` object. After this call,
+    /// the pointer will be invalid and should not be dereferenced.
+    unsafe extern "C" fn on_destroy(object: *mut c_void) {
+        ptr::drop_in_place(object as *mut T)
+    }
+
+    /// Called whenever a new, local `AIBinder` object is needed of a specific
+    /// class.
+    ///
+    /// Constructs the user data pointer that will be stored in the object,
+    /// which will be a heap-allocated `T` object.
+    ///
+    /// # Safety
+    ///
+    /// Must be called with a valid pointer to a `T` object allocated via `Box`.
+    unsafe extern "C" fn on_create(args: *mut c_void) -> *mut c_void {
+        // We just return the argument, as it is already a pointer to the rust
+        // object created by Box.
+        args
+    }
+}
+
+impl<T: Remotable> Drop for Binder<T> {
+    // This causes C++ to decrease the strong ref count of the `AIBinder`
+    // object. We specifically do not drop the `rust_object` here. When C++
+    // actually destroys the object, it calls `on_destroy` and we can drop the
+    // `rust_object` then.
+    fn drop(&mut self) {
+        unsafe {
+            // Safety: When `self` is dropped, we can no longer access the
+            // reference, so can decrement the reference count. `self.ibinder`
+            // is always a valid `AIBinder` pointer, so is valid to pass to
+            // `AIBinder_decStrong`.
+            sys::AIBinder_decStrong(self.ibinder);
+        }
+    }
+}
+
+impl<T: Remotable> Deref for Binder<T> {
+    type Target = T;
+
+    fn deref(&self) -> &Self::Target {
+        unsafe {
+            // Safety: While `self` is alive, the reference count of the
+            // underlying object is > 0 and therefore `on_destroy` cannot be
+            // called. Therefore while `self` is alive, we know that
+            // `rust_object` is still a valid pointer to a heap allocated object
+            // of type `T`.
+            &*self.rust_object
+        }
+    }
+}
+
+impl<B: Remotable> Serialize for Binder<B> {
+    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+        parcel.write_binder(Some(&self.as_binder()))
+    }
+}
+
+// This implementation is an idiomatic implementation of the C++
+// `IBinder::localBinder` interface if the binder object is a Rust binder
+// service.
+impl<B: Remotable> TryFrom<SpIBinder> for Binder<B> {
+    type Error = StatusCode;
+
+    fn try_from(mut ibinder: SpIBinder) -> Result<Self> {
+        let class = B::get_class();
+        if Some(class) != ibinder.get_class() {
+            return Err(StatusCode::BAD_TYPE);
+        }
+        let userdata = unsafe {
+            // Safety: `SpIBinder` always holds a valid pointer pointer to an
+            // `AIBinder`, which we can safely pass to
+            // `AIBinder_getUserData`. `ibinder` retains ownership of the
+            // returned pointer.
+            sys::AIBinder_getUserData(ibinder.as_native_mut())
+        };
+        if userdata.is_null() {
+            return Err(StatusCode::UNEXPECTED_NULL);
+        }
+        // We are transferring the ownership of the AIBinder into the new Binder
+        // object.
+        let mut ibinder = ManuallyDrop::new(ibinder);
+        Ok(Binder {
+            ibinder: ibinder.as_native_mut(),
+            rust_object: userdata as *mut B,
+        })
+    }
+}
+
+/// # Safety
+///
+/// The constructor for `Binder` guarantees that `self.ibinder` will contain a
+/// valid, non-null pointer to an `AIBinder`, so this implementation is type
+/// safe. `self.ibinder` will remain valid for the entire lifetime of `self`
+/// because we hold a strong reference to the `AIBinder` until `self` is
+/// dropped.
+unsafe impl<B: Remotable> AsNative<sys::AIBinder> for Binder<B> {
+    fn as_native(&self) -> *const sys::AIBinder {
+        self.ibinder
+    }
+
+    fn as_native_mut(&mut self) -> *mut sys::AIBinder {
+        self.ibinder
+    }
+}
+
+/// Register a new service with the default service manager.
+///
+/// Registers the given binder object with the given identifier. If successful,
+/// this service can then be retrieved using that identifier.
+pub fn add_service(identifier: &str, mut binder: SpIBinder) -> Result<()> {
+    let instance = CString::new(identifier).unwrap();
+    let status = unsafe {
+        // Safety: `AServiceManager_addService` expects valid `AIBinder` and C
+        // string pointers. Caller retains ownership of both
+        // pointers. `AServiceManager_addService` creates a new strong reference
+        // and copies the string, so both pointers need only be valid until the
+        // call returns.
+        sys::AServiceManager_addService(binder.as_native_mut(), instance.as_ptr())
+    };
+    status_result(status)
+}
+
+/// Tests often create a base BBinder instance; so allowing the unit
+/// type to be remotable translates nicely to Binder::new(()).
+impl Remotable for () {
+    fn get_descriptor() -> &'static str {
+        ""
+    }
+
+    fn on_transact(
+        &self,
+        _code: TransactionCode,
+        _data: &Parcel,
+        _reply: &mut Parcel,
+    ) -> Result<()> {
+        Ok(())
+    }
+
+    binder_fn_get_class!(Binder::<Self>);
+}
+
+impl Interface for () {}
diff --git a/libs/binder/rust/src/parcel.rs b/libs/binder/rust/src/parcel.rs
new file mode 100644
index 0000000..43850fe
--- /dev/null
+++ b/libs/binder/rust/src/parcel.rs
@@ -0,0 +1,447 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! Container for messages that are sent via binder.
+
+use crate::binder::AsNative;
+use crate::error::{status_result, Result, StatusCode};
+use crate::proxy::SpIBinder;
+use crate::sys;
+
+use std::convert::TryInto;
+use std::mem::ManuallyDrop;
+use std::ptr;
+
+mod file_descriptor;
+mod parcelable;
+
+pub use self::file_descriptor::ParcelFileDescriptor;
+pub use self::parcelable::{
+    Deserialize, DeserializeArray, DeserializeOption, Serialize, SerializeArray, SerializeOption,
+};
+
+/// Container for a message (data and object references) that can be sent
+/// through Binder.
+///
+/// A Parcel can contain both serialized data that will be deserialized on the
+/// other side of the IPC, and references to live Binder objects that will
+/// result in the other side receiving a proxy Binder connected with the
+/// original Binder in the Parcel.
+pub enum Parcel {
+    /// Owned parcel pointer
+    Owned(*mut sys::AParcel),
+    /// Borrowed parcel pointer (will not be destroyed on drop)
+    Borrowed(*mut sys::AParcel),
+}
+
+/// # Safety
+///
+/// The `Parcel` constructors guarantee that a `Parcel` object will always
+/// contain a valid pointer to an `AParcel`.
+unsafe impl AsNative<sys::AParcel> for Parcel {
+    fn as_native(&self) -> *const sys::AParcel {
+        match *self {
+            Self::Owned(x) | Self::Borrowed(x) => x,
+        }
+    }
+
+    fn as_native_mut(&mut self) -> *mut sys::AParcel {
+        match *self {
+            Self::Owned(x) | Self::Borrowed(x) => x,
+        }
+    }
+}
+
+impl Parcel {
+    /// Create a borrowed reference to a parcel object from a raw pointer.
+    ///
+    /// # Safety
+    ///
+    /// This constructor is safe if the raw pointer parameter is either null
+    /// (resulting in `None`), or a valid pointer to an `AParcel` object.
+    pub(crate) unsafe fn borrowed(ptr: *mut sys::AParcel) -> Option<Parcel> {
+        ptr.as_mut().map(|ptr| Self::Borrowed(ptr))
+    }
+
+    /// Create an owned reference to a parcel object from a raw pointer.
+    ///
+    /// # Safety
+    ///
+    /// This constructor is safe if the raw pointer parameter is either null
+    /// (resulting in `None`), or a valid pointer to an `AParcel` object. The
+    /// parcel object must be owned by the caller prior to this call, as this
+    /// constructor takes ownership of the parcel and will destroy it on drop.
+    pub(crate) unsafe fn owned(ptr: *mut sys::AParcel) -> Option<Parcel> {
+        ptr.as_mut().map(|ptr| Self::Owned(ptr))
+    }
+
+    /// Consume the parcel, transferring ownership to the caller if the parcel
+    /// was owned.
+    pub(crate) fn into_raw(mut self) -> *mut sys::AParcel {
+        let ptr = self.as_native_mut();
+        let _ = ManuallyDrop::new(self);
+        ptr
+    }
+}
+
+// Data serialization methods
+impl Parcel {
+    /// Write a type that implements [`Serialize`] to the `Parcel`.
+    pub fn write<S: Serialize + ?Sized>(&mut self, parcelable: &S) -> Result<()> {
+        parcelable.serialize(self)
+    }
+
+    /// Writes the length of a slice to the `Parcel`.
+    ///
+    /// This is used in AIDL-generated client side code to indicate the
+    /// allocated space for an output array parameter.
+    pub fn write_slice_size<T>(&mut self, slice: Option<&[T]>) -> Result<()> {
+        if let Some(slice) = slice {
+            let len: i32 = slice.len().try_into().or(Err(StatusCode::BAD_VALUE))?;
+            self.write(&len)
+        } else {
+            self.write(&-1i32)
+        }
+    }
+
+    /// Returns the current position in the parcel data.
+    pub fn get_data_position(&self) -> i32 {
+        unsafe {
+            // Safety: `Parcel` always contains a valid pointer to an `AParcel`,
+            // and this call is otherwise safe.
+            sys::AParcel_getDataPosition(self.as_native())
+        }
+    }
+
+    /// Move the current read/write position in the parcel.
+    ///
+    /// The new position must be a position previously returned by
+    /// `self.get_data_position()`.
+    ///
+    /// # Safety
+    ///
+    /// This method is safe if `pos` is less than the current size of the parcel
+    /// data buffer. Otherwise, we are relying on correct bounds checking in the
+    /// Parcel C++ code on every subsequent read or write to this parcel. If all
+    /// accesses are bounds checked, this call is still safe, but we can't rely
+    /// on that.
+    pub unsafe fn set_data_position(&self, pos: i32) -> Result<()> {
+        status_result(sys::AParcel_setDataPosition(self.as_native(), pos))
+    }
+}
+
+// Data deserialization methods
+impl Parcel {
+    /// Attempt to read a type that implements [`Deserialize`] from this
+    /// `Parcel`.
+    pub fn read<D: Deserialize>(&self) -> Result<D> {
+        D::deserialize(self)
+    }
+
+    /// Read a vector size from the `Parcel` and resize the given output vector
+    /// to be correctly sized for that amount of data.
+    ///
+    /// This method is used in AIDL-generated server side code for methods that
+    /// take a mutable slice reference parameter.
+    pub fn resize_out_vec<D: Default + Deserialize>(&self, out_vec: &mut Vec<D>) -> Result<()> {
+        let len: i32 = self.read()?;
+
+        if len < 0 {
+            return Err(StatusCode::UNEXPECTED_NULL);
+        }
+
+        // usize in Rust may be 16-bit, so i32 may not fit
+        let len = len.try_into().unwrap();
+        out_vec.resize_with(len, Default::default);
+
+        Ok(())
+    }
+
+    /// Read a vector size from the `Parcel` and either create a correctly sized
+    /// vector for that amount of data or set the output parameter to None if
+    /// the vector should be null.
+    ///
+    /// This method is used in AIDL-generated server side code for methods that
+    /// take a mutable slice reference parameter.
+    pub fn resize_nullable_out_vec<D: Default + Deserialize>(
+        &self,
+        out_vec: &mut Option<Vec<D>>,
+    ) -> Result<()> {
+        let len: i32 = self.read()?;
+
+        if len < 0 {
+            *out_vec = None;
+        } else {
+            // usize in Rust may be 16-bit, so i32 may not fit
+            let len = len.try_into().unwrap();
+            let mut vec = Vec::with_capacity(len);
+            vec.resize_with(len, Default::default);
+            *out_vec = Some(vec);
+        }
+
+        Ok(())
+    }
+}
+
+// Internal APIs
+impl Parcel {
+    pub(crate) fn write_binder(&mut self, binder: Option<&SpIBinder>) -> Result<()> {
+        unsafe {
+            // Safety: `Parcel` always contains a valid pointer to an
+            // `AParcel`. `AsNative` for `Option<SpIBinder`> will either return
+            // null or a valid pointer to an `AIBinder`, both of which are
+            // valid, safe inputs to `AParcel_writeStrongBinder`.
+            //
+            // This call does not take ownership of the binder. However, it does
+            // require a mutable pointer, which we cannot extract from an
+            // immutable reference, so we clone the binder, incrementing the
+            // refcount before the call. The refcount will be immediately
+            // decremented when this temporary is dropped.
+            status_result(sys::AParcel_writeStrongBinder(
+                self.as_native_mut(),
+                binder.cloned().as_native_mut(),
+            ))
+        }
+    }
+
+    pub(crate) fn read_binder(&self) -> Result<Option<SpIBinder>> {
+        let mut binder = ptr::null_mut();
+        let status = unsafe {
+            // Safety: `Parcel` always contains a valid pointer to an
+            // `AParcel`. We pass a valid, mutable out pointer to the `binder`
+            // parameter. After this call, `binder` will be either null or a
+            // valid pointer to an `AIBinder` owned by the caller.
+            sys::AParcel_readStrongBinder(self.as_native(), &mut binder)
+        };
+
+        status_result(status)?;
+
+        Ok(unsafe {
+            // Safety: `binder` is either null or a valid, owned pointer at this
+            // point, so can be safely passed to `SpIBinder::from_raw`.
+            SpIBinder::from_raw(binder)
+        })
+    }
+}
+
+impl Drop for Parcel {
+    fn drop(&mut self) {
+        // Run the C++ Parcel complete object destructor
+        if let Self::Owned(ptr) = *self {
+            unsafe {
+                // Safety: `Parcel` always contains a valid pointer to an
+                // `AParcel`. If we own the parcel, we can safely delete it
+                // here.
+                sys::AParcel_delete(ptr)
+            }
+        }
+    }
+}
+
+#[cfg(test)]
+impl Parcel {
+    /// Create a new parcel tied to a bogus binder. TESTING ONLY!
+    ///
+    /// This can only be used for testing! All real parcel operations must be
+    /// done in the callback to [`IBinder::transact`] or in
+    /// [`Remotable::on_transact`] using the parcels provided to these methods.
+    pub(crate) fn new_for_test(binder: &mut SpIBinder) -> Result<Self> {
+        let mut input = ptr::null_mut();
+        let status = unsafe {
+            // Safety: `SpIBinder` guarantees that `binder` always contains a
+            // valid pointer to an `AIBinder`. We pass a valid, mutable out
+            // pointer to receive a newly constructed parcel. When successful
+            // this function assigns a new pointer to an `AParcel` to `input`
+            // and transfers ownership of this pointer to the caller. Thus,
+            // after this call, `input` will either be null or point to a valid,
+            // owned `AParcel`.
+            sys::AIBinder_prepareTransaction(binder.as_native_mut(), &mut input)
+        };
+        status_result(status)?;
+        unsafe {
+            // Safety: `input` is either null or a valid, owned pointer to an
+            // `AParcel`, so is valid to safe to
+            // `Parcel::owned`. `Parcel::owned` takes ownership of the parcel
+            // pointer.
+            Parcel::owned(input).ok_or(StatusCode::UNEXPECTED_NULL)
+        }
+    }
+}
+
+#[test]
+fn test_read_write() {
+    use crate::binder::Interface;
+    use crate::native::Binder;
+    use std::ffi::CString;
+
+    let mut service = Binder::new(()).as_binder();
+    let mut parcel = Parcel::new_for_test(&mut service).unwrap();
+    let start = parcel.get_data_position();
+
+    assert_eq!(parcel.read::<bool>(), Err(StatusCode::NOT_ENOUGH_DATA));
+    assert_eq!(parcel.read::<i8>(), Err(StatusCode::NOT_ENOUGH_DATA));
+    assert_eq!(parcel.read::<u16>(), Err(StatusCode::NOT_ENOUGH_DATA));
+    assert_eq!(parcel.read::<i32>(), Err(StatusCode::NOT_ENOUGH_DATA));
+    assert_eq!(parcel.read::<u32>(), Err(StatusCode::NOT_ENOUGH_DATA));
+    assert_eq!(parcel.read::<i64>(), Err(StatusCode::NOT_ENOUGH_DATA));
+    assert_eq!(parcel.read::<u64>(), Err(StatusCode::NOT_ENOUGH_DATA));
+    assert_eq!(parcel.read::<f32>(), Err(StatusCode::NOT_ENOUGH_DATA));
+    assert_eq!(parcel.read::<f64>(), Err(StatusCode::NOT_ENOUGH_DATA));
+    assert_eq!(parcel.read::<Option<CString>>(), Ok(None));
+    assert_eq!(parcel.read::<String>(), Err(StatusCode::UNEXPECTED_NULL));
+
+    assert_eq!(parcel.read_binder().err(), Some(StatusCode::BAD_TYPE));
+
+    parcel.write(&1i32).unwrap();
+
+    unsafe {
+        parcel.set_data_position(start).unwrap();
+    }
+
+    let i: i32 = parcel.read().unwrap();
+    assert_eq!(i, 1i32);
+}
+
+#[test]
+#[allow(clippy::float_cmp)]
+fn test_read_data() {
+    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 str_start = parcel.get_data_position();
+
+    parcel.write(&b"Hello, Binder!\0"[..]).unwrap();
+    // Skip over string length
+    unsafe {
+        assert!(parcel.set_data_position(str_start).is_ok());
+    }
+    assert_eq!(parcel.read::<i32>().unwrap(), 15);
+    let start = parcel.get_data_position();
+
+    assert_eq!(parcel.read::<bool>().unwrap(), true);
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert_eq!(parcel.read::<i8>().unwrap(), 72i8);
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert_eq!(parcel.read::<u16>().unwrap(), 25928);
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert_eq!(parcel.read::<i32>().unwrap(), 1819043144);
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert_eq!(parcel.read::<u32>().unwrap(), 1819043144);
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert_eq!(parcel.read::<i64>().unwrap(), 4764857262830019912);
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert_eq!(parcel.read::<u64>().unwrap(), 4764857262830019912);
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert_eq!(
+        parcel.read::<f32>().unwrap(),
+        1143139100000000000000000000.0
+    );
+    assert_eq!(parcel.read::<f32>().unwrap(), 40.043392);
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert_eq!(parcel.read::<f64>().unwrap(), 34732488246.197815);
+
+    // Skip back to before the string length
+    unsafe {
+        assert!(parcel.set_data_position(str_start).is_ok());
+    }
+
+    assert_eq!(parcel.read::<Vec<u8>>().unwrap(), b"Hello, Binder!\0");
+}
+
+#[test]
+fn test_utf8_utf16_conversions() {
+    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();
+
+    assert!(parcel.write("Hello, Binder!").is_ok());
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+    assert_eq!(
+        parcel.read::<Option<String>>().unwrap().unwrap(),
+        "Hello, Binder!"
+    );
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+    assert!(parcel.write(&["str1", "str2", "str3"][..]).is_ok());
+    assert!(parcel
+        .write(
+            &[
+                String::from("str4"),
+                String::from("str5"),
+                String::from("str6"),
+            ][..]
+        )
+        .is_ok());
+
+    let s1 = "Hello, Binder!";
+    let s2 = "This is a utf8 string.";
+    let s3 = "Some more text here.";
+
+    assert!(parcel.write(&[s1, s2, s3][..]).is_ok());
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert_eq!(
+        parcel.read::<Vec<String>>().unwrap(),
+        ["str1", "str2", "str3"]
+    );
+    assert_eq!(
+        parcel.read::<Vec<String>>().unwrap(),
+        ["str4", "str5", "str6"]
+    );
+    assert_eq!(parcel.read::<Vec<String>>().unwrap(), [s1, s2, s3]);
+}
diff --git a/libs/binder/rust/src/parcel/file_descriptor.rs b/libs/binder/rust/src/parcel/file_descriptor.rs
new file mode 100644
index 0000000..8a89ab0
--- /dev/null
+++ b/libs/binder/rust/src/parcel/file_descriptor.rs
@@ -0,0 +1,126 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use super::{
+    Deserialize, DeserializeArray, DeserializeOption, Parcel, Serialize, SerializeArray,
+    SerializeOption,
+};
+use crate::binder::AsNative;
+use crate::error::{status_result, Result, StatusCode};
+use crate::sys;
+
+use std::fs::File;
+use std::os::unix::io::{AsRawFd, FromRawFd};
+
+/// Rust version of the Java class android.os.ParcelFileDescriptor
+pub struct ParcelFileDescriptor(File);
+
+impl ParcelFileDescriptor {
+    /// Create a new `ParcelFileDescriptor`
+    pub fn new(file: File) -> Self {
+        Self(file)
+    }
+}
+
+impl AsRef<File> for ParcelFileDescriptor {
+    fn as_ref(&self) -> &File {
+        &self.0
+    }
+}
+
+impl From<ParcelFileDescriptor> for File {
+    fn from(file: ParcelFileDescriptor) -> File {
+        file.0
+    }
+}
+
+impl Serialize for ParcelFileDescriptor {
+    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+        let fd = self.0.as_raw_fd();
+        let status = unsafe {
+            // Safety: `Parcel` always contains a valid pointer to an
+            // `AParcel`. Likewise, `ParcelFileDescriptor` always contains a
+            // valid file, so we can borrow a valid file
+            // descriptor. `AParcel_writeParcelFileDescriptor` does NOT take
+            // ownership of the fd, so we need not duplicate it first.
+            sys::AParcel_writeParcelFileDescriptor(parcel.as_native_mut(), fd)
+        };
+        status_result(status)
+    }
+}
+
+impl SerializeArray for ParcelFileDescriptor {}
+
+impl SerializeOption for ParcelFileDescriptor {
+    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+        if let Some(f) = this {
+            f.serialize(parcel)
+        } else {
+            let status = unsafe {
+                // Safety: `Parcel` always contains a valid pointer to an
+                // `AParcel`. `AParcel_writeParcelFileDescriptor` accepts the
+                // value `-1` as the file descriptor to signify serializing a
+                // null file descriptor.
+                sys::AParcel_writeParcelFileDescriptor(parcel.as_native_mut(), -1i32)
+            };
+            status_result(status)
+        }
+    }
+}
+
+impl SerializeArray for Option<ParcelFileDescriptor> {}
+
+impl DeserializeOption for ParcelFileDescriptor {
+    fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> {
+        let mut fd = -1i32;
+        unsafe {
+            // Safety: `Parcel` always contains a valid pointer to an
+            // `AParcel`. We pass a valid mutable pointer to an i32, which
+            // `AParcel_readParcelFileDescriptor` assigns the valid file
+            // descriptor into, or `-1` if deserializing a null file
+            // descriptor. The read function passes ownership of the file
+            // descriptor to its caller if it was non-null, so we must take
+            // ownership of the file and ensure that it is eventually closed.
+            status_result(sys::AParcel_readParcelFileDescriptor(
+                parcel.as_native(),
+                &mut fd,
+            ))?;
+        }
+        if fd < 0 {
+            Ok(None)
+        } else {
+            let file = unsafe {
+                // Safety: At this point, we know that the file descriptor was
+                // not -1, so must be a valid, owned file descriptor which we
+                // can safely turn into a `File`.
+                File::from_raw_fd(fd)
+            };
+            Ok(Some(ParcelFileDescriptor::new(file)))
+        }
+    }
+}
+
+impl DeserializeArray for Option<ParcelFileDescriptor> {}
+
+impl Deserialize for ParcelFileDescriptor {
+    fn deserialize(parcel: &Parcel) -> Result<Self> {
+        Deserialize::deserialize(parcel)
+            .transpose()
+            .unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
+    }
+}
+
+impl DeserializeArray for ParcelFileDescriptor {}
diff --git a/libs/binder/rust/src/parcel/parcelable.rs b/libs/binder/rust/src/parcel/parcelable.rs
new file mode 100644
index 0000000..78b3d2c
--- /dev/null
+++ b/libs/binder/rust/src/parcel/parcelable.rs
@@ -0,0 +1,922 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use crate::binder::{AsNative, FromIBinder};
+use crate::error::{status_result, Result, Status, StatusCode};
+use crate::parcel::Parcel;
+use crate::proxy::SpIBinder;
+use crate::sys;
+
+use std::convert::TryInto;
+use std::ffi::{c_void, CStr, CString};
+use std::ptr;
+
+/// A struct whose instances can be written to a [`Parcel`].
+// Might be able to hook this up as a serde backend in the future?
+pub trait Serialize {
+    /// Serialize this instance into the given [`Parcel`].
+    fn serialize(&self, parcel: &mut Parcel) -> Result<()>;
+}
+
+/// A struct whose instances can be restored from a [`Parcel`].
+// Might be able to hook this up as a serde backend in the future?
+pub trait Deserialize: Sized {
+    /// Deserialize an instance from the given [`Parcel`].
+    fn deserialize(parcel: &Parcel) -> Result<Self>;
+}
+
+/// Helper trait for types that can be serialized as arrays.
+/// Defaults to calling Serialize::serialize() manually for every element,
+/// but can be overridden for custom implementations like `writeByteArray`.
+// Until specialization is stabilized in Rust, we need this to be a separate
+// trait because it's the only way to have a default implementation for a method.
+// We want the default implementation for most types, but an override for
+// a few special ones like `readByteArray` for `u8`.
+pub trait SerializeArray: Serialize + Sized {
+    /// Serialize an array of this type into the given [`Parcel`].
+    fn serialize_array(slice: &[Self], parcel: &mut Parcel) -> Result<()> {
+        parcel.write_slice_size(Some(slice))?;
+
+        for item in slice {
+            parcel.write(item)?;
+        }
+
+        Ok(())
+    }
+}
+
+/// Helper trait for types that can be deserialized as arrays.
+/// Defaults to calling Deserialize::deserialize() manually for every element,
+/// but can be overridden for custom implementations like `readByteArray`.
+pub trait DeserializeArray: Deserialize {
+    /// Deserialize an array of type from the given [`Parcel`].
+    fn deserialize_array(parcel: &Parcel) -> Result<Option<Vec<Self>>> {
+        let len: i32 = parcel.read()?;
+        if len < 0 {
+            return Ok(None);
+        }
+
+        // TODO: Assumes that usize is at least 32 bits
+        let mut vec = Vec::with_capacity(len as usize);
+
+        for _ in 0..len {
+            vec.push(parcel.read()?);
+        }
+
+        Ok(Some(vec))
+    }
+}
+
+/// Helper trait for types that can be nullable when serialized.
+// We really need this trait instead of implementing `Serialize for Option<T>`
+// because of the Rust orphan rule which prevents us from doing
+// `impl Serialize for Option<&dyn IFoo>` for AIDL interfaces.
+// Instead we emit `impl SerializeOption for dyn IFoo` which is allowed.
+// We also use it to provide a default implementation for AIDL-generated
+// parcelables.
+pub trait SerializeOption: Serialize {
+    /// Serialize an Option of this type into the given [`Parcel`].
+    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+        if let Some(inner) = this {
+            parcel.write(&1i32)?;
+            parcel.write(inner)
+        } else {
+            parcel.write(&0i32)
+        }
+    }
+}
+
+/// Helper trait for types that can be nullable when deserialized.
+pub trait DeserializeOption: Deserialize {
+    /// Deserialize an Option of this type from the given [`Parcel`].
+    fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> {
+        let null: i32 = parcel.read()?;
+        if null == 0 {
+            Ok(None)
+        } else {
+            parcel.read().map(Some)
+        }
+    }
+}
+
+/// Callback to allocate a vector for parcel array read functions.
+///
+/// # Safety
+///
+/// The opaque data pointer passed to the array read function must be a mutable
+/// pointer to an `Option<Vec<T>>`. `buffer` will be assigned a mutable pointer
+/// to the allocated vector data if this function returns true.
+unsafe extern "C" fn allocate_vec<T: Clone + Default>(
+    data: *mut c_void,
+    len: i32,
+    buffer: *mut *mut T,
+) -> bool {
+    let vec = &mut *(data as *mut Option<Vec<T>>);
+    if len < 0 {
+        *vec = None;
+        return true;
+    }
+    let mut new_vec: Vec<T> = Vec::with_capacity(len as usize);
+    new_vec.resize_with(len as usize, Default::default);
+    *buffer = new_vec.as_mut_ptr();
+    *vec = Some(new_vec);
+    true
+}
+
+macro_rules! parcelable_primitives {
+    {
+        $(
+            impl $trait:ident for $ty:ty = $fn:path;
+        )*
+    } => {
+        $(impl_parcelable!{$trait, $ty, $fn})*
+    };
+}
+
+macro_rules! impl_parcelable {
+    {Serialize, $ty:ty, $write_fn:path} => {
+        impl Serialize for $ty {
+            fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+                unsafe {
+                    // Safety: `Parcel` always contains a valid pointer to an
+                    // `AParcel`, and any `$ty` literal value is safe to pass to
+                    // `$write_fn`.
+                    status_result($write_fn(parcel.as_native_mut(), *self))
+                }
+            }
+        }
+    };
+
+    {Deserialize, $ty:ty, $read_fn:path} => {
+        impl Deserialize for $ty {
+            fn deserialize(parcel: &Parcel) -> Result<Self> {
+                let mut val = Self::default();
+                unsafe {
+                    // Safety: `Parcel` always contains a valid pointer to an
+                    // `AParcel`. We pass a valid, mutable pointer to `val`, a
+                    // literal of type `$ty`, and `$read_fn` will write the
+                    // value read into `val` if successful
+                    status_result($read_fn(parcel.as_native(), &mut val))?
+                };
+                Ok(val)
+            }
+        }
+    };
+
+    {SerializeArray, $ty:ty, $write_array_fn:path} => {
+        impl SerializeArray for $ty {
+            fn serialize_array(slice: &[Self], parcel: &mut Parcel) -> Result<()> {
+                let status = unsafe {
+                    // Safety: `Parcel` always contains a valid pointer to an
+                    // `AParcel`. If the slice is > 0 length, `slice.as_ptr()`
+                    // will be a valid pointer to an array of elements of type
+                    // `$ty`. If the slice length is 0, `slice.as_ptr()` may be
+                    // dangling, but this is safe since the pointer is not
+                    // dereferenced if the length parameter is 0.
+                    $write_array_fn(
+                        parcel.as_native_mut(),
+                        slice.as_ptr(),
+                        slice
+                            .len()
+                            .try_into()
+                            .or(Err(StatusCode::BAD_VALUE))?,
+                    )
+                };
+                status_result(status)
+            }
+        }
+    };
+
+    {DeserializeArray, $ty:ty, $read_array_fn:path} => {
+        impl DeserializeArray for $ty {
+            fn deserialize_array(parcel: &Parcel) -> Result<Option<Vec<Self>>> {
+                let mut vec: Option<Vec<Self>> = None;
+                let status = unsafe {
+                    // Safety: `Parcel` always contains a valid pointer to an
+                    // `AParcel`. `allocate_vec<T>` expects the opaque pointer to
+                    // be of type `*mut Option<Vec<T>>`, so `&mut vec` is
+                    // correct for it.
+                    $read_array_fn(
+                        parcel.as_native(),
+                        &mut vec as *mut _ as *mut c_void,
+                        Some(allocate_vec),
+                    )
+                };
+                status_result(status)?;
+                Ok(vec)
+            }
+        }
+    };
+}
+
+parcelable_primitives! {
+    impl Serialize for bool = sys::AParcel_writeBool;
+    impl Deserialize for bool = sys::AParcel_readBool;
+
+    // This is only safe because `Option<Vec<u8>>` is interchangeable with
+    // `Option<Vec<i8>>` (what the allocator function actually allocates.
+    impl DeserializeArray for u8 = sys::AParcel_readByteArray;
+
+    impl Serialize for i8 = sys::AParcel_writeByte;
+    impl Deserialize for i8 = sys::AParcel_readByte;
+    impl SerializeArray for i8 = sys::AParcel_writeByteArray;
+    impl DeserializeArray for i8 = sys::AParcel_readByteArray;
+
+    impl Serialize for u16 = sys::AParcel_writeChar;
+    impl Deserialize for u16 = sys::AParcel_readChar;
+    impl SerializeArray for u16 = sys::AParcel_writeCharArray;
+    impl DeserializeArray for u16 = sys::AParcel_readCharArray;
+
+    // This is only safe because `Option<Vec<i16>>` is interchangeable with
+    // `Option<Vec<u16>>` (what the allocator function actually allocates.
+    impl DeserializeArray for i16 = sys::AParcel_readCharArray;
+
+    impl Serialize for u32 = sys::AParcel_writeUint32;
+    impl Deserialize for u32 = sys::AParcel_readUint32;
+    impl SerializeArray for u32 = sys::AParcel_writeUint32Array;
+    impl DeserializeArray for u32 = sys::AParcel_readUint32Array;
+
+    impl Serialize for i32 = sys::AParcel_writeInt32;
+    impl Deserialize for i32 = sys::AParcel_readInt32;
+    impl SerializeArray for i32 = sys::AParcel_writeInt32Array;
+    impl DeserializeArray for i32 = sys::AParcel_readInt32Array;
+
+    impl Serialize for u64 = sys::AParcel_writeUint64;
+    impl Deserialize for u64 = sys::AParcel_readUint64;
+    impl SerializeArray for u64 = sys::AParcel_writeUint64Array;
+    impl DeserializeArray for u64 = sys::AParcel_readUint64Array;
+
+    impl Serialize for i64 = sys::AParcel_writeInt64;
+    impl Deserialize for i64 = sys::AParcel_readInt64;
+    impl SerializeArray for i64 = sys::AParcel_writeInt64Array;
+    impl DeserializeArray for i64 = sys::AParcel_readInt64Array;
+
+    impl Serialize for f32 = sys::AParcel_writeFloat;
+    impl Deserialize for f32 = sys::AParcel_readFloat;
+    impl SerializeArray for f32 = sys::AParcel_writeFloatArray;
+    impl DeserializeArray for f32 = sys::AParcel_readFloatArray;
+
+    impl Serialize for f64 = sys::AParcel_writeDouble;
+    impl Deserialize for f64 = sys::AParcel_readDouble;
+    impl SerializeArray for f64 = sys::AParcel_writeDoubleArray;
+    impl DeserializeArray for f64 = sys::AParcel_readDoubleArray;
+}
+
+impl SerializeArray for bool {}
+impl DeserializeArray for bool {}
+
+impl Serialize for u8 {
+    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+        (*self as i8).serialize(parcel)
+    }
+}
+
+impl Deserialize for u8 {
+    fn deserialize(parcel: &Parcel) -> Result<Self> {
+        i8::deserialize(parcel).map(|v| v as u8)
+    }
+}
+
+impl SerializeArray for u8 {
+    fn serialize_array(slice: &[Self], parcel: &mut Parcel) -> Result<()> {
+        let status = unsafe {
+            // Safety: `Parcel` always contains a valid pointer to an
+            // `AParcel`. If the slice is > 0 length, `slice.as_ptr()` will be a
+            // valid pointer to an array of elements of type `$ty`. If the slice
+            // length is 0, `slice.as_ptr()` may be dangling, but this is safe
+            // since the pointer is not dereferenced if the length parameter is
+            // 0.
+            sys::AParcel_writeByteArray(
+                parcel.as_native_mut(),
+                slice.as_ptr() as *const i8,
+                slice.len().try_into().or(Err(StatusCode::BAD_VALUE))?,
+            )
+        };
+        status_result(status)
+    }
+}
+
+impl Serialize for i16 {
+    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+        (*self as u16).serialize(parcel)
+    }
+}
+
+impl Deserialize for i16 {
+    fn deserialize(parcel: &Parcel) -> Result<Self> {
+        u16::deserialize(parcel).map(|v| v as i16)
+    }
+}
+
+impl SerializeArray for i16 {
+    fn serialize_array(slice: &[Self], parcel: &mut Parcel) -> Result<()> {
+        let status = unsafe {
+            // Safety: `Parcel` always contains a valid pointer to an
+            // `AParcel`. If the slice is > 0 length, `slice.as_ptr()` will be a
+            // valid pointer to an array of elements of type `$ty`. If the slice
+            // length is 0, `slice.as_ptr()` may be dangling, but this is safe
+            // since the pointer is not dereferenced if the length parameter is
+            // 0.
+            sys::AParcel_writeCharArray(
+                parcel.as_native_mut(),
+                slice.as_ptr() as *const u16,
+                slice.len().try_into().or(Err(StatusCode::BAD_VALUE))?,
+            )
+        };
+        status_result(status)
+    }
+}
+
+impl SerializeOption for CStr {
+    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+        match this {
+            None => unsafe {
+                // Safety: `Parcel` always contains a valid pointer to an
+                // `AParcel`. If the string pointer is null,
+                // `AParcel_writeString` requires that the length is -1 to
+                // indicate that we want to serialize a null string.
+                status_result(sys::AParcel_writeString(
+                    parcel.as_native_mut(),
+                    ptr::null(),
+                    -1,
+                ))
+            },
+            Some(s) => unsafe {
+                // Safety: `Parcel` always contains a valid pointer to an
+                // `AParcel`. `AParcel_writeString` assumes that we pass a
+                // null-terminated C string pointer with no nulls in the middle
+                // of the string. Rust guarantees exactly that for a valid CStr
+                // instance.
+                status_result(sys::AParcel_writeString(
+                    parcel.as_native_mut(),
+                    s.as_ptr(),
+                    s.to_bytes()
+                        .len()
+                        .try_into()
+                        .or(Err(StatusCode::BAD_VALUE))?,
+                ))
+            },
+        }
+    }
+}
+
+impl SerializeArray for Option<&CStr> {}
+
+impl Serialize for CStr {
+    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+        Some(self).serialize(parcel)
+    }
+}
+
+impl Serialize for CString {
+    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+        Some(self.as_c_str()).serialize(parcel)
+    }
+}
+
+impl SerializeArray for CString {}
+
+impl SerializeOption for CString {
+    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+        SerializeOption::serialize_option(this.map(CString::as_c_str), parcel)
+    }
+}
+
+impl SerializeArray for Option<CString> {}
+
+impl Serialize for String {
+    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+        Some(self.as_str()).serialize(parcel)
+    }
+}
+
+impl SerializeArray for String {}
+
+impl SerializeOption for String {
+    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+        SerializeOption::serialize_option(this.map(String::as_str), parcel)
+    }
+}
+
+impl SerializeArray for Option<String> {}
+
+impl Deserialize for Option<CString> {
+    fn deserialize(parcel: &Parcel) -> Result<Self> {
+        let mut vec: Option<Vec<u8>> = None;
+        let status = unsafe {
+            // Safety: `Parcel` always contains a valid pointer to an `AParcel`.
+            // `Option<Vec<u8>>` is equivalent to the expected `Option<Vec<i8>>`
+            // for `allocate_vec`, so `vec` is safe to pass as the opaque data
+            // pointer on platforms where char is signed.
+            sys::AParcel_readString(
+                parcel.as_native(),
+                &mut vec as *mut _ as *mut c_void,
+                Some(allocate_vec),
+            )
+        };
+
+        status_result(status)?;
+        vec.map(|mut s| {
+            // The vector includes a null-terminator and CString::new requires
+            // no nulls, including terminating.
+            s.pop();
+            CString::new(s).or(Err(StatusCode::BAD_VALUE))
+        })
+        .transpose()
+    }
+}
+
+impl DeserializeArray for Option<CString> {}
+
+impl DeserializeOption for String {
+    fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> {
+        let c_str = <Option<CString>>::deserialize(parcel)?;
+        c_str
+            .map(|s| s.into_string().or(Err(StatusCode::BAD_VALUE)))
+            .transpose()
+    }
+}
+
+impl DeserializeArray for Option<String> {}
+
+impl Deserialize for String {
+    fn deserialize(parcel: &Parcel) -> Result<Self> {
+        Deserialize::deserialize(parcel)
+            .transpose()
+            .unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
+    }
+}
+
+impl DeserializeArray for String {}
+
+impl SerializeOption for str {
+    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+        match this {
+            None => parcel.write(&-1i32),
+            Some(s) => {
+                let c_str = CString::new(s).or(Err(StatusCode::BAD_VALUE))?;
+                parcel.write(&c_str)
+            }
+        }
+    }
+}
+
+impl Serialize for str {
+    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+        Some(self).serialize(parcel)
+    }
+}
+
+impl SerializeArray for &str {}
+
+impl SerializeArray for Option<&str> {}
+
+impl<T: SerializeArray> Serialize for [T] {
+    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+        SerializeArray::serialize_array(self, parcel)
+    }
+}
+
+impl<T: SerializeArray> Serialize for Vec<T> {
+    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+        SerializeArray::serialize_array(&self[..], parcel)
+    }
+}
+
+impl<T: SerializeArray> SerializeOption for [T] {
+    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+        if let Some(v) = this {
+            SerializeArray::serialize_array(v, parcel)
+        } else {
+            parcel.write(&-1i32)
+        }
+    }
+}
+
+impl<T: SerializeArray> SerializeOption for Vec<T> {
+    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+        SerializeOption::serialize_option(this.map(Vec::as_slice), parcel)
+    }
+}
+
+impl<T: DeserializeArray> Deserialize for Vec<T> {
+    fn deserialize(parcel: &Parcel) -> Result<Self> {
+        DeserializeArray::deserialize_array(parcel)
+            .transpose()
+            .unwrap_or(Err(StatusCode::UNEXPECTED_NULL))
+    }
+}
+
+impl<T: DeserializeArray> DeserializeOption for Vec<T> {
+    fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> {
+        DeserializeArray::deserialize_array(parcel)
+    }
+}
+
+impl Serialize for Status {
+    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+        unsafe {
+            // Safety: `Parcel` always contains a valid pointer to an `AParcel`
+            // and `Status` always contains a valid pointer to an `AStatus`, so
+            // both parameters are valid and safe. This call does not take
+            // ownership of either of its parameters.
+            status_result(sys::AParcel_writeStatusHeader(
+                parcel.as_native_mut(),
+                self.as_native(),
+            ))
+        }
+    }
+}
+
+impl Deserialize for Status {
+    fn deserialize(parcel: &Parcel) -> Result<Self> {
+        let mut status_ptr = ptr::null_mut();
+        let ret_status = unsafe {
+            // Safety: `Parcel` always contains a valid pointer to an
+            // `AParcel`. We pass a mutable out pointer which will be
+            // assigned a valid `AStatus` pointer if the function returns
+            // status OK. This function passes ownership of the status
+            // pointer to the caller, if it was assigned.
+            sys::AParcel_readStatusHeader(parcel.as_native(), &mut status_ptr)
+        };
+        status_result(ret_status)?;
+        Ok(unsafe {
+            // Safety: At this point, the return status of the read call was ok,
+            // so we know that `status_ptr` is a valid, owned pointer to an
+            // `AStatus`, from which we can safely construct a `Status` object.
+            Status::from_ptr(status_ptr)
+        })
+    }
+}
+
+impl<T: Serialize + ?Sized> Serialize for Box<T> {
+    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+        Serialize::serialize(&**self, parcel)
+    }
+}
+
+impl<T: SerializeOption + ?Sized> SerializeOption for Box<T> {
+    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+        SerializeOption::serialize_option(this.map(|b| &**b), parcel)
+    }
+}
+
+impl<T: FromIBinder + ?Sized> Deserialize for Box<T> {
+    fn deserialize(parcel: &Parcel) -> Result<Self> {
+        let ibinder: SpIBinder = parcel.read()?;
+        FromIBinder::try_from(ibinder)
+    }
+}
+
+impl<T: FromIBinder + ?Sized> DeserializeOption for Box<T> {
+    fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> {
+        let ibinder: Option<SpIBinder> = parcel.read()?;
+        ibinder.map(FromIBinder::try_from).transpose()
+    }
+}
+
+// We need these to support Option<&T> for all T
+impl<T: Serialize + ?Sized> Serialize for &T {
+    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+        Serialize::serialize(*self, parcel)
+    }
+}
+
+impl<T: SerializeOption + ?Sized> SerializeOption for &T {
+    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+        SerializeOption::serialize_option(this.copied(), parcel)
+    }
+}
+
+impl<T: SerializeOption> Serialize for Option<T> {
+    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+        SerializeOption::serialize_option(self.as_ref(), parcel)
+    }
+}
+
+impl<T: DeserializeOption> Deserialize for Option<T> {
+    fn deserialize(parcel: &Parcel) -> Result<Self> {
+        DeserializeOption::deserialize_option(parcel)
+    }
+}
+
+#[test]
+fn test_custom_parcelable() {
+    use crate::binder::Interface;
+    use crate::native::Binder;
+    let mut service = Binder::new(()).as_binder();
+
+    struct Custom(u32, bool, String, Vec<String>);
+
+    impl Serialize for Custom {
+        fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+            self.0.serialize(parcel)?;
+            self.1.serialize(parcel)?;
+            self.2.serialize(parcel)?;
+            self.3.serialize(parcel)
+        }
+    }
+
+    impl Deserialize for Custom {
+        fn deserialize(parcel: &Parcel) -> Result<Self> {
+            Ok(Custom(
+                parcel.read()?,
+                parcel.read()?,
+                parcel.read()?,
+                parcel.read::<Option<Vec<String>>>()?.unwrap(),
+            ))
+        }
+    }
+
+    let string8 = "Custom Parcelable".to_string();
+
+    let s1 = "str1".to_string();
+    let s2 = "str2".to_string();
+    let s3 = "str3".to_string();
+
+    let strs = vec![s1, s2, s3];
+
+    let custom = Custom(123_456_789, true, string8, strs);
+
+    let mut parcel = Parcel::new_for_test(&mut service).unwrap();
+    let start = parcel.get_data_position();
+
+    assert!(custom.serialize(&mut parcel).is_ok());
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    let custom2 = Custom::deserialize(&parcel).unwrap();
+
+    assert_eq!(custom2.0, 123_456_789);
+    assert!(custom2.1);
+    assert_eq!(custom2.2, custom.2);
+    assert_eq!(custom2.3, custom.3);
+}
+
+#[test]
+#[allow(clippy::excessive_precision)]
+fn test_slice_parcelables() {
+    use crate::binder::Interface;
+    use crate::native::Binder;
+    let mut service = Binder::new(()).as_binder();
+
+    let bools = [true, false, false, true];
+
+    let mut parcel = Parcel::new_for_test(&mut service).unwrap();
+    let start = parcel.get_data_position();
+
+    assert!(bools.serialize(&mut parcel).is_ok());
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert_eq!(parcel.read::<u32>().unwrap(), 4);
+    assert_eq!(parcel.read::<u32>().unwrap(), 1);
+    assert_eq!(parcel.read::<u32>().unwrap(), 0);
+    assert_eq!(parcel.read::<u32>().unwrap(), 0);
+    assert_eq!(parcel.read::<u32>().unwrap(), 1);
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    let vec = Vec::<bool>::deserialize(&parcel).unwrap();
+
+    assert_eq!(vec, [true, false, false, true]);
+
+    let u8s = [101u8, 255, 42, 117];
+
+    let mut parcel = Parcel::new_for_test(&mut service).unwrap();
+    let start = parcel.get_data_position();
+
+    assert!(parcel.write(&u8s[..]).is_ok());
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+    assert_eq!(parcel.read::<u32>().unwrap(), 0x752aff65); // bytes
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    let vec = Vec::<u8>::deserialize(&parcel).unwrap();
+    assert_eq!(vec, [101, 255, 42, 117]);
+
+    let i8s = [-128i8, 127, 42, -117];
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert!(parcel.write(&i8s[..]).is_ok());
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+    assert_eq!(parcel.read::<u32>().unwrap(), 0x8b2a7f80); // bytes
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    let vec = Vec::<u8>::deserialize(&parcel).unwrap();
+    assert_eq!(vec, [-128i8 as u8, 127, 42, -117i8 as u8]);
+
+    let u16s = [u16::max_value(), 12_345, 42, 117];
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+    assert!(u16s.serialize(&mut parcel).is_ok());
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+    assert_eq!(parcel.read::<u32>().unwrap(), 0xffff); // u16::max_value()
+    assert_eq!(parcel.read::<u32>().unwrap(), 12345); // 12,345
+    assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
+    assert_eq!(parcel.read::<u32>().unwrap(), 117); // 117
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    let vec = Vec::<u16>::deserialize(&parcel).unwrap();
+
+    assert_eq!(vec, [u16::max_value(), 12_345, 42, 117]);
+
+    let i16s = [i16::max_value(), i16::min_value(), 42, -117];
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+    assert!(i16s.serialize(&mut parcel).is_ok());
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+    assert_eq!(parcel.read::<u32>().unwrap(), 0x7fff); // i16::max_value()
+    assert_eq!(parcel.read::<u32>().unwrap(), 0x8000); // i16::min_value()
+    assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
+    assert_eq!(parcel.read::<u32>().unwrap(), 0xff8b); // -117
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    let vec = Vec::<i16>::deserialize(&parcel).unwrap();
+
+    assert_eq!(vec, [i16::max_value(), i16::min_value(), 42, -117]);
+
+    let u32s = [u32::max_value(), 12_345, 42, 117];
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+    assert!(u32s.serialize(&mut parcel).is_ok());
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+    assert_eq!(parcel.read::<u32>().unwrap(), 0xffffffff); // u32::max_value()
+    assert_eq!(parcel.read::<u32>().unwrap(), 12345); // 12,345
+    assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
+    assert_eq!(parcel.read::<u32>().unwrap(), 117); // 117
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    let vec = Vec::<u32>::deserialize(&parcel).unwrap();
+
+    assert_eq!(vec, [u32::max_value(), 12_345, 42, 117]);
+
+    let i32s = [i32::max_value(), i32::min_value(), 42, -117];
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+    assert!(i32s.serialize(&mut parcel).is_ok());
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    assert_eq!(parcel.read::<u32>().unwrap(), 4); // 4 items
+    assert_eq!(parcel.read::<u32>().unwrap(), 0x7fffffff); // i32::max_value()
+    assert_eq!(parcel.read::<u32>().unwrap(), 0x80000000); // i32::min_value()
+    assert_eq!(parcel.read::<u32>().unwrap(), 42); // 42
+    assert_eq!(parcel.read::<u32>().unwrap(), 0xffffff8b); // -117
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    let vec = Vec::<i32>::deserialize(&parcel).unwrap();
+
+    assert_eq!(vec, [i32::max_value(), i32::min_value(), 42, -117]);
+
+    let u64s = [u64::max_value(), 12_345, 42, 117];
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+    assert!(u64s.serialize(&mut parcel).is_ok());
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    let vec = Vec::<u64>::deserialize(&parcel).unwrap();
+
+    assert_eq!(vec, [u64::max_value(), 12_345, 42, 117]);
+
+    let i64s = [i64::max_value(), i64::min_value(), 42, -117];
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+    assert!(i64s.serialize(&mut parcel).is_ok());
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    let vec = Vec::<i64>::deserialize(&parcel).unwrap();
+
+    assert_eq!(vec, [i64::max_value(), i64::min_value(), 42, -117]);
+
+    let f32s = [
+        std::f32::NAN,
+        std::f32::INFINITY,
+        1.23456789,
+        std::f32::EPSILON,
+    ];
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+    assert!(f32s.serialize(&mut parcel).is_ok());
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    let vec = Vec::<f32>::deserialize(&parcel).unwrap();
+
+    // NAN != NAN so we can't use it in the assert_eq:
+    assert!(vec[0].is_nan());
+    assert_eq!(vec[1..], f32s[1..]);
+
+    let f64s = [
+        std::f64::NAN,
+        std::f64::INFINITY,
+        1.234567890123456789,
+        std::f64::EPSILON,
+    ];
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+    assert!(f64s.serialize(&mut parcel).is_ok());
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    let vec = Vec::<f64>::deserialize(&parcel).unwrap();
+
+    // NAN != NAN so we can't use it in the assert_eq:
+    assert!(vec[0].is_nan());
+    assert_eq!(vec[1..], f64s[1..]);
+
+    let s1 = "Hello, Binder!";
+    let s2 = "This is a utf8 string.";
+    let s3 = "Some more text here.";
+
+    let strs = [s1, s2, s3];
+
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+    assert!(strs.serialize(&mut parcel).is_ok());
+    unsafe {
+        assert!(parcel.set_data_position(start).is_ok());
+    }
+
+    let vec = Vec::<String>::deserialize(&parcel).unwrap();
+
+    assert_eq!(vec, strs);
+}
diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs
new file mode 100644
index 0000000..f9519b4
--- /dev/null
+++ b/libs/binder/rust/src/proxy.rs
@@ -0,0 +1,512 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! Rust API for interacting with a remote binder service.
+
+use crate::binder::{
+    AsNative, FromIBinder, IBinder, Interface, InterfaceClass, TransactionCode, TransactionFlags,
+};
+use crate::error::{status_result, Result, StatusCode};
+use crate::parcel::{
+    Deserialize, DeserializeArray, DeserializeOption, Parcel, Serialize, SerializeArray,
+    SerializeOption,
+};
+use crate::sys;
+
+use std::convert::TryInto;
+use std::ffi::{c_void, CString};
+use std::os::unix::io::AsRawFd;
+use std::ptr;
+
+/// A strong reference to a Binder remote object.
+///
+/// This struct encapsulates the generic C++ `sp<IBinder>` class. This wrapper
+/// is untyped; typed interface access is implemented by the AIDL compiler.
+pub struct SpIBinder(*mut sys::AIBinder);
+
+/// # Safety
+///
+/// An `SpIBinder` is a handle to a C++ IBinder, which is thread-safe
+unsafe impl Send for SpIBinder {}
+
+impl SpIBinder {
+    /// Create an `SpIBinder` wrapper object from a raw `AIBinder` pointer.
+    ///
+    /// # Safety
+    ///
+    /// This constructor is safe iff `ptr` is a null pointer or a valid pointer
+    /// to an `AIBinder`.
+    ///
+    /// In the non-null case, this method conceptually takes ownership of a strong
+    /// reference to the object, so `AIBinder_incStrong` must have been called
+    /// on the pointer before passing it to this constructor. This is generally
+    /// done by Binder NDK methods that return an `AIBinder`, but care should be
+    /// taken to ensure this invariant.
+    ///
+    /// All `SpIBinder` objects that are constructed will hold a valid pointer
+    /// to an `AIBinder`, which will remain valid for the entire lifetime of the
+    /// `SpIBinder` (we keep a strong reference, and only decrement on drop).
+    pub(crate) unsafe fn from_raw(ptr: *mut sys::AIBinder) -> Option<Self> {
+        ptr.as_mut().map(|p| Self(p))
+    }
+
+    /// Return true if this binder object is hosted in a different process than
+    /// the current one.
+    pub fn is_remote(&self) -> bool {
+        unsafe {
+            // Safety: `SpIBinder` guarantees that it always contains a valid
+            // `AIBinder` pointer.
+            sys::AIBinder_isRemote(self.as_native())
+        }
+    }
+
+    /// Try to convert this Binder object into a trait object for the given
+    /// Binder interface.
+    ///
+    /// If this object does not implement the expected interface, the error
+    /// `StatusCode::BAD_TYPE` is returned.
+    pub fn into_interface<I: FromIBinder + ?Sized>(self) -> Result<Box<I>> {
+        FromIBinder::try_from(self)
+    }
+
+    /// Return the interface class of this binder object, if associated with
+    /// one.
+    pub(crate) fn get_class(&mut self) -> Option<InterfaceClass> {
+        unsafe {
+            // Safety: `SpIBinder` guarantees that it always contains a valid
+            // `AIBinder` pointer. `AIBinder_getClass` returns either a null
+            // pointer or a valid pointer to an `AIBinder_Class`. After mapping
+            // null to None, we can safely construct an `InterfaceClass` if the
+            // pointer was non-null.
+            let class = sys::AIBinder_getClass(self.as_native_mut());
+            class.as_ref().map(|p| InterfaceClass::from_ptr(p))
+        }
+    }
+}
+
+/// An object that can be associate with an [`InterfaceClass`].
+pub trait AssociateClass {
+    /// Check if this object is a valid object for the given interface class
+    /// `I`.
+    ///
+    /// Returns `Some(self)` if this is a valid instance of the interface, and
+    /// `None` otherwise.
+    ///
+    /// Classes constructed by `InterfaceClass` are unique per type, so
+    /// repeatedly calling this method for the same `InterfaceClass` is allowed.
+    fn associate_class(&mut self, class: InterfaceClass) -> bool;
+}
+
+impl AssociateClass for SpIBinder {
+    fn associate_class(&mut self, class: InterfaceClass) -> bool {
+        unsafe {
+            // Safety: `SpIBinder` guarantees that it always contains a valid
+            // `AIBinder` pointer. An `InterfaceClass` can always be converted
+            // into a valid `AIBinder_Class` pointer, so these parameters are
+            // always safe.
+            sys::AIBinder_associateClass(self.as_native_mut(), class.into())
+        }
+    }
+}
+
+impl Clone for SpIBinder {
+    fn clone(&self) -> Self {
+        unsafe {
+            // Safety: Cloning a strong reference must increment the reference
+            // count. We are guaranteed by the `SpIBinder` constructor
+            // invariants that `self.0` is always a valid `AIBinder` pointer.
+            sys::AIBinder_incStrong(self.0);
+        }
+        Self(self.0)
+    }
+}
+
+impl Drop for SpIBinder {
+    // We hold a strong reference to the IBinder in SpIBinder and need to give up
+    // this reference on drop.
+    fn drop(&mut self) {
+        unsafe {
+            // Safety: SpIBinder always holds a valid `AIBinder` pointer, so we
+            // know this pointer is safe to pass to `AIBinder_decStrong` here.
+            sys::AIBinder_decStrong(self.as_native_mut());
+        }
+    }
+}
+
+impl<T: AsNative<sys::AIBinder>> IBinder for T {
+    /// Perform a binder transaction
+    fn transact<F: FnOnce(&mut Parcel) -> Result<()>>(
+        &self,
+        code: TransactionCode,
+        flags: TransactionFlags,
+        input_callback: F,
+    ) -> Result<Parcel> {
+        let mut input = ptr::null_mut();
+        let status = unsafe {
+            // Safety: `SpIBinder` guarantees that `self` always contains a
+            // valid pointer to an `AIBinder`. It is safe to cast from an
+            // immutable pointer to a mutable pointer here, because
+            // `AIBinder_prepareTransaction` only calls immutable `AIBinder`
+            // methods but the parameter is unfortunately not marked as const.
+            //
+            // After the call, input will be either a valid, owned `AParcel`
+            // pointer, or null.
+            sys::AIBinder_prepareTransaction(self.as_native() as *mut sys::AIBinder, &mut input)
+        };
+        status_result(status)?;
+        let mut input = unsafe {
+            // Safety: At this point, `input` is either a valid, owned `AParcel`
+            // pointer, or null. `Parcel::owned` safely handles both cases,
+            // taking ownership of the parcel.
+            Parcel::owned(input).ok_or(StatusCode::UNEXPECTED_NULL)?
+        };
+        input_callback(&mut input)?;
+        let mut reply = ptr::null_mut();
+        let status = unsafe {
+            // Safety: `SpIBinder` guarantees that `self` always contains a
+            // valid pointer to an `AIBinder`. Although `IBinder::transact` is
+            // not a const method, it is still safe to cast our immutable
+            // pointer to mutable for the call. First, `IBinder::transact` is
+            // thread-safe, so concurrency is not an issue. The only way that
+            // `transact` can affect any visible, mutable state in the current
+            // process is by calling `onTransact` for a local service. However,
+            // in order for transactions to be thread-safe, this method must
+            // dynamically lock its data before modifying it. We enforce this
+            // property in Rust by requiring `Sync` for remotable objects and
+            // only providing `on_transact` with an immutable reference to
+            // `self`.
+            //
+            // This call takes ownership of the `input` parcel pointer, and
+            // passes ownership of the `reply` out parameter to its caller. It
+            // does not affect ownership of the `binder` parameter.
+            sys::AIBinder_transact(
+                self.as_native() as *mut sys::AIBinder,
+                code,
+                &mut input.into_raw(),
+                &mut reply,
+                flags,
+            )
+        };
+        status_result(status)?;
+
+        unsafe {
+            // Safety: `reply` is either a valid `AParcel` pointer or null
+            // after the call to `AIBinder_transact` above, so we can
+            // construct a `Parcel` out of it. `AIBinder_transact` passes
+            // ownership of the `reply` parcel to Rust, so we need to
+            // construct an owned variant. `Parcel::owned` takes ownership
+            // of the parcel pointer.
+            Parcel::owned(reply).ok_or(StatusCode::UNEXPECTED_NULL)
+        }
+    }
+
+    fn is_binder_alive(&self) -> bool {
+        unsafe {
+            // Safety: `SpIBinder` guarantees that `self` always contains a
+            // valid pointer to an `AIBinder`.
+            //
+            // This call does not affect ownership of its pointer parameter.
+            sys::AIBinder_isAlive(self.as_native())
+        }
+    }
+
+    fn ping_binder(&mut self) -> Result<()> {
+        let status = unsafe {
+            // Safety: `SpIBinder` guarantees that `self` always contains a
+            // valid pointer to an `AIBinder`.
+            //
+            // This call does not affect ownership of its pointer parameter.
+            sys::AIBinder_ping(self.as_native_mut())
+        };
+        status_result(status)
+    }
+
+    fn dump<F: AsRawFd>(&mut self, fp: &F, args: &[&str]) -> Result<()> {
+        let args: Vec<_> = args.iter().map(|a| CString::new(*a).unwrap()).collect();
+        let mut arg_ptrs: Vec<_> = args.iter().map(|a| a.as_ptr()).collect();
+        let status = unsafe {
+            // Safety: `SpIBinder` guarantees that `self` always contains a
+            // valid pointer to an `AIBinder`. `AsRawFd` guarantees that the
+            // file descriptor parameter is always be a valid open file. The
+            // `args` pointer parameter is a valid pointer to an array of C
+            // strings that will outlive the call since `args` lives for the
+            // whole function scope.
+            //
+            // This call does not affect ownership of its binder pointer
+            // parameter and does not take ownership of the file or args array
+            // parameters.
+            sys::AIBinder_dump(
+                self.as_native_mut(),
+                fp.as_raw_fd(),
+                arg_ptrs.as_mut_ptr(),
+                arg_ptrs.len().try_into().unwrap(),
+            )
+        };
+        status_result(status)
+    }
+
+    fn get_extension(&mut self) -> Result<Option<SpIBinder>> {
+        let mut out = ptr::null_mut();
+        let status = unsafe {
+            // Safety: `SpIBinder` guarantees that `self` always contains a
+            // valid pointer to an `AIBinder`. After this call, the `out`
+            // parameter will be either null, or a valid pointer to an
+            // `AIBinder`.
+            //
+            // This call passes ownership of the out pointer to its caller
+            // (assuming it is set to a non-null value).
+            sys::AIBinder_getExtension(self.as_native_mut(), &mut out)
+        };
+        let ibinder = unsafe {
+            // Safety: The call above guarantees that `out` is either null or a
+            // valid, owned pointer to an `AIBinder`, both of which are safe to
+            // pass to `SpIBinder::from_raw`.
+            SpIBinder::from_raw(out)
+        };
+
+        status_result(status)?;
+        Ok(ibinder)
+    }
+
+    fn link_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
+        status_result(unsafe {
+            // Safety: `SpIBinder` guarantees that `self` always contains a
+            // valid pointer to an `AIBinder`. `recipient` can always be
+            // converted into a valid pointer to an
+            // `AIBinder_DeatRecipient`. Any value is safe to pass as the
+            // cookie, although we depend on this value being set by
+            // `get_cookie` when the death recipient callback is called.
+            sys::AIBinder_linkToDeath(
+                self.as_native_mut(),
+                recipient.as_native_mut(),
+                recipient.get_cookie(),
+            )
+        })
+    }
+
+    fn unlink_to_death(&mut self, recipient: &mut DeathRecipient) -> Result<()> {
+        status_result(unsafe {
+            // Safety: `SpIBinder` guarantees that `self` always contains a
+            // valid pointer to an `AIBinder`. `recipient` can always be
+            // converted into a valid pointer to an
+            // `AIBinder_DeatRecipient`. Any value is safe to pass as the
+            // cookie, although we depend on this value being set by
+            // `get_cookie` when the death recipient callback is called.
+            sys::AIBinder_unlinkToDeath(
+                self.as_native_mut(),
+                recipient.as_native_mut(),
+                recipient.get_cookie(),
+            )
+        })
+    }
+}
+
+impl Serialize for SpIBinder {
+    fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
+        parcel.write_binder(Some(self))
+    }
+}
+
+impl SerializeOption for SpIBinder {
+    fn serialize_option(this: Option<&Self>, parcel: &mut Parcel) -> Result<()> {
+        parcel.write_binder(this)
+    }
+}
+
+impl SerializeArray for SpIBinder {}
+impl SerializeArray for Option<&SpIBinder> {}
+
+impl Deserialize for SpIBinder {
+    fn deserialize(parcel: &Parcel) -> Result<SpIBinder> {
+        parcel.read_binder().transpose().unwrap()
+    }
+}
+
+impl DeserializeOption for SpIBinder {
+    fn deserialize_option(parcel: &Parcel) -> Result<Option<SpIBinder>> {
+        parcel.read_binder()
+    }
+}
+
+impl DeserializeArray for SpIBinder {}
+impl DeserializeArray for Option<SpIBinder> {}
+
+/// A weak reference to a Binder remote object.
+///
+/// This struct encapsulates the C++ `wp<IBinder>` class. However, this wrapper
+/// is untyped, so properly typed versions implementing a particular binder
+/// interface should be crated with [`declare_binder_interface!`].
+pub struct WpIBinder(*mut sys::AIBinder_Weak);
+
+impl WpIBinder {
+    /// Create a new weak reference from an object that can be converted into a
+    /// raw `AIBinder` pointer.
+    pub fn new<B: AsNative<sys::AIBinder>>(binder: &mut B) -> WpIBinder {
+        let ptr = unsafe {
+            // Safety: `SpIBinder` guarantees that `binder` always contains a
+            // valid pointer to an `AIBinder`.
+            sys::AIBinder_Weak_new(binder.as_native_mut())
+        };
+        assert!(!ptr.is_null());
+        Self(ptr)
+    }
+}
+
+/// Rust wrapper around DeathRecipient objects.
+#[repr(C)]
+pub struct DeathRecipient {
+    recipient: *mut sys::AIBinder_DeathRecipient,
+    callback: Box<dyn Fn() + Send + 'static>,
+}
+
+impl DeathRecipient {
+    /// Create a new death recipient that will call the given callback when its
+    /// associated object dies.
+    pub fn new<F>(callback: F) -> DeathRecipient
+    where
+        F: Fn() + Send + 'static,
+    {
+        let callback = Box::new(callback);
+        let recipient = unsafe {
+            // Safety: The function pointer is a valid death recipient callback.
+            //
+            // This call returns an owned `AIBinder_DeathRecipient` pointer
+            // which must be destroyed via `AIBinder_DeathRecipient_delete` when
+            // no longer needed.
+            sys::AIBinder_DeathRecipient_new(Some(Self::binder_died::<F>))
+        };
+        DeathRecipient {
+            recipient,
+            callback,
+        }
+    }
+
+    /// Get the opaque cookie that identifies this death recipient.
+    ///
+    /// This cookie will be used to link and unlink this death recipient to a
+    /// binder object and will be passed to the `binder_died` callback as an
+    /// opaque userdata pointer.
+    fn get_cookie(&self) -> *mut c_void {
+        &*self.callback as *const _ as *mut c_void
+    }
+
+    /// Callback invoked from C++ when the binder object dies.
+    ///
+    /// # Safety
+    ///
+    /// The `cookie` parameter must have been created with the `get_cookie`
+    /// method of this object.
+    unsafe extern "C" fn binder_died<F>(cookie: *mut c_void)
+    where
+        F: Fn() + Send + 'static,
+    {
+        let callback = (cookie as *mut F).as_ref().unwrap();
+        callback();
+    }
+}
+
+/// # Safety
+///
+/// A `DeathRecipient` is always constructed with a valid raw pointer to an
+/// `AIBinder_DeathRecipient`, so it is always type-safe to extract this
+/// pointer.
+unsafe impl AsNative<sys::AIBinder_DeathRecipient> for DeathRecipient {
+    fn as_native(&self) -> *const sys::AIBinder_DeathRecipient {
+        self.recipient
+    }
+
+    fn as_native_mut(&mut self) -> *mut sys::AIBinder_DeathRecipient {
+        self.recipient
+    }
+}
+
+impl Drop for DeathRecipient {
+    fn drop(&mut self) {
+        unsafe {
+            // Safety: `self.recipient` is always a valid, owned
+            // `AIBinder_DeathRecipient` pointer returned by
+            // `AIBinder_DeathRecipient_new` when `self` was created. This
+            // delete method can only be called once when `self` is dropped.
+            sys::AIBinder_DeathRecipient_delete(self.recipient);
+        }
+    }
+}
+
+/// Generic interface to remote binder objects.
+///
+/// Corresponds to the C++ `BpInterface` class.
+pub trait Proxy: Sized + Interface {
+    /// The Binder interface descriptor string.
+    ///
+    /// This string is a unique identifier for a Binder interface, and should be
+    /// the same between all implementations of that interface.
+    fn get_descriptor() -> &'static str;
+
+    /// Create a new interface from the given proxy, if it matches the expected
+    /// type of this interface.
+    fn from_binder(binder: SpIBinder) -> Result<Self>;
+}
+
+/// # Safety
+///
+/// This is a convenience method that wraps `AsNative` for `SpIBinder` to allow
+/// invocation of `IBinder` methods directly from `Interface` objects. It shares
+/// the same safety as the implementation for `SpIBinder`.
+unsafe impl<T: Proxy> AsNative<sys::AIBinder> for T {
+    fn as_native(&self) -> *const sys::AIBinder {
+        self.as_binder().as_native()
+    }
+
+    fn as_native_mut(&mut self) -> *mut sys::AIBinder {
+        self.as_binder().as_native_mut()
+    }
+}
+
+/// Retrieve an existing service, blocking for a few seconds if it doesn't yet
+/// exist.
+pub fn get_service(name: &str) -> Option<SpIBinder> {
+    let name = CString::new(name).ok()?;
+    unsafe {
+        // Safety: `AServiceManager_getService` returns either a null pointer or
+        // a valid pointer to an owned `AIBinder`. Either of these values is
+        // safe to pass to `SpIBinder::from_raw`.
+        SpIBinder::from_raw(sys::AServiceManager_getService(name.as_ptr()))
+    }
+}
+
+/// Retrieve an existing service for a particular interface, blocking for a few
+/// seconds if it doesn't yet exist.
+pub fn get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Box<T>> {
+    let service = get_service(name);
+    match service {
+        Some(service) => FromIBinder::try_from(service),
+        None => Err(StatusCode::NAME_NOT_FOUND),
+    }
+}
+
+/// # Safety
+///
+/// `SpIBinder` guarantees that `binder` always contains a valid pointer to an
+/// `AIBinder`, so we can trivially extract this pointer here.
+unsafe impl AsNative<sys::AIBinder> for SpIBinder {
+    fn as_native(&self) -> *const sys::AIBinder {
+        self.0
+    }
+
+    fn as_native_mut(&mut self) -> *mut sys::AIBinder {
+        self.0
+    }
+}
diff --git a/libs/binder/rust/src/state.rs b/libs/binder/rust/src/state.rs
new file mode 100644
index 0000000..992f074
--- /dev/null
+++ b/libs/binder/rust/src/state.rs
@@ -0,0 +1,101 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+use crate::sys;
+
+use libc::{pid_t, uid_t};
+
+/// Static utility functions to manage Binder process state.
+pub struct ProcessState;
+
+impl ProcessState {
+    /// Start the Binder IPC thread pool
+    pub fn start_thread_pool() {
+        unsafe {
+            // Safety: Safe FFI
+            sys::ABinderProcess_startThreadPool();
+        }
+    }
+
+    /// Set the maximum number of threads that can be started in the threadpool.
+    ///
+    /// By default, after startThreadPool is called, this is 15. If it is called
+    /// additional times, it will only prevent the kernel from starting new
+    /// threads and will not delete already existing threads.
+    pub fn set_thread_pool_max_thread_count(num_threads: u32) {
+        unsafe {
+            // Safety: Safe FFI
+            sys::ABinderProcess_setThreadPoolMaxThreadCount(num_threads);
+        }
+    }
+
+    /// Block on the Binder IPC thread pool
+    pub fn join_thread_pool() {
+        unsafe {
+            // Safety: Safe FFI
+            sys::ABinderProcess_joinThreadPool();
+        }
+    }
+}
+
+/// Static utility functions to manage Binder thread state.
+pub struct ThreadState;
+
+impl ThreadState {
+    /// This returns the calling UID assuming that this thread is called from a
+    /// thread that is processing a binder transaction (for instance, in the
+    /// implementation of
+    /// [`Remotable::on_transact`](crate::Remotable::on_transact)).
+    ///
+    /// This can be used with higher-level system services to determine the
+    /// caller's identity and check permissions.
+    ///
+    /// Available since API level 29.
+    ///
+    /// \return calling uid or the current process's UID if this thread isn't
+    /// processing a transaction.
+    pub fn get_calling_uid() -> uid_t {
+        unsafe {
+            // Safety: Safe FFI
+            sys::AIBinder_getCallingUid()
+        }
+    }
+
+    /// This returns the calling PID assuming that this thread is called from a
+    /// thread that is processing a binder transaction (for instance, in the
+    /// implementation of
+    /// [`Remotable::on_transact`](crate::Remotable::on_transact)).
+    ///
+    /// This can be used with higher-level system services to determine the
+    /// caller's identity and check permissions. However, when doing this, one
+    /// should be aware of possible TOCTOU problems when the calling process
+    /// dies and is replaced with another process with elevated permissions and
+    /// the same PID.
+    ///
+    /// Available since API level 29.
+    ///
+    /// \return calling pid or the current process's PID if this thread isn't
+    /// processing a transaction.
+    ///
+    /// If the transaction being processed is a oneway transaction, then this
+    /// method will return 0.
+    pub fn get_calling_pid() -> pid_t {
+        unsafe {
+            // Safety: Safe FFI
+            sys::AIBinder_getCallingPid()
+        }
+    }
+}
diff --git a/libs/binder/rust/tests/Android.bp b/libs/binder/rust/tests/Android.bp
new file mode 100644
index 0000000..7127110
--- /dev/null
+++ b/libs/binder/rust/tests/Android.bp
@@ -0,0 +1,24 @@
+rust_test {
+    name: "rustBinderTest",
+    srcs: ["integration.rs"],
+    rustlibs: [
+        "libbinder_rs",
+    ],
+    // For the binaries to be pushed properly as specified in AndroidTest.xml,
+    // this cannot be the same as the module name.
+    stem: "rustBinderTestClientBinary",
+    test_suites: ["general-tests"],
+}
+
+rust_test {
+    name: "rustBinderTestService",
+    srcs: ["integration.rs"],
+    rustlibs: [
+        "libbinder_rs",
+        "liblibc",
+    ],
+    // For the binaries to be pushed properly as specified in AndroidTest.xml,
+    // this cannot be the same as the module name.
+    stem: "rustBinderTestServiceBinary",
+    test_harness: false,
+}
diff --git a/libs/binder/rust/tests/AndroidTest.xml b/libs/binder/rust/tests/AndroidTest.xml
new file mode 100644
index 0000000..d8d735d
--- /dev/null
+++ b/libs/binder/rust/tests/AndroidTest.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2020 The Android Open Source Project
+
+     Licensed under the Apache License, Version 2.0 (the "License");
+     you may not use this file except in compliance with the License.
+     You may obtain a copy of the License at
+
+          http://www.apache.org/licenses/LICENSE-2.0
+
+     Unless required by applicable law or agreed to in writing, software
+     distributed under the License is distributed on an "AS IS" BASIS,
+     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+     See the License for the specific language governing permissions and
+     limitations under the License.
+-->
+<configuration description="Runs Binder Rust integration tests.">
+    <target_preparer class="com.android.tradefed.targetprep.RootTargetPreparer"/>
+    <target_preparer class="com.android.tradefed.targetprep.PushFilePreparer">
+        <option name="cleanup" value="true" />
+        <option name="push" value="rustBinderTestClientBinary->/data/local/tmp/rustBinderTest" />
+        <option name="push" value="rustBinderTestServiceBinary->/data/local/tmp/rustBinderTestService" />
+    </target_preparer>
+
+    <test class="com.android.tradefed.testtype.rust.RustBinaryTest" >
+        <option name="test-device-path" value="/data/local/tmp" />
+        <option name="module-name" value="rustBinderTest" />
+    </test>
+</configuration>
diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs
new file mode 100644
index 0000000..fe59416
--- /dev/null
+++ b/libs/binder/rust/tests/integration.rs
@@ -0,0 +1,371 @@
+/*
+ * Copyright (C) 2020 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+//! Rust Binder crate integration tests
+
+use binder::declare_binder_interface;
+use binder::parcel::Parcel;
+use binder::{Binder, IBinder, Interface, SpIBinder, TransactionCode};
+
+/// Name of service runner.
+///
+/// Must match the binary name in Android.bp
+const RUST_SERVICE_BINARY: &str = "rustBinderTestService";
+
+/// Binary to run a test service.
+///
+/// This needs to be in a separate process from the tests, so we spawn this
+/// binary as a child, providing the service name as an argument.
+fn main() -> Result<(), &'static str> {
+    // Ensure that we can handle all transactions on the main thread.
+    binder::ProcessState::set_thread_pool_max_thread_count(0);
+    binder::ProcessState::start_thread_pool();
+
+    let mut args = std::env::args().skip(1);
+    if args.len() < 1 || args.len() > 2 {
+        print_usage();
+        return Err("");
+    }
+    let service_name = args.next().ok_or_else(|| {
+        print_usage();
+        "Missing SERVICE_NAME argument"
+    })?;
+    let extension_name = args.next();
+
+    {
+        let mut service = Binder::new(BnTest(Box::new(TestService {
+            s: service_name.clone(),
+        })));
+        if let Some(extension_name) = extension_name {
+            let extension = BnTest::new_binder(TestService { s: extension_name });
+            service
+                .set_extension(&mut extension.as_binder())
+                .expect("Could not add extension");
+        }
+        binder::add_service(&service_name, service.as_binder())
+            .expect("Could not register service");
+    }
+
+    binder::ProcessState::join_thread_pool();
+    Err("Unexpected exit after join_thread_pool")
+}
+
+fn print_usage() {
+    eprintln!(
+        "Usage: {} SERVICE_NAME [EXTENSION_NAME]",
+        RUST_SERVICE_BINARY
+    );
+    eprintln!(concat!(
+        "Spawn a Binder test service identified by SERVICE_NAME,",
+        " optionally with an extesion named EXTENSION_NAME",
+    ));
+}
+
+#[derive(Clone)]
+struct TestService {
+    s: String,
+}
+
+impl Interface for TestService {}
+
+impl ITest for TestService {
+    fn test(&self) -> binder::Result<String> {
+        Ok(self.s.clone())
+    }
+}
+
+/// Trivial testing binder interface
+pub trait ITest: Interface {
+    /// Returns a test string
+    fn test(&self) -> binder::Result<String>;
+}
+
+declare_binder_interface! {
+    ITest["android.os.ITest"] {
+        native: BnTest(on_transact),
+        proxy: BpTest {
+            x: i32 = 100
+        },
+    }
+}
+
+fn on_transact(
+    service: &dyn ITest,
+    _code: TransactionCode,
+    _data: &Parcel,
+    reply: &mut Parcel,
+) -> binder::Result<()> {
+    reply.write(&service.test()?)?;
+    Ok(())
+}
+
+impl ITest for BpTest {
+    fn test(&self) -> binder::Result<String> {
+        let reply = self
+            .binder
+            .transact(SpIBinder::FIRST_CALL_TRANSACTION, 0, |_| Ok(()))?;
+        reply.read()
+    }
+}
+
+impl ITest for Binder<BnTest> {
+    fn test(&self) -> binder::Result<String> {
+        self.0.test()
+    }
+}
+
+#[cfg(test)]
+mod tests {
+    use std::fs::File;
+    use std::process::{Child, Command};
+    use std::sync::atomic::{AtomicBool, Ordering};
+    use std::sync::Arc;
+    use std::thread;
+    use std::time::Duration;
+
+    use binder::{DeathRecipient, FromIBinder, IBinder, SpIBinder, StatusCode};
+
+    use super::{ITest, RUST_SERVICE_BINARY};
+
+    pub struct ScopedServiceProcess(Child);
+
+    impl ScopedServiceProcess {
+        pub fn new(identifier: &str) -> Self {
+            Self::new_internal(identifier, None)
+        }
+
+        pub fn new_with_extension(identifier: &str, extension: &str) -> Self {
+            Self::new_internal(identifier, Some(extension))
+        }
+
+        fn new_internal(identifier: &str, extension: Option<&str>) -> Self {
+            let mut binary_path =
+                std::env::current_exe().expect("Could not retrieve current executable path");
+            binary_path.pop();
+            binary_path.push(RUST_SERVICE_BINARY);
+            let mut command = Command::new(&binary_path);
+            command.arg(identifier);
+            if let Some(ext) = extension {
+                command.arg(ext);
+            }
+            let child = command.spawn().expect("Could not start service");
+            Self(child)
+        }
+    }
+
+    impl Drop for ScopedServiceProcess {
+        fn drop(&mut self) {
+            self.0.kill().expect("Could not kill child process");
+            self.0
+                .wait()
+                .expect("Could not wait for child process to die");
+        }
+    }
+
+    #[test]
+    fn check_services() {
+        let mut sm = binder::get_service("manager").expect("Did not get manager binder service");
+        assert!(sm.is_binder_alive());
+        assert!(sm.ping_binder().is_ok());
+
+        assert!(binder::get_service("this_service_does_not_exist").is_none());
+        assert_eq!(
+            binder::get_interface::<dyn ITest>("this_service_does_not_exist").err(),
+            Some(StatusCode::NAME_NOT_FOUND)
+        );
+
+        // The service manager service isn't an ITest, so this must fail.
+        assert_eq!(
+            binder::get_interface::<dyn ITest>("manager").err(),
+            Some(StatusCode::BAD_TYPE)
+        );
+    }
+
+    #[test]
+    fn trivial_client() {
+        let service_name = "trivial_client_test";
+        let _process = ScopedServiceProcess::new(service_name);
+        let test_client: Box<dyn ITest> =
+            binder::get_interface(service_name).expect("Did not get manager binder service");
+        assert_eq!(test_client.test().unwrap(), "trivial_client_test");
+    }
+
+    fn register_death_notification(binder: &mut SpIBinder) -> (Arc<AtomicBool>, DeathRecipient) {
+        let binder_died = Arc::new(AtomicBool::new(false));
+
+        let mut death_recipient = {
+            let flag = binder_died.clone();
+            DeathRecipient::new(move || {
+                flag.store(true, Ordering::Relaxed);
+            })
+        };
+
+        binder
+            .link_to_death(&mut death_recipient)
+            .expect("link_to_death failed");
+
+        (binder_died, death_recipient)
+    }
+
+    /// Killing a remote service should unregister the service and trigger
+    /// death notifications.
+    #[test]
+    fn test_death_notifications() {
+        binder::ProcessState::start_thread_pool();
+
+        let service_name = "test_death_notifications";
+        let service_process = ScopedServiceProcess::new(service_name);
+        let mut remote = binder::get_service(service_name).expect("Could not retrieve service");
+
+        let (binder_died, _recipient) = register_death_notification(&mut remote);
+
+        drop(service_process);
+        remote
+            .ping_binder()
+            .expect_err("Service should have died already");
+
+        // Pause to ensure any death notifications get delivered
+        thread::sleep(Duration::from_secs(1));
+
+        assert!(
+            binder_died.load(Ordering::Relaxed),
+            "Did not receive death notification"
+        );
+    }
+
+    /// Test unregistering death notifications.
+    #[test]
+    fn test_unregister_death_notifications() {
+        binder::ProcessState::start_thread_pool();
+
+        let service_name = "test_unregister_death_notifications";
+        let service_process = ScopedServiceProcess::new(service_name);
+        let mut remote = binder::get_service(service_name).expect("Could not retrieve service");
+
+        let (binder_died, mut recipient) = register_death_notification(&mut remote);
+
+        remote
+            .unlink_to_death(&mut recipient)
+            .expect("Could not unlink death notifications");
+
+        drop(service_process);
+        remote
+            .ping_binder()
+            .expect_err("Service should have died already");
+
+        // Pause to ensure any death notifications get delivered
+        thread::sleep(Duration::from_secs(1));
+
+        assert!(
+            !binder_died.load(Ordering::Relaxed),
+            "Received unexpected death notification after unlinking",
+        );
+    }
+
+    /// Dropping a remote handle should unregister any death notifications.
+    #[test]
+    fn test_death_notification_registration_lifetime() {
+        binder::ProcessState::start_thread_pool();
+
+        let service_name = "test_death_notification_registration_lifetime";
+        let service_process = ScopedServiceProcess::new(service_name);
+        let mut remote = binder::get_service(service_name).expect("Could not retrieve service");
+
+        let (binder_died, _recipient) = register_death_notification(&mut remote);
+
+        // This should automatically unregister our death notification.
+        drop(remote);
+
+        drop(service_process);
+
+        // Pause to ensure any death notifications get delivered
+        thread::sleep(Duration::from_secs(1));
+
+        // We dropped the remote handle, so we should not receive the death
+        // notification when the remote process dies here.
+        assert!(
+            !binder_died.load(Ordering::Relaxed),
+            "Received unexpected death notification after dropping remote handle"
+        );
+    }
+
+    /// Test IBinder interface methods not exercised elsewhere.
+    #[test]
+    fn test_misc_ibinder() {
+        let service_name = "rust_test_ibinder";
+
+        {
+            let _process = ScopedServiceProcess::new(service_name);
+
+            let mut remote = binder::get_service(service_name);
+            assert!(remote.is_binder_alive());
+            remote.ping_binder().expect("Could not ping remote service");
+
+            // We're not testing the output of dump here, as that's really a
+            // property of the C++ implementation. There is the risk that the
+            // method just does nothing, but we don't want to depend on any
+            // particular output from the underlying library.
+            let null_out = File::open("/dev/null").expect("Could not open /dev/null");
+            remote
+                .dump(&null_out, &[])
+                .expect("Could not dump remote service");
+        }
+
+        // get/set_extensions is tested in test_extensions()
+
+        // transact is tested everywhere else, and we can't make raw
+        // transactions outside the [FIRST_CALL_TRANSACTION,
+        // LAST_CALL_TRANSACTION] range from the NDK anyway.
+
+        // link_to_death is tested in test_*_death_notification* tests.
+    }
+
+    #[test]
+    fn test_extensions() {
+        let service_name = "rust_test_extensions";
+        let extension_name = "rust_test_extensions_ext";
+
+        {
+            let _process = ScopedServiceProcess::new(service_name);
+
+            let mut remote = binder::get_service(service_name);
+            assert!(remote.is_binder_alive());
+
+            let extension = remote
+                .get_extension()
+                .expect("Could not check for an extension");
+            assert!(extension.is_none());
+        }
+
+        {
+            let _process = ScopedServiceProcess::new_with_extension(service_name, extension_name);
+
+            let mut remote = binder::get_service(service_name);
+            assert!(remote.is_binder_alive());
+
+            let maybe_extension = remote
+                .get_extension()
+                .expect("Could not check for an extension");
+
+            let extension = maybe_extension.expect("Remote binder did not have an extension");
+
+            let extension: Box<dyn ITest> = FromIBinder::try_from(extension)
+                .expect("Extension could not be converted to the expected interface");
+
+            assert_eq!(extension.test().unwrap(), extension_name);
+        }
+    }
+}
