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

Commit 6b21d390 authored by android-build-team Robot's avatar android-build-team Robot
Browse files

Snap for 7140885 from e06403fa to sc-release

Change-Id: I8af7014bf77d02662d3560ee89000780092fedfe
parents 9ce8a5a0 e06403fa
Loading
Loading
Loading
Loading
+15 −2
Original line number Diff line number Diff line
@@ -30,6 +30,7 @@
 */

#include <string>
#include <unordered_map>

#include <android-base/chrono_utils.h>

@@ -155,6 +156,7 @@ struct InputMessage {
        struct Finished {
            uint32_t empty1;
            uint32_t handled; // actually a bool, but we must maintain 8-byte alignment
            nsecs_t consumeTime; // The time when the event was consumed by the receiving end

            inline size_t size() const { return sizeof(Finished); }
        } finished;
@@ -362,7 +364,8 @@ public:

    /* Receives the finished signal from the consumer in reply to the original dispatch signal.
     * If a signal was received, returns the message sequence number,
     * and whether the consumer handled the message.
     * whether the consumer handled the message, and the time the event was first read by the
     * consumer.
     *
     * The returned sequence number is never 0 unless the operation failed.
     *
@@ -371,7 +374,8 @@ public:
     * Returns DEAD_OBJECT if the channel's peer has been closed.
     * Other errors probably indicate that the channel is broken.
     */
    status_t receiveFinishedSignal(uint32_t* outSeq, bool* outHandled);
    status_t receiveFinishedSignal(
            const std::function<void(uint32_t seq, bool handled, nsecs_t consumeTime)>& callback);

private:
    std::shared_ptr<InputChannel> mChannel;
@@ -577,6 +581,13 @@ private:
    };
    std::vector<SeqChain> mSeqChains;

    // The time at which each event with the sequence number 'seq' was consumed.
    // This data is provided in 'finishInputEvent' so that the receiving end can measure the latency
    // This collection is populated when the event is received, and the entries are erased when the
    // events are finished. It should not grow infinitely because if an event is not ack'd, ANR
    // will be raised for that connection, and no further events will be posted to that channel.
    std::unordered_map<uint32_t /*seq*/, nsecs_t /*consumeTime*/> mConsumeTimes;

    status_t consumeBatch(InputEventFactoryInterface* factory,
            nsecs_t frameTime, uint32_t* outSeq, InputEvent** outEvent);
    status_t consumeSamples(InputEventFactoryInterface* factory,
@@ -589,6 +600,8 @@ private:
    ssize_t findBatch(int32_t deviceId, int32_t source) const;
    ssize_t findTouchState(int32_t deviceId, int32_t source) const;

    nsecs_t getConsumeTime(uint32_t seq) const;
    void popConsumeTime(uint32_t seq);
    status_t sendUnchainedFinishedSignal(uint32_t seq, bool handled);

    static void rewriteMessage(TouchState& state, InputMessage& msg);
+104 −606

File changed.

Preview size limit exceeded, changes collapsed.

+586 −554

File changed.

Preview size limit exceeded, changes collapsed.

+145 −13
Original line number Diff line number Diff line
@@ -16,12 +16,17 @@

//! Trait definitions for binder objects

use crate::error::{status_t, Result};
use crate::error::{status_t, Result, StatusCode};
use crate::parcel::Parcel;
use crate::proxy::{DeathRecipient, SpIBinder};
use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder};
use crate::sys;

use std::borrow::Borrow;
use std::cmp::Ordering;
use std::ffi::{c_void, CStr, CString};
use std::fmt;
use std::marker::PhantomData;
use std::ops::Deref;
use std::os::raw::c_char;
use std::os::unix::io::AsRawFd;
use std::ptr;
@@ -44,7 +49,7 @@ pub type TransactionFlags = u32;
/// interfaces) must implement this trait.
///
/// This is equivalent `IInterface` in C++.
pub trait Interface {
pub trait Interface: Send {
    /// 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.")
@@ -230,6 +235,132 @@ impl From<InterfaceClass> for *const sys::AIBinder_Class {
    }
}

/// Strong reference to a binder object
pub struct Strong<I: FromIBinder + ?Sized>(Box<I>);

impl<I: FromIBinder + ?Sized> Strong<I> {
    /// Create a new strong reference to the provided binder object
    pub fn new(binder: Box<I>) -> Self {
        Self(binder)
    }

    /// Construct a new weak reference to this binder
    pub fn downgrade(this: &Strong<I>) -> Weak<I> {
        Weak::new(this)
    }
}

impl<I: FromIBinder + ?Sized> Clone for Strong<I> {
    fn clone(&self) -> Self {
        // Since we hold a strong reference, we should always be able to create
        // a new strong reference to the same interface type, so try_from()
        // should never fail here.
        FromIBinder::try_from(self.0.as_binder()).unwrap()
    }
}

impl<I: FromIBinder + ?Sized> Borrow<I> for Strong<I> {
    fn borrow(&self) -> &I {
        &self.0
    }
}

impl<I: FromIBinder + ?Sized> AsRef<I> for Strong<I> {
    fn as_ref(&self) -> &I {
        &self.0
    }
}

impl<I: FromIBinder + ?Sized> Deref for Strong<I> {
    type Target = I;

    fn deref(&self) -> &Self::Target {
        &self.0
    }
}

impl<I: FromIBinder + fmt::Debug + ?Sized> fmt::Debug for Strong<I> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        fmt::Debug::fmt(&**self, f)
    }
}

impl<I: FromIBinder + ?Sized> Ord for Strong<I> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.0.as_binder().cmp(&other.0.as_binder())
    }
}

impl<I: FromIBinder + ?Sized> PartialOrd for Strong<I> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.0.as_binder().partial_cmp(&other.0.as_binder())
    }
}

impl<I: FromIBinder + ?Sized> PartialEq for Strong<I> {
    fn eq(&self, other: &Self) -> bool {
        self.0.as_binder().eq(&other.0.as_binder())
    }
}

impl<I: FromIBinder + ?Sized> Eq for Strong<I> {}

/// Weak reference to a binder object
#[derive(Debug)]
pub struct Weak<I: FromIBinder + ?Sized> {
    weak_binder: WpIBinder,
    interface_type: PhantomData<I>,
}

impl<I: FromIBinder + ?Sized> Weak<I> {
    /// Construct a new weak reference from a strong reference
    fn new(binder: &Strong<I>) -> Self {
        let weak_binder = binder.as_binder().downgrade();
        Weak {
            weak_binder,
            interface_type: PhantomData,
        }
    }

    /// Upgrade this weak reference to a strong reference if the binder object
    /// is still alive
    pub fn upgrade(&self) -> Result<Strong<I>> {
        self.weak_binder
            .promote()
            .ok_or(StatusCode::DEAD_OBJECT)
            .and_then(FromIBinder::try_from)
    }
}

impl<I: FromIBinder + ?Sized> Clone for Weak<I> {
    fn clone(&self) -> Self {
        Self {
            weak_binder: self.weak_binder.clone(),
            interface_type: PhantomData,
        }
    }
}

impl<I: FromIBinder + ?Sized> Ord for Weak<I> {
    fn cmp(&self, other: &Self) -> Ordering {
        self.weak_binder.cmp(&other.weak_binder)
    }
}

impl<I: FromIBinder + ?Sized> PartialOrd for Weak<I> {
    fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
        self.weak_binder.partial_cmp(&other.weak_binder)
    }
}

impl<I: FromIBinder + ?Sized> PartialEq for Weak<I> {
    fn eq(&self, other: &Self) -> bool {
        self.weak_binder == other.weak_binder
    }
}

impl<I: FromIBinder + ?Sized> Eq for Weak<I> {}

/// Create a function implementing a static getter for an interface class.
///
/// Each binder interface (i.e. local [`Remotable`] service or remote proxy
@@ -354,12 +485,12 @@ pub trait InterfaceClassMethods {
///     }
/// }
/// ```
pub trait FromIBinder {
pub trait FromIBinder: Interface {
    /// 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>>;
    fn try_from(ibinder: SpIBinder) -> Result<Strong<Self>>;
}

/// Trait for transparent Rust wrappers around android C++ native types.
@@ -534,8 +665,9 @@ macro_rules! declare_binder_interface {

        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)))
            pub fn new_binder<T: $interface + Sync + Send + 'static>(inner: T) -> $crate::Strong<dyn $interface> {
                let binder = $crate::Binder::new($native(Box::new(inner)));
                $crate::Strong::new(Box::new(binder))
            }
        }

@@ -577,7 +709,7 @@ macro_rules! declare_binder_interface {
        }

        impl $crate::FromIBinder for dyn $interface {
            fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<Box<dyn $interface>> {
            fn try_from(mut ibinder: $crate::SpIBinder) -> $crate::Result<$crate::Strong<dyn $interface>> {
                use $crate::AssociateClass;

                let existing_class = ibinder.get_class();
@@ -590,7 +722,7 @@ macro_rules! declare_binder_interface {
                        // associated object as remote, because we can't cast it
                        // into a Rust service object without a matching class
                        // pointer.
                        return Ok(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?));
                        return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
                    }
                }

@@ -600,10 +732,10 @@ macro_rules! declare_binder_interface {
                    if let Ok(service) = service {
                        // We were able to associate with our expected class and
                        // the service is local.
                        return Ok(Box::new(service));
                        return Ok($crate::Strong::new(Box::new(service)));
                    } else {
                        // Service is remote
                        return Ok(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?));
                        return Ok($crate::Strong::new(Box::new(<$proxy as $crate::Proxy>::from_binder(ibinder)?)));
                    }
                }

@@ -633,9 +765,9 @@ macro_rules! declare_binder_interface {
            }
        }

        // Convert a &dyn $interface to Box<dyn $interface>
        /// Convert a &dyn $interface to Strong<dyn $interface>
        impl std::borrow::ToOwned for dyn $interface {
            type Owned = Box<dyn $interface>;
            type Owned = $crate::Strong<dyn $interface>;
            fn to_owned(&self) -> Self::Owned {
                self.as_binder().into_interface()
                    .expect(concat!("Error cloning interface ", stringify!($interface)))
+4 −2
Original line number Diff line number Diff line
@@ -107,7 +107,8 @@ use binder_ndk_sys as sys;
pub mod parcel;

pub use crate::binder::{
    FromIBinder, IBinder, Interface, InterfaceClass, Remotable, TransactionCode, TransactionFlags,
    FromIBinder, IBinder, Interface, InterfaceClass, Remotable, Strong, TransactionCode,
    TransactionFlags, Weak,
};
pub use error::{status_t, ExceptionCode, Result, Status, StatusCode};
pub use native::add_service;
@@ -122,7 +123,8 @@ 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, WpIBinder,
        ExceptionCode, Interface, ProcessState, SpIBinder, Status, StatusCode, Strong, ThreadState,
        Weak, WpIBinder,
    };

    /// Binder result containing a [`Status`] on error.
Loading