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

Commit 92f07bd2 authored by Andrew Walbran's avatar Andrew Walbran Committed by Automerger Merge Worker
Browse files

Merge "Standardise safety comments for unsafe blocks, and add some more." into...

Merge "Standardise safety comments for unsafe blocks, and add some more." into main am: f56c8b1e am: a98f7e2a am: b0668bad am: 054d327a am: 25e6062e

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



Change-Id: I9137a23a081d9be2882c79bf3f794ec42a1edf62
Signed-off-by: default avatarAutomerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
parents 54ee96d8 25e6062e
Loading
Loading
Loading
Loading
+15 −6
Original line number Original line Diff line number Diff line
@@ -33,9 +33,9 @@ foreign_type! {
    pub struct RpcServerRef;
    pub struct RpcServerRef;
}
}


/// SAFETY - The opaque handle can be cloned freely.
/// SAFETY: The opaque handle can be cloned freely.
unsafe impl Send for RpcServer {}
unsafe impl Send for RpcServer {}
/// SAFETY - The underlying C++ RpcServer class is thread-safe.
/// SAFETY: The underlying C++ RpcServer class is thread-safe.
unsafe impl Sync for RpcServer {}
unsafe impl Sync for RpcServer {}


impl RpcServer {
impl RpcServer {
@@ -59,7 +59,10 @@ impl RpcServer {
    /// Creates a binder RPC server, serving the supplied binder service implementation on the given
    /// Creates a binder RPC server, serving the supplied binder service implementation on the given
    /// socket file descriptor. The socket should be bound to an address before calling this
    /// socket file descriptor. The socket should be bound to an address before calling this
    /// function.
    /// function.
    pub fn new_bound_socket(mut service: SpIBinder, socket_fd: OwnedFd) -> Result<RpcServer, Error> {
    pub fn new_bound_socket(
        mut service: SpIBinder,
        socket_fd: OwnedFd,
    ) -> Result<RpcServer, Error> {
        let service = service.as_native_mut();
        let service = service.as_native_mut();


        // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
        // SAFETY: Service ownership is transferring to the server and won't be valid afterward.
@@ -67,7 +70,8 @@ impl RpcServer {
        // The server takes ownership of the socket FD.
        // The server takes ownership of the socket FD.
        unsafe {
        unsafe {
            Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newBoundSocket(
            Self::checked_from_ptr(binder_rpc_unstable_bindgen::ARpcServer_newBoundSocket(
                service, socket_fd.into_raw_fd(),
                service,
                socket_fd.into_raw_fd(),
            ))
            ))
        }
        }
    }
    }
@@ -120,7 +124,9 @@ impl RpcServer {
        if ptr.is_null() {
        if ptr.is_null() {
            return Err(Error::new(ErrorKind::Other, "Failed to start server"));
            return Err(Error::new(ErrorKind::Other, "Failed to start server"));
        }
        }
        Ok(RpcServer::from_ptr(ptr))
        // SAFETY: Our caller must pass us a valid or null pointer, and we've checked that it's not
        // null.
        Ok(unsafe { RpcServer::from_ptr(ptr) })
    }
    }
}
}


@@ -130,7 +136,7 @@ impl RpcServerRef {
        &self,
        &self,
        modes: &[FileDescriptorTransportMode],
        modes: &[FileDescriptorTransportMode],
    ) {
    ) {
        // SAFETY - Does not keep the pointer after returning does, nor does it
        // SAFETY: Does not keep the pointer after returning does, nor does it
        // read past its boundary. Only passes the 'self' pointer as an opaque handle.
        // read past its boundary. Only passes the 'self' pointer as an opaque handle.
        unsafe {
        unsafe {
            binder_rpc_unstable_bindgen::ARpcServer_setSupportedFileDescriptorTransportModes(
            binder_rpc_unstable_bindgen::ARpcServer_setSupportedFileDescriptorTransportModes(
@@ -143,18 +149,21 @@ impl RpcServerRef {


    /// Starts a new background thread and calls join(). Returns immediately.
    /// Starts a new background thread and calls join(). Returns immediately.
    pub fn start(&self) {
    pub fn start(&self) {
        // SAFETY: RpcServerRef wraps a valid pointer to an ARpcServer.
        unsafe { binder_rpc_unstable_bindgen::ARpcServer_start(self.as_ptr()) };
        unsafe { binder_rpc_unstable_bindgen::ARpcServer_start(self.as_ptr()) };
    }
    }


    /// Joins the RpcServer thread. The call blocks until the server terminates.
    /// Joins the RpcServer thread. The call blocks until the server terminates.
    /// This must be called from exactly one thread.
    /// This must be called from exactly one thread.
    pub fn join(&self) {
    pub fn join(&self) {
        // SAFETY: RpcServerRef wraps a valid pointer to an ARpcServer.
        unsafe { binder_rpc_unstable_bindgen::ARpcServer_join(self.as_ptr()) };
        unsafe { binder_rpc_unstable_bindgen::ARpcServer_join(self.as_ptr()) };
    }
    }


    /// Shuts down the running RpcServer. Can be called multiple times and from
    /// Shuts down the running RpcServer. Can be called multiple times and from
    /// multiple threads. Called automatically during drop().
    /// multiple threads. Called automatically during drop().
    pub fn shutdown(&self) -> Result<(), Error> {
    pub fn shutdown(&self) -> Result<(), Error> {
        // SAFETY: RpcServerRef wraps a valid pointer to an ARpcServer.
        if unsafe { binder_rpc_unstable_bindgen::ARpcServer_shutdown(self.as_ptr()) } {
        if unsafe { binder_rpc_unstable_bindgen::ARpcServer_shutdown(self.as_ptr()) } {
            Ok(())
            Ok(())
        } else {
        } else {
+8 −8
Original line number Original line Diff line number Diff line
@@ -36,15 +36,15 @@ foreign_type! {
    pub struct RpcSessionRef;
    pub struct RpcSessionRef;
}
}


/// SAFETY - The opaque handle can be cloned freely.
/// SAFETY: The opaque handle can be cloned freely.
unsafe impl Send for RpcSession {}
unsafe impl Send for RpcSession {}
/// SAFETY - The underlying C++ RpcSession class is thread-safe.
/// SAFETY: The underlying C++ RpcSession class is thread-safe.
unsafe impl Sync for RpcSession {}
unsafe impl Sync for RpcSession {}


impl RpcSession {
impl RpcSession {
    /// Allocates a new RpcSession object.
    /// Allocates a new RpcSession object.
    pub fn new() -> RpcSession {
    pub fn new() -> RpcSession {
        // SAFETY - Takes ownership of the returned handle, which has correct refcount.
        // SAFETY: Takes ownership of the returned handle, which has correct refcount.
        unsafe { RpcSession::from_ptr(binder_rpc_unstable_bindgen::ARpcSession_new()) }
        unsafe { RpcSession::from_ptr(binder_rpc_unstable_bindgen::ARpcSession_new()) }
    }
    }
}
}
@@ -58,7 +58,7 @@ impl Default for RpcSession {
impl RpcSessionRef {
impl RpcSessionRef {
    /// Sets the file descriptor transport mode for this session.
    /// Sets the file descriptor transport mode for this session.
    pub fn set_file_descriptor_transport_mode(&self, mode: FileDescriptorTransportMode) {
    pub fn set_file_descriptor_transport_mode(&self, mode: FileDescriptorTransportMode) {
        // SAFETY - Only passes the 'self' pointer as an opaque handle.
        // SAFETY: Only passes the 'self' pointer as an opaque handle.
        unsafe {
        unsafe {
            binder_rpc_unstable_bindgen::ARpcSession_setFileDescriptorTransportMode(
            binder_rpc_unstable_bindgen::ARpcSession_setFileDescriptorTransportMode(
                self.as_ptr(),
                self.as_ptr(),
@@ -69,7 +69,7 @@ impl RpcSessionRef {


    /// Sets the maximum number of incoming threads.
    /// Sets the maximum number of incoming threads.
    pub fn set_max_incoming_threads(&self, threads: usize) {
    pub fn set_max_incoming_threads(&self, threads: usize) {
        // SAFETY - Only passes the 'self' pointer as an opaque handle.
        // SAFETY: Only passes the 'self' pointer as an opaque handle.
        unsafe {
        unsafe {
            binder_rpc_unstable_bindgen::ARpcSession_setMaxIncomingThreads(self.as_ptr(), threads)
            binder_rpc_unstable_bindgen::ARpcSession_setMaxIncomingThreads(self.as_ptr(), threads)
        };
        };
@@ -77,7 +77,7 @@ impl RpcSessionRef {


    /// Sets the maximum number of outgoing connections.
    /// Sets the maximum number of outgoing connections.
    pub fn set_max_outgoing_connections(&self, connections: usize) {
    pub fn set_max_outgoing_connections(&self, connections: usize) {
        // SAFETY - Only passes the 'self' pointer as an opaque handle.
        // SAFETY: Only passes the 'self' pointer as an opaque handle.
        unsafe {
        unsafe {
            binder_rpc_unstable_bindgen::ARpcSession_setMaxOutgoingConnections(
            binder_rpc_unstable_bindgen::ARpcSession_setMaxOutgoingConnections(
                self.as_ptr(),
                self.as_ptr(),
@@ -210,10 +210,10 @@ impl RpcSessionRef {
type RequestFd<'a> = &'a mut dyn FnMut() -> Option<RawFd>;
type RequestFd<'a> = &'a mut dyn FnMut() -> Option<RawFd>;


unsafe extern "C" fn request_fd_wrapper(param: *mut c_void) -> c_int {
unsafe extern "C" fn request_fd_wrapper(param: *mut c_void) -> c_int {
    let request_fd_ptr = param as *mut RequestFd;
    // SAFETY: This is only ever called by RpcPreconnectedClient, within the lifetime of the
    // SAFETY: This is only ever called by RpcPreconnectedClient, within the lifetime of the
    // BinderFdFactory reference, with param being a properly aligned non-null pointer to an
    // BinderFdFactory reference, with param being a properly aligned non-null pointer to an
    // initialized instance.
    // initialized instance.
    let request_fd_ptr = param as *mut RequestFd;
    let request_fd = unsafe { request_fd_ptr.as_mut().unwrap() };
    let request_fd = request_fd_ptr.as_mut().unwrap();
    request_fd().unwrap_or(-1)
    request_fd().unwrap_or(-1)
}
}
+25 −27
Original line number Original line Diff line number Diff line
@@ -300,15 +300,14 @@ impl InterfaceClass {
    /// [`crate::declare_binder_interface!`].
    /// [`crate::declare_binder_interface!`].
    pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
    pub fn new<I: InterfaceClassMethods>() -> InterfaceClass {
        let descriptor = CString::new(I::get_descriptor()).unwrap();
        let descriptor = CString::new(I::get_descriptor()).unwrap();
        // 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 ptr = unsafe {
        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(
            let class = sys::AIBinder_Class_define(
                descriptor.as_ptr(),
                descriptor.as_ptr(),
                Some(I::on_create),
                Some(I::on_create),
@@ -338,13 +337,12 @@ impl InterfaceClass {


    /// Get the interface descriptor string of this class.
    /// Get the interface descriptor string of this class.
    pub fn get_descriptor(&self) -> String {
    pub fn get_descriptor(&self) -> String {
        // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor is
        // always a two-byte null terminated sequence of u16s. Thus, we can
        // continue reading from the pointer until we hit a null value, and this
        // pointer can be a valid slice if the slice length is <= the number of
        // u16 elements before the null terminator.
        unsafe {
        unsafe {
            // SAFETY: The descriptor returned by AIBinder_Class_getDescriptor
            // is always a two-byte null terminated sequence of u16s. Thus, we
            // can continue reading from the pointer until we hit a null value,
            // and this pointer can be a valid slice if the slice length is <=
            // the number of u16 elements before the null terminator.

            let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0);
            let raw_descriptor: *const c_char = sys::AIBinder_Class_getDescriptor(self.0);
            CStr::from_ptr(raw_descriptor)
            CStr::from_ptr(raw_descriptor)
                .to_str()
                .to_str()
@@ -542,17 +540,15 @@ macro_rules! binder_fn_get_class {
            static CLASS_INIT: std::sync::Once = std::sync::Once::new();
            static CLASS_INIT: std::sync::Once = std::sync::Once::new();
            static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None;
            static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None;


            CLASS_INIT.call_once(|| unsafe {
            // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
            // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
            // variable, and therefore is thread-safe, as it can only occur
            // variable, and therefore is thread-safe, as it can only occur
            // once.
            // once.
            CLASS_INIT.call_once(|| unsafe {
                CLASS = Some($constructor);
                CLASS = Some($constructor);
            });
            });
            unsafe {
            // Safety: The `CLASS` variable can only be mutated once, above, and
                // Safety: The `CLASS` variable can only be mutated once, above,
            // is subsequently safe to read from any thread.
                // and is subsequently safe to read from any thread.
            unsafe { CLASS.unwrap() }
                CLASS.unwrap()
            }
        }
        }
    };
    };
}
}
@@ -664,6 +660,8 @@ pub unsafe trait AsNative<T> {
    fn as_native_mut(&mut self) -> *mut T;
    fn as_native_mut(&mut self) -> *mut T;
}
}


// Safety: If V is a valid Android C++ type then we can either use that or a
// null pointer.
unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
unsafe impl<T, V: AsNative<T>> AsNative<T> for Option<V> {
    fn as_native(&self) -> *const T {
    fn as_native(&self) -> *const T {
        self.as_ref().map_or(ptr::null(), |v| v.as_native())
        self.as_ref().map_or(ptr::null(), |v| v.as_native())
@@ -924,15 +922,15 @@ macro_rules! declare_binder_interface {
                static CLASS_INIT: std::sync::Once = std::sync::Once::new();
                static CLASS_INIT: std::sync::Once = std::sync::Once::new();
                static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None;
                static mut CLASS: Option<$crate::binder_impl::InterfaceClass> = None;


                CLASS_INIT.call_once(|| unsafe {
                // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
                // Safety: This assignment is guarded by the `CLASS_INIT` `Once`
                // variable, and therefore is thread-safe, as it can only occur
                // variable, and therefore is thread-safe, as it can only occur
                // once.
                // once.
                CLASS_INIT.call_once(|| unsafe {
                    CLASS = Some($crate::binder_impl::InterfaceClass::new::<$crate::binder_impl::Binder<$native>>());
                    CLASS = Some($crate::binder_impl::InterfaceClass::new::<$crate::binder_impl::Binder<$native>>());
                });
                });
                unsafe {
                // Safety: The `CLASS` variable can only be mutated once, above,
                // Safety: The `CLASS` variable can only be mutated once, above,
                // and is subsequently safe to read from any thread.
                // and is subsequently safe to read from any thread.
                unsafe {
                    CLASS.unwrap()
                    CLASS.unwrap()
                }
                }
            }
            }
+71 −95
Original line number Original line Diff line number Diff line
@@ -112,21 +112,18 @@ fn to_cstring<T: AsRef<str>>(message: T) -> Option<CString> {
impl Status {
impl Status {
    /// Create a status object representing a successful transaction.
    /// Create a status object representing a successful transaction.
    pub fn ok() -> Self {
    pub fn ok() -> Self {
        let ptr = unsafe {
        // Safety: `AStatus_newOk` always returns a new, heap allocated
        // Safety: `AStatus_newOk` always returns a new, heap allocated
        // pointer to an `ASTatus` object, so we know this pointer will be
        // pointer to an `ASTatus` object, so we know this pointer will be
        // valid.
        // valid.
        //
        //
        // Rust takes ownership of the returned pointer.
        // Rust takes ownership of the returned pointer.
            sys::AStatus_newOk()
        let ptr = unsafe { sys::AStatus_newOk() };
        };
        Self(ptr::NonNull::new(ptr).expect("Unexpected null AStatus pointer"))
        Self(ptr::NonNull::new(ptr).expect("Unexpected null AStatus pointer"))
    }
    }


    /// Create a status object from a service specific error
    /// Create a status object from a service specific error
    pub fn new_service_specific_error(err: i32, message: Option<&CStr>) -> Status {
    pub fn new_service_specific_error(err: i32, message: Option<&CStr>) -> Status {
        let ptr = if let Some(message) = message {
        let ptr = if let Some(message) = message {
            unsafe {
            // Safety: Any i32 is a valid service specific error for the
            // Safety: Any i32 is a valid service specific error for the
            // error code parameter. We construct a valid, null-terminated
            // error code parameter. We construct a valid, null-terminated
            // `CString` from the message, which must be a valid C-style
            // `CString` from the message, which must be a valid C-style
@@ -135,18 +132,15 @@ impl Status {
            // know the returned pointer will be valid.
            // know the returned pointer will be valid.
            //
            //
            // Rust takes ownership of the returned pointer.
            // Rust takes ownership of the returned pointer.
                sys::AStatus_fromServiceSpecificErrorWithMessage(err, message.as_ptr())
            unsafe { sys::AStatus_fromServiceSpecificErrorWithMessage(err, message.as_ptr()) }
            }
        } else {
        } else {
            unsafe {
            // Safety: Any i32 is a valid service specific error for the
            // Safety: Any i32 is a valid service specific error for the
            // error code parameter. This function always returns a new,
            // error code parameter. This function always returns a new,
            // heap allocated pointer to an `AStatus` object, so we know the
            // heap allocated pointer to an `AStatus` object, so we know the
            // returned pointer will be valid.
            // returned pointer will be valid.
            //
            //
            // Rust takes ownership of the returned pointer.
            // Rust takes ownership of the returned pointer.
                sys::AStatus_fromServiceSpecificError(err)
            unsafe { sys::AStatus_fromServiceSpecificError(err) }
            }
        };
        };
        Self(ptr::NonNull::new(ptr).expect("Unexpected null AStatus pointer"))
        Self(ptr::NonNull::new(ptr).expect("Unexpected null AStatus pointer"))
    }
    }
@@ -159,6 +153,8 @@ impl Status {
    /// Create a status object from an exception code
    /// Create a status object from an exception code
    pub fn new_exception(exception: ExceptionCode, message: Option<&CStr>) -> Status {
    pub fn new_exception(exception: ExceptionCode, message: Option<&CStr>) -> Status {
        if let Some(message) = message {
        if let Some(message) = message {
            // Safety: the C string pointer is valid and not retained by the
            // function.
            let ptr = unsafe {
            let ptr = unsafe {
                sys::AStatus_fromExceptionCodeWithMessage(exception as i32, message.as_ptr())
                sys::AStatus_fromExceptionCodeWithMessage(exception as i32, message.as_ptr())
            };
            };
@@ -187,16 +183,13 @@ impl Status {


    /// Returns `true` if this status represents a successful transaction.
    /// Returns `true` if this status represents a successful transaction.
    pub fn is_ok(&self) -> bool {
    pub fn is_ok(&self) -> bool {
        unsafe {
        // Safety: `Status` always contains a valid `AStatus` pointer, so we
        // Safety: `Status` always contains a valid `AStatus` pointer, so we
        // are always passing a valid pointer to `AStatus_isOk` here.
        // are always passing a valid pointer to `AStatus_isOk` here.
            sys::AStatus_isOk(self.as_native())
        unsafe { sys::AStatus_isOk(self.as_native()) }
        }
    }
    }


    /// Returns a description of the status.
    /// Returns a description of the status.
    pub fn get_description(&self) -> String {
    pub fn get_description(&self) -> String {
        let description_ptr = unsafe {
        // Safety: `Status` always contains a valid `AStatus` pointer, so we
        // Safety: `Status` always contains a valid `AStatus` pointer, so we
        // are always passing a valid pointer to `AStatus_getDescription`
        // are always passing a valid pointer to `AStatus_getDescription`
        // here.
        // here.
@@ -204,20 +197,17 @@ impl Status {
        // `AStatus_getDescription` always returns a valid pointer to a null
        // `AStatus_getDescription` always returns a valid pointer to a null
        // terminated C string. Rust is responsible for freeing this pointer
        // terminated C string. Rust is responsible for freeing this pointer
        // via `AStatus_deleteDescription`.
        // via `AStatus_deleteDescription`.
            sys::AStatus_getDescription(self.as_native())
        let description_ptr = unsafe { sys::AStatus_getDescription(self.as_native()) };
        };
        let description = unsafe {
        // Safety: `AStatus_getDescription` always returns a valid C string,
        // Safety: `AStatus_getDescription` always returns a valid C string,
        // which can be safely converted to a `CStr`.
        // which can be safely converted to a `CStr`.
            CStr::from_ptr(description_ptr)
        let description = unsafe { CStr::from_ptr(description_ptr) };
        };
        let description = description.to_string_lossy().to_string();
        let description = description.to_string_lossy().to_string();
        unsafe {
        // Safety: `description_ptr` was returned from
        // Safety: `description_ptr` was returned from
        // `AStatus_getDescription` above, and must be freed via
        // `AStatus_getDescription` above, and must be freed via
        // `AStatus_deleteDescription`. We must not access the pointer after
        // `AStatus_deleteDescription`. We must not access the pointer after
        // this call, so we copy it into an owned string above and return
        // this call, so we copy it into an owned string above and return
        // that string.
        // that string.
        unsafe {
            sys::AStatus_deleteDescription(description_ptr);
            sys::AStatus_deleteDescription(description_ptr);
        }
        }
        description
        description
@@ -225,12 +215,10 @@ impl Status {


    /// Returns the exception code of the status.
    /// Returns the exception code of the status.
    pub fn exception_code(&self) -> ExceptionCode {
    pub fn exception_code(&self) -> ExceptionCode {
        let code = unsafe {
        // Safety: `Status` always contains a valid `AStatus` pointer, so we
        // Safety: `Status` always contains a valid `AStatus` pointer, so we
        // are always passing a valid pointer to `AStatus_getExceptionCode`
        // are always passing a valid pointer to `AStatus_getExceptionCode`
        // here.
        // here.
            sys::AStatus_getExceptionCode(self.as_native())
        let code = unsafe { sys::AStatus_getExceptionCode(self.as_native()) };
        };
        parse_exception_code(code)
        parse_exception_code(code)
    }
    }


@@ -241,11 +229,9 @@ impl Status {
    /// exception or a service specific error. To find out if this transaction
    /// exception or a service specific error. To find out if this transaction
    /// as a whole is okay, use [`is_ok`](Self::is_ok) instead.
    /// as a whole is okay, use [`is_ok`](Self::is_ok) instead.
    pub fn transaction_error(&self) -> StatusCode {
    pub fn transaction_error(&self) -> StatusCode {
        let code = unsafe {
        // Safety: `Status` always contains a valid `AStatus` pointer, so we
        // Safety: `Status` always contains a valid `AStatus` pointer, so we
        // are always passing a valid pointer to `AStatus_getStatus` here.
        // are always passing a valid pointer to `AStatus_getStatus` here.
            sys::AStatus_getStatus(self.as_native())
        let code = unsafe { sys::AStatus_getStatus(self.as_native()) };
        };
        parse_status_code(code)
        parse_status_code(code)
    }
    }


@@ -258,12 +244,10 @@ impl Status {
    /// find out if this transaction as a whole is okay, use
    /// find out if this transaction as a whole is okay, use
    /// [`is_ok`](Self::is_ok) instead.
    /// [`is_ok`](Self::is_ok) instead.
    pub fn service_specific_error(&self) -> i32 {
    pub fn service_specific_error(&self) -> i32 {
        unsafe {
        // Safety: `Status` always contains a valid `AStatus` pointer, so we
        // Safety: `Status` always contains a valid `AStatus` pointer, so we
        // are always passing a valid pointer to
        // are always passing a valid pointer to
        // `AStatus_getServiceSpecificError` here.
        // `AStatus_getServiceSpecificError` here.
            sys::AStatus_getServiceSpecificError(self.as_native())
        unsafe { sys::AStatus_getServiceSpecificError(self.as_native()) }
        }
    }
    }


    /// Calls `op` if the status was ok, otherwise returns an `Err` value of
    /// Calls `op` if the status was ok, otherwise returns an `Err` value of
@@ -321,24 +305,20 @@ impl From<StatusCode> for Status {


impl From<status_t> for Status {
impl From<status_t> for Status {
    fn from(status: status_t) -> Status {
    fn from(status: status_t) -> Status {
        let ptr = unsafe {
        // Safety: `AStatus_fromStatus` expects any `status_t` integer, so
        // Safety: `AStatus_fromStatus` expects any `status_t` integer, so
        // this is a safe FFI call. Unknown values will be coerced into
        // this is a safe FFI call. Unknown values will be coerced into
        // UNKNOWN_ERROR.
        // UNKNOWN_ERROR.
            sys::AStatus_fromStatus(status)
        let ptr = unsafe { sys::AStatus_fromStatus(status) };
        };
        Self(ptr::NonNull::new(ptr).expect("Unexpected null AStatus pointer"))
        Self(ptr::NonNull::new(ptr).expect("Unexpected null AStatus pointer"))
    }
    }
}
}


impl From<ExceptionCode> for Status {
impl From<ExceptionCode> for Status {
    fn from(code: ExceptionCode) -> Status {
    fn from(code: ExceptionCode) -> Status {
        let ptr = unsafe {
        // Safety: `AStatus_fromExceptionCode` expects any
        // Safety: `AStatus_fromExceptionCode` expects any
        // `binder_exception_t` (i32) integer, so this is a safe FFI call.
        // `binder_exception_t` (i32) integer, so this is a safe FFI call.
        // Unknown values will be coerced into EX_TRANSACTION_FAILED.
        // Unknown values will be coerced into EX_TRANSACTION_FAILED.
            sys::AStatus_fromExceptionCode(code as i32)
        let ptr = unsafe { sys::AStatus_fromExceptionCode(code as i32) };
        };
        Self(ptr::NonNull::new(ptr).expect("Unexpected null AStatus pointer"))
        Self(ptr::NonNull::new(ptr).expect("Unexpected null AStatus pointer"))
    }
    }
}
}
@@ -363,20 +343,18 @@ impl From<Status> for status_t {


impl Drop for Status {
impl Drop for Status {
    fn drop(&mut self) {
    fn drop(&mut self) {
        unsafe {
        // Safety: `Status` manages the lifetime of its inner `AStatus`
        // Safety: `Status` manages the lifetime of its inner `AStatus`
        // pointee, so we need to delete it here. We know that the pointer
        // pointee, so we need to delete it here. We know that the pointer
        // will be valid here since `Status` always contains a valid pointer
        // will be valid here since `Status` always contains a valid pointer
        // while it is alive.
        // while it is alive.
        unsafe {
            sys::AStatus_delete(self.0.as_mut());
            sys::AStatus_delete(self.0.as_mut());
        }
        }
    }
    }
}
}


/// # Safety
/// Safety: `Status` always contains a valid pointer to an `AStatus` object, so
///
/// we can trivially convert it to a correctly-typed raw pointer.
/// `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
/// Care must be taken that the returned pointer is only dereferenced while the
/// `Status` object is still alive.
/// `Status` object is still alive.
@@ -386,11 +364,9 @@ unsafe impl AsNative<sys::AStatus> for Status {
    }
    }


    fn as_native_mut(&mut self) -> *mut sys::AStatus {
    fn as_native_mut(&mut self) -> *mut sys::AStatus {
        unsafe {
        // Safety: The pointer will be valid here since `Status` always contains
            // Safety: The pointer will be valid here since `Status` always
        // a valid and initialized pointer while it is alive.
            // contains a valid and initialized pointer while it is alive.
        unsafe { self.0.as_mut() }
            self.0.as_mut()
        }
    }
    }
}
}


+96 −93

File changed.

Preview size limit exceeded, changes collapsed.

Loading