Merge "Parcel: add generic readData and writeData methods."
diff --git a/cmds/idlcli/Android.bp b/cmds/idlcli/Android.bp
index 402767a..875a61a 100644
--- a/cmds/idlcli/Android.bp
+++ b/cmds/idlcli/Android.bp
@@ -15,7 +15,7 @@
cc_defaults {
name: "idlcli-defaults",
shared_libs: [
- "android.hardware.vibrator-ndk_platform",
+ "android.hardware.vibrator-V1-ndk_platform",
"android.hardware.vibrator@1.0",
"android.hardware.vibrator@1.1",
"android.hardware.vibrator@1.2",
diff --git a/include/OWNERS b/include/OWNERS
index db52850..c98e87a 100644
--- a/include/OWNERS
+++ b/include/OWNERS
@@ -1,3 +1,4 @@
+alecmouri@google.com
alexeykuzmin@google.com
dangittik@google.com
jreck@google.com
@@ -8,7 +9,6 @@
racarr@google.com
romainguy@android.com
santoscordon@google.com
-stoza@google.com
svv@google.com
# For multinetwork.h only.
diff --git a/include/android/bitmap.h b/include/android/bitmap.h
index 2362c9e..a70dffd 100644
--- a/include/android/bitmap.h
+++ b/include/android/bitmap.h
@@ -31,18 +31,8 @@
#include <stddef.h>
#include <jni.h>
-#ifndef __ANDROID__
- // Value copied from 'bionic/libc/include/android/api-level.h' which is not available on
- // non Android systems. It is set to 10000 which is same as __ANDROID_API_FUTURE__ value.
- #ifndef __ANDROID_API__
- #define __ANDROID_API__ 10000
- #endif
-
- // Value copied from 'bionic/libc/include/android/versioning.h' which is not available on
- // non Android systems
- #ifndef __INTRODUCED_IN
- #define __INTRODUCED_IN(api_level)
- #endif
+#if !defined(__INTRODUCED_IN)
+#define __INTRODUCED_IN(__api_level) /* nothing */
#endif
#ifdef __cplusplus
diff --git a/include/android/imagedecoder.h b/include/android/imagedecoder.h
index 48d217f..1298c62 100644
--- a/include/android/imagedecoder.h
+++ b/include/android/imagedecoder.h
@@ -51,18 +51,8 @@
#include <android/rect.h>
#include <stdint.h>
-#ifndef __ANDROID__
- // Value copied from 'bionic/libc/include/android/api-level.h' which is not available on
- // non Android systems. It is set to 10000 which is same as __ANDROID_API_FUTURE__ value.
- #ifndef __ANDROID_API__
- #define __ANDROID_API__ 10000
- #endif
-
- // Value copied from 'bionic/libc/include/android/versioning.h' which is not available on
- // non Android systems
- #ifndef __INTRODUCED_IN
- #define __INTRODUCED_IN(api_level)
- #endif
+#if !defined(__INTRODUCED_IN)
+#define __INTRODUCED_IN(__api_level) /* nothing */
#endif
#ifdef __cplusplus
diff --git a/include/android/thermal.h b/include/android/thermal.h
index 5ebdc02..6ec68d9 100644
--- a/include/android/thermal.h
+++ b/include/android/thermal.h
@@ -53,7 +53,7 @@
#include <sys/types.h>
#if !defined(__INTRODUCED_IN)
-#define __INTRODUCED_IN(30) /* Introduced in API level 30 */
+#define __INTRODUCED_IN(__api_level) /* nothing */
#endif
#ifdef __cplusplus
diff --git a/libs/adbd_auth/include/adbd_auth.h b/libs/adbd_auth/include/adbd_auth.h
index 8f834df..1dcf540 100644
--- a/libs/adbd_auth/include/adbd_auth.h
+++ b/libs/adbd_auth/include/adbd_auth.h
@@ -26,7 +26,6 @@
#endif
__BEGIN_DECLS
-#if !defined(__ANDROID__) || __ANDROID_API__ >= 30
// The transport type of the device connection.
enum AdbTransportType : int32_t {
@@ -186,5 +185,4 @@
*/
bool adbd_auth_supports_feature(AdbdAuthFeature feature);
-#endif //!__ANDROID__ || __ANDROID_API__ >= 30
__END_DECLS
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 11b032b..7901f45 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -32,6 +32,11 @@
"libcutils_headers",
"libutils_headers",
],
+ apex_available: [
+ "//apex_available:platform",
+ "com.android.media",
+ "com.android.media.swcodec",
+ ],
min_sdk_version: "29",
target: {
darwin: {
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index d76a1f9..897c72a 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -141,14 +141,12 @@
enabled: false,
},
},
- min_sdk_version: "29",
apex_available: [
"//apex_available:platform",
- // TODO(b/166468760) remove these three
"com.android.media",
"com.android.media.swcodec",
- "test_com.android.media.swcodec",
],
+ min_sdk_version: "29",
}
ndk_headers {
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder.h b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
index bb70588..a44c261 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder.h
@@ -41,8 +41,6 @@
android platform host build, you must use libbinder_ndk_host_user.
#endif
-#if __ANDROID_API__ >= 29
-
typedef uint32_t binder_flags_t;
enum {
/**
@@ -567,10 +565,6 @@
*/
void AIBinder_DeathRecipient_delete(AIBinder_DeathRecipient* recipient) __INTRODUCED_IN(29);
-#endif //__ANDROID_API__ >= 29
-
-#if __ANDROID_API__ >= 30
-
/**
* Gets the extension registered with AIBinder_setExtension.
*
@@ -640,10 +634,6 @@
*/
binder_status_t AIBinder_setExtension(AIBinder* binder, AIBinder* ext) __INTRODUCED_IN(30);
-#endif //__ANDROID_API__ >= 30
-
-#if __ANDROID_API__ >= 31
-
/**
* Retrieve the class descriptor for the class.
*
@@ -728,8 +718,6 @@
*/
bool AIBinder_Weak_lt(const AIBinder_Weak* lhs, const AIBinder_Weak* rhs);
-#endif //__ANDROID_API__ >= 31
-
__END_DECLS
/** @} */
diff --git a/libs/binder/ndk/include_ndk/android/binder_ibinder_jni.h b/libs/binder/ndk/include_ndk/android/binder_ibinder_jni.h
index cd1ff1f..6880d86 100644
--- a/libs/binder/ndk/include_ndk/android/binder_ibinder_jni.h
+++ b/libs/binder/ndk/include_ndk/android/binder_ibinder_jni.h
@@ -31,7 +31,6 @@
#include <jni.h>
__BEGIN_DECLS
-#if __ANDROID_API__ >= 29
/**
* Converts an android.os.IBinder object into an AIBinder* object.
@@ -67,7 +66,6 @@
__attribute__((warn_unused_result)) jobject AIBinder_toJavaBinder(JNIEnv* env, AIBinder* binder)
__INTRODUCED_IN(29);
-#endif //__ANDROID_API__ >= 29
__END_DECLS
/** @} */
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel.h b/libs/binder/ndk/include_ndk/android/binder_parcel.h
index ab67017..527b151 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel.h
@@ -36,7 +36,6 @@
typedef struct AIBinder AIBinder;
__BEGIN_DECLS
-#if __ANDROID_API__ >= 29
/**
* This object represents a package of data that can be sent between processes. When transacting, an
@@ -1119,7 +1118,6 @@
// @END-PRIMITIVE-READ-WRITE
-#endif //__ANDROID_API__ >= 29
/**
* Reset the parcel to the initial status.
*
diff --git a/libs/binder/ndk/include_ndk/android/binder_parcel_jni.h b/libs/binder/ndk/include_ndk/android/binder_parcel_jni.h
index 65e1704..384d4f7 100644
--- a/libs/binder/ndk/include_ndk/android/binder_parcel_jni.h
+++ b/libs/binder/ndk/include_ndk/android/binder_parcel_jni.h
@@ -31,7 +31,6 @@
#include <jni.h>
__BEGIN_DECLS
-#if __ANDROID_API__ >= 30
/**
* Converts an android.os.Parcel object into an AParcel* object.
@@ -50,7 +49,6 @@
__attribute__((warn_unused_result)) AParcel* AParcel_fromJavaParcel(JNIEnv* env, jobject parcel)
__INTRODUCED_IN(30);
-#endif //__ANDROID_API__ >= 30
__END_DECLS
/** @} */
diff --git a/libs/binder/ndk/include_ndk/android/binder_status.h b/libs/binder/ndk/include_ndk/android/binder_status.h
index 3a55f94..05b25e7 100644
--- a/libs/binder/ndk/include_ndk/android/binder_status.h
+++ b/libs/binder/ndk/include_ndk/android/binder_status.h
@@ -31,7 +31,6 @@
#include <sys/cdefs.h>
__BEGIN_DECLS
-#if __ANDROID_API__ >= 29
enum {
STATUS_OK = 0,
@@ -275,7 +274,6 @@
*/
void AStatus_delete(AStatus* status) __INTRODUCED_IN(29);
-#endif //__ANDROID_API__ >= 29
__END_DECLS
/** @} */
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index 42c1e0a..d53a88f 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -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 @@
/// 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 @@
}
}
+/// 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 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 @@
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 @@
}
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 @@
// 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 @@
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 @@
}
}
- // 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)))
diff --git a/libs/binder/rust/src/lib.rs b/libs/binder/rust/src/lib.rs
index edfb56a..43a237a 100644
--- a/libs/binder/rust/src/lib.rs
+++ b/libs/binder/rust/src/lib.rs
@@ -107,7 +107,8 @@
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 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.
diff --git a/libs/binder/rust/src/parcel/parcelable.rs b/libs/binder/rust/src/parcel/parcelable.rs
index 8d18fb4..f57788b 100644
--- a/libs/binder/rust/src/parcel/parcelable.rs
+++ b/libs/binder/rust/src/parcel/parcelable.rs
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-use crate::binder::{AsNative, FromIBinder};
+use crate::binder::{AsNative, FromIBinder, Strong};
use crate::error::{status_result, status_t, Result, Status, StatusCode};
use crate::parcel::Parcel;
use crate::proxy::SpIBinder;
@@ -628,26 +628,26 @@
}
}
-impl<T: Serialize + ?Sized> Serialize for Box<T> {
+impl<T: Serialize + FromIBinder + ?Sized> Serialize for Strong<T> {
fn serialize(&self, parcel: &mut Parcel) -> Result<()> {
Serialize::serialize(&**self, parcel)
}
}
-impl<T: SerializeOption + ?Sized> SerializeOption for Box<T> {
+impl<T: SerializeOption + FromIBinder + ?Sized> SerializeOption for Strong<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> {
+impl<T: FromIBinder + ?Sized> Deserialize for Strong<T> {
fn deserialize(parcel: &Parcel) -> Result<Self> {
let ibinder: SpIBinder = parcel.read()?;
FromIBinder::try_from(ibinder)
}
}
-impl<T: FromIBinder + ?Sized> DeserializeOption for Box<T> {
+impl<T: FromIBinder + ?Sized> DeserializeOption for Strong<T> {
fn deserialize_option(parcel: &Parcel) -> Result<Option<Self>> {
let ibinder: Option<SpIBinder> = parcel.read()?;
ibinder.map(FromIBinder::try_from).transpose()
diff --git a/libs/binder/rust/src/proxy.rs b/libs/binder/rust/src/proxy.rs
index e9e74c0..132e075 100644
--- a/libs/binder/rust/src/proxy.rs
+++ b/libs/binder/rust/src/proxy.rs
@@ -17,7 +17,7 @@
//! Rust API for interacting with a remote binder service.
use crate::binder::{
- AsNative, FromIBinder, IBinder, Interface, InterfaceClass, TransactionCode, TransactionFlags,
+ AsNative, FromIBinder, IBinder, Interface, InterfaceClass, Strong, TransactionCode, TransactionFlags,
};
use crate::error::{status_result, Result, StatusCode};
use crate::parcel::{
@@ -27,6 +27,7 @@
use crate::sys;
use std::convert::TryInto;
+use std::cmp::Ordering;
use std::ffi::{c_void, CString};
use std::fmt;
use std::os::unix::io::AsRawFd;
@@ -99,7 +100,7 @@
///
/// 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>> {
+ pub fn into_interface<I: FromIBinder + Interface + ?Sized>(self) -> Result<Strong<I>> {
FromIBinder::try_from(self)
}
@@ -148,6 +149,36 @@
}
}
+impl Ord for SpIBinder {
+ fn cmp(&self, other: &Self) -> Ordering {
+ let less_than = unsafe {
+ // Safety: SpIBinder always holds a valid `AIBinder` pointer, so
+ // this pointer is always safe to pass to `AIBinder_lt` (null is
+ // also safe to pass to this function, but we should never do that).
+ sys::AIBinder_lt(self.0, other.0)
+ };
+ let greater_than = unsafe {
+ // Safety: SpIBinder always holds a valid `AIBinder` pointer, so
+ // this pointer is always safe to pass to `AIBinder_lt` (null is
+ // also safe to pass to this function, but we should never do that).
+ sys::AIBinder_lt(other.0, self.0)
+ };
+ if !less_than && !greater_than {
+ Ordering::Equal
+ } else if less_than {
+ Ordering::Less
+ } else {
+ Ordering::Greater
+ }
+ }
+}
+
+impl PartialOrd for SpIBinder {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
impl PartialEq for SpIBinder {
fn eq(&self, other: &Self) -> bool {
ptr::eq(self.0, other.0)
@@ -326,7 +357,7 @@
// 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
+ // `AIBinder_DeathRecipient`. 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(
@@ -342,7 +373,7 @@
// 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
+ // `AIBinder_DeathRecipient`. 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(
@@ -430,6 +461,62 @@
}
}
+impl Clone for WpIBinder {
+ fn clone(&self) -> Self {
+ let ptr = unsafe {
+ // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
+ // so this pointer is always safe to pass to `AIBinder_Weak_clone`
+ // (although null is also a safe value to pass to this API).
+ //
+ // We get ownership of the returned pointer, so can construct a new
+ // WpIBinder object from it.
+ sys::AIBinder_Weak_clone(self.0)
+ };
+ assert!(!ptr.is_null(), "Unexpected null pointer from AIBinder_Weak_clone");
+ Self(ptr)
+ }
+}
+
+impl Ord for WpIBinder {
+ fn cmp(&self, other: &Self) -> Ordering {
+ let less_than = unsafe {
+ // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
+ // so this pointer is always safe to pass to `AIBinder_Weak_lt`
+ // (null is also safe to pass to this function, but we should never
+ // do that).
+ sys::AIBinder_Weak_lt(self.0, other.0)
+ };
+ let greater_than = unsafe {
+ // Safety: WpIBinder always holds a valid `AIBinder_Weak` pointer,
+ // so this pointer is always safe to pass to `AIBinder_Weak_lt`
+ // (null is also safe to pass to this function, but we should never
+ // do that).
+ sys::AIBinder_Weak_lt(other.0, self.0)
+ };
+ if !less_than && !greater_than {
+ Ordering::Equal
+ } else if less_than {
+ Ordering::Less
+ } else {
+ Ordering::Greater
+ }
+ }
+}
+
+impl PartialOrd for WpIBinder {
+ fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
+ Some(self.cmp(other))
+ }
+}
+
+impl PartialEq for WpIBinder {
+ fn eq(&self, other: &Self) -> bool {
+ self.cmp(other) == Ordering::Equal
+ }
+}
+
+impl Eq for WpIBinder {}
+
impl Drop for WpIBinder {
fn drop(&mut self) {
unsafe {
@@ -564,7 +651,7 @@
/// 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>> {
+pub fn get_interface<T: FromIBinder + ?Sized>(name: &str) -> Result<Strong<T>> {
let service = get_service(name);
match service {
Some(service) => FromIBinder::try_from(service),
diff --git a/libs/binder/rust/tests/integration.rs b/libs/binder/rust/tests/integration.rs
index bb8c492..719229c 100644
--- a/libs/binder/rust/tests/integration.rs
+++ b/libs/binder/rust/tests/integration.rs
@@ -209,7 +209,7 @@
use std::thread;
use std::time::Duration;
- use binder::{Binder, DeathRecipient, FromIBinder, IBinder, Interface, SpIBinder, StatusCode};
+ use binder::{Binder, DeathRecipient, FromIBinder, IBinder, Interface, SpIBinder, StatusCode, Strong};
use super::{BnTest, ITest, ITestSameDescriptor, RUST_SERVICE_BINARY, TestService};
@@ -271,7 +271,7 @@
fn trivial_client() {
let service_name = "trivial_client_test";
let _process = ScopedServiceProcess::new(service_name);
- let test_client: Box<dyn ITest> =
+ let test_client: Strong<dyn ITest> =
binder::get_interface(service_name).expect("Did not get manager binder service");
assert_eq!(test_client.test().unwrap(), "trivial_client_test");
}
@@ -280,7 +280,7 @@
fn get_selinux_context() {
let service_name = "get_selinux_context";
let _process = ScopedServiceProcess::new(service_name);
- let test_client: Box<dyn ITest> =
+ let test_client: Strong<dyn ITest> =
binder::get_interface(service_name).expect("Did not get manager binder service");
let expected_context = unsafe {
let mut out_ptr = ptr::null_mut();
@@ -453,7 +453,7 @@
let extension = maybe_extension.expect("Remote binder did not have an extension");
- let extension: Box<dyn ITest> = FromIBinder::try_from(extension)
+ let extension: Strong<dyn ITest> = FromIBinder::try_from(extension)
.expect("Extension could not be converted to the expected interface");
assert_eq!(extension.test().unwrap(), extension_name);
@@ -479,7 +479,7 @@
// This should succeed although we will have to treat the service as
// remote.
- let _interface: Box<dyn ITestSameDescriptor> = FromIBinder::try_from(service.as_binder())
+ let _interface: Strong<dyn ITestSameDescriptor> = FromIBinder::try_from(service.as_binder())
.expect("Could not re-interpret service as the ITestSameDescriptor interface");
}
@@ -490,9 +490,60 @@
let service_ibinder = BnTest::new_binder(TestService { s: service_name.to_string() })
.as_binder();
- let service: Box<dyn ITest> = service_ibinder.into_interface()
+ let service: Strong<dyn ITest> = service_ibinder.into_interface()
.expect("Could not reassociate the generic ibinder");
assert_eq!(service.test().unwrap(), service_name);
}
+
+ #[test]
+ fn weak_binder_upgrade() {
+ let service_name = "testing_service";
+ let service = BnTest::new_binder(TestService { s: service_name.to_string() });
+
+ let weak = Strong::downgrade(&service);
+
+ let upgraded = weak.upgrade().expect("Could not upgrade weak binder");
+
+ assert_eq!(service, upgraded);
+ }
+
+ #[test]
+ fn weak_binder_upgrade_dead() {
+ let service_name = "testing_service";
+ let weak = {
+ let service = BnTest::new_binder(TestService { s: service_name.to_string() });
+
+ Strong::downgrade(&service)
+ };
+
+ assert_eq!(weak.upgrade(), Err(StatusCode::DEAD_OBJECT));
+ }
+
+ #[test]
+ fn weak_binder_clone() {
+ let service_name = "testing_service";
+ let service = BnTest::new_binder(TestService { s: service_name.to_string() });
+
+ let weak = Strong::downgrade(&service);
+ let cloned = weak.clone();
+ assert_eq!(weak, cloned);
+
+ let upgraded = weak.upgrade().expect("Could not upgrade weak binder");
+ let clone_upgraded = cloned.upgrade().expect("Could not upgrade weak binder");
+
+ assert_eq!(service, upgraded);
+ assert_eq!(service, clone_upgraded);
+ }
+
+ #[test]
+ #[allow(clippy::eq_op)]
+ fn binder_ord() {
+ let service1 = BnTest::new_binder(TestService { s: "testing_service1".to_string() });
+ let service2 = BnTest::new_binder(TestService { s: "testing_service2".to_string() });
+
+ assert!(!(service1 < service1));
+ assert!(!(service1 > service1));
+ assert_eq!(service1 < service2, !(service2 < service1));
+ }
}
diff --git a/libs/binder/rust/tests/ndk_rust_interop.rs b/libs/binder/rust/tests/ndk_rust_interop.rs
index 70a6dc0..ce75ab7 100644
--- a/libs/binder/rust/tests/ndk_rust_interop.rs
+++ b/libs/binder/rust/tests/ndk_rust_interop.rs
@@ -37,7 +37,7 @@
// The Rust class descriptor pointer will not match the NDK one, but the
// descriptor strings match so this needs to still associate.
- let service: Box<dyn IBinderRustNdkInteropTest> = match binder::get_interface(service_name) {
+ let service: binder::Strong<dyn IBinderRustNdkInteropTest> = match binder::get_interface(service_name) {
Err(e) => {
eprintln!("Could not find Ndk service {}: {:?}", service_name, e);
return StatusCode::NAME_NOT_FOUND as c_int;
@@ -53,7 +53,7 @@
}
// Try using the binder service through the wrong interface type
- let wrong_service: Result<Box<dyn IBinderRustNdkInteropTestOther>, StatusCode> =
+ let wrong_service: Result<binder::Strong<dyn IBinderRustNdkInteropTestOther>, StatusCode> =
binder::get_interface(service_name);
match wrong_service {
Err(e) if e == StatusCode::BAD_TYPE => {}
diff --git a/libs/gralloc/types/Android.bp b/libs/gralloc/types/Android.bp
index 243d7f1..dd0ae30 100644
--- a/libs/gralloc/types/Android.bp
+++ b/libs/gralloc/types/Android.bp
@@ -43,14 +43,14 @@
],
shared_libs: [
- "android.hardware.graphics.common-unstable-ndk_platform",
+ "android.hardware.graphics.common-V2-ndk_platform",
"android.hardware.graphics.mapper@4.0",
"libhidlbase",
"liblog",
],
export_shared_lib_headers: [
- "android.hardware.graphics.common-unstable-ndk_platform",
+ "android.hardware.graphics.common-V2-ndk_platform",
"android.hardware.graphics.mapper@4.0",
"libhidlbase",
],
diff --git a/libs/gui/OWNERS b/libs/gui/OWNERS
index 1667fb0..45c958e 100644
--- a/libs/gui/OWNERS
+++ b/libs/gui/OWNERS
@@ -1,5 +1,4 @@
adyabr@google.com
-akrulec@google.com
alecmouri@google.com
chaviw@google.com
chrisforbes@google.com
@@ -7,7 +6,6 @@
lpy@google.com
mathias@google.com
racarr@google.com
-stoza@google.com
vishnun@google.com
per-file EndToEndNativeInputTest.cpp = svv@google.com
diff --git a/libs/renderengine/OWNERS b/libs/renderengine/OWNERS
index b44456b..08cf2de 100644
--- a/libs/renderengine/OWNERS
+++ b/libs/renderengine/OWNERS
@@ -1,4 +1,3 @@
alecmouri@google.com
jreck@google.com
lpy@google.com
-stoza@google.com
diff --git a/libs/ui/Android.bp b/libs/ui/Android.bp
index 47eb59f..00940ac 100644
--- a/libs/ui/Android.bp
+++ b/libs/ui/Android.bp
@@ -72,7 +72,7 @@
"android.hardware.graphics.allocator@2.0",
"android.hardware.graphics.allocator@3.0",
"android.hardware.graphics.allocator@4.0",
- "android.hardware.graphics.common-unstable-ndk_platform",
+ "android.hardware.graphics.common-V2-ndk_platform",
"android.hardware.graphics.common@1.2",
"android.hardware.graphics.mapper@2.0",
"android.hardware.graphics.mapper@2.1",
@@ -89,7 +89,7 @@
export_shared_lib_headers: [
"android.hardware.graphics.common@1.2",
- "android.hardware.graphics.common-unstable-ndk_platform",
+ "android.hardware.graphics.common-V2-ndk_platform",
"android.hardware.graphics.mapper@4.0",
"libgralloctypes",
],
diff --git a/libs/ui/OWNERS b/libs/ui/OWNERS
index b1317b1..5110a6c 100644
--- a/libs/ui/OWNERS
+++ b/libs/ui/OWNERS
@@ -4,4 +4,3 @@
lpy@google.com
mathias@google.com
romainguy@google.com
-stoza@google.com
diff --git a/services/inputflinger/tests/fuzzers/Android.bp b/services/inputflinger/tests/fuzzers/Android.bp
new file mode 100644
index 0000000..9018aca
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/Android.bp
@@ -0,0 +1,112 @@
+//
+// 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.
+//
+
+cc_defaults {
+ name: "inputflinger_fuzz_defaults",
+ defaults: [
+ "inputflinger_defaults",
+ ],
+ include_dirs: [
+ "frameworks/native/services/inputflinger",
+ ],
+ shared_libs: [
+ "android.hardware.input.classifier@1.0",
+ "libbase",
+ "libbinder",
+ "libcutils",
+ "liblog",
+ "libutils",
+ "libui",
+ "libinput",
+ "libinputflinger",
+ "libinputreader",
+ "libinputflinger_base",
+ "libstatslog",
+ ],
+ header_libs: [
+ "libinputreader_headers",
+ ],
+}
+
+cc_fuzz {
+ name: "inputflinger_cursor_input_fuzzer",
+ defaults: [
+ "inputflinger_fuzz_defaults",
+ ],
+ srcs: [
+ "CursorInputFuzzer.cpp",
+ ],
+}
+
+cc_fuzz {
+ name: "inputflinger_keyboard_input_fuzzer",
+ defaults: [
+ "inputflinger_fuzz_defaults",
+ ],
+ srcs: [
+ "KeyboardInputFuzzer.cpp",
+ ],
+}
+
+cc_fuzz {
+ name: "inputflinger_multitouch_input_fuzzer",
+ defaults: [
+ "inputflinger_fuzz_defaults",
+ ],
+ srcs: [
+ "MultiTouchInputFuzzer.cpp",
+ ],
+}
+
+cc_fuzz {
+ name: "inputflinger_switch_input_fuzzer",
+ defaults: [
+ "inputflinger_fuzz_defaults",
+ ],
+ srcs: [
+ "SwitchInputFuzzer.cpp",
+ ],
+}
+
+cc_fuzz {
+ name: "inputflinger_input_reader_device_fuzzer",
+ defaults: [
+ "inputflinger_fuzz_defaults",
+ ],
+ srcs: [
+ "InputReaderDeviceFuzzer.cpp",
+ ],
+}
+
+cc_fuzz {
+ name: "inputflinger_blocking_queue_fuzzer",
+ defaults: [
+ "inputflinger_fuzz_defaults",
+ ],
+ srcs: [
+ "BlockingQueueFuzzer.cpp",
+ ],
+}
+
+cc_fuzz {
+ name: "inputflinger_input_classifier_fuzzer",
+ defaults: [
+ "inputflinger_fuzz_defaults",
+ ],
+ srcs: [
+ "InputClassifierFuzzer.cpp",
+ ],
+}
diff --git a/services/inputflinger/tests/fuzzers/BlockingQueueFuzzer.cpp b/services/inputflinger/tests/fuzzers/BlockingQueueFuzzer.cpp
new file mode 100644
index 0000000..6a136cf
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/BlockingQueueFuzzer.cpp
@@ -0,0 +1,69 @@
+/*
+ * Copyright 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 <fuzzer/FuzzedDataProvider.h>
+#include <thread>
+#include "BlockingQueue.h"
+
+// Chosen to be a number large enough for variation in fuzzer runs, but not consume too much memory.
+static constexpr size_t MAX_CAPACITY = 1024;
+
+namespace android {
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
+ FuzzedDataProvider fdp(data, size);
+ size_t capacity = fdp.ConsumeIntegralInRange<size_t>(1, MAX_CAPACITY);
+ size_t filled = 0;
+ BlockingQueue<int32_t> queue(capacity);
+
+ while (fdp.remaining_bytes() > 0) {
+ fdp.PickValueInArray<std::function<void()>>({
+ [&]() -> void {
+ size_t numPushes = fdp.ConsumeIntegralInRange<size_t>(0, capacity + 1);
+ for (size_t i = 0; i < numPushes; i++) {
+ queue.push(fdp.ConsumeIntegral<int32_t>());
+ }
+ filled = std::min(capacity, filled + numPushes);
+ },
+ [&]() -> void {
+ // Pops blocks if it is empty, so only pop up to num elements inserted.
+ size_t numPops = fdp.ConsumeIntegralInRange<size_t>(0, filled);
+ for (size_t i = 0; i < numPops; i++) {
+ queue.pop();
+ }
+ filled > numPops ? filled -= numPops : filled = 0;
+ },
+ [&]() -> void {
+ queue.clear();
+ filled = 0;
+ },
+ [&]() -> void {
+ int32_t eraseElement = fdp.ConsumeIntegral<int32_t>();
+ queue.erase([&](int32_t element) {
+ if (element == eraseElement) {
+ filled--;
+ return true;
+ }
+ return false;
+ });
+ },
+ })();
+ }
+
+ return 0;
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp
new file mode 100644
index 0000000..8aa7434
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/CursorInputFuzzer.cpp
@@ -0,0 +1,90 @@
+/*
+ * Copyright 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 <CursorInputMapper.h>
+#include <FuzzContainer.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+void addProperty(FuzzContainer& fuzzer, std::shared_ptr<FuzzedDataProvider> fdp) {
+ // Pick a random property to set for the mapper to have set.
+ fdp->PickValueInArray<std::function<void()>>(
+ {[&]() -> void { fuzzer.addProperty(String8("cursor.mode"), String8("pointer")); },
+ [&]() -> void { fuzzer.addProperty(String8("cursor.mode"), String8("navigation")); },
+ [&]() -> void {
+ fuzzer.addProperty(String8("cursor.mode"),
+ String8(fdp->ConsumeRandomLengthString(100).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("cursor.orientationAware"),
+ String8(fdp->ConsumeRandomLengthString(100).data()));
+ }})();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
+ std::shared_ptr<FuzzedDataProvider> fdp = std::make_shared<FuzzedDataProvider>(data, size);
+ FuzzContainer fuzzer = FuzzContainer(fdp);
+
+ CursorInputMapper& mapper = fuzzer.getMapper<CursorInputMapper>();
+ auto policyConfig = fuzzer.getPolicyConfig();
+
+ // Loop through mapper operations until randomness is exhausted.
+ while (fdp->remaining_bytes() > 0) {
+ fdp->PickValueInArray<std::function<void()>>({
+ [&]() -> void { addProperty(fuzzer, fdp); },
+ [&]() -> void {
+ std::string dump;
+ mapper.dump(dump);
+ },
+ [&]() -> void { mapper.getSources(); },
+ [&]() -> void {
+ mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig,
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void {
+ // Need to reconfigure with 0 or you risk a NPE.
+ mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig, 0);
+ InputDeviceInfo info;
+ mapper.populateDeviceInfo(&info);
+ },
+ [&]() -> void {
+ // Need to reconfigure with 0 or you risk a NPE.
+ mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig, 0);
+ RawEvent rawEvent{fdp->ConsumeIntegral<nsecs_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>()};
+ mapper.process(&rawEvent);
+ },
+ [&]() -> void { mapper.reset(fdp->ConsumeIntegral<nsecs_t>()); },
+ [&]() -> void {
+ mapper.getScanCodeState(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void {
+ // Need to reconfigure with 0 or you risk a NPE.
+ mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig, 0);
+ mapper.getAssociatedDisplayId();
+ },
+ })();
+ }
+
+ return 0;
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/FuzzContainer.h b/services/inputflinger/tests/fuzzers/FuzzContainer.h
new file mode 100644
index 0000000..84f0566
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/FuzzContainer.h
@@ -0,0 +1,84 @@
+/*
+ * Copyright 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.
+ */
+
+#pragma once
+
+#include <InputDevice.h>
+#include <InputMapper.h>
+#include <InputReader.h>
+#include <MapperHelpers.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+class FuzzContainer {
+ int32_t meventID;
+ std::shared_ptr<FuzzEventHub> mFuzzEventHub;
+ sp<FuzzInputReaderPolicy> mFuzzPolicy;
+ sp<FuzzInputListener> mFuzzListener;
+ std::unique_ptr<FuzzInputReaderContext> mFuzzContext;
+ std::unique_ptr<InputDevice> mFuzzDevice;
+ InputReaderConfiguration mPolicyConfig;
+ std::shared_ptr<FuzzedDataProvider> fdp;
+
+public:
+ FuzzContainer(std::shared_ptr<FuzzedDataProvider> fdp) : fdp(fdp) {
+ // Setup parameters.
+ std::string deviceName = fdp->ConsumeRandomLengthString(16);
+ std::string deviceLocation = fdp->ConsumeRandomLengthString(12);
+ int32_t deviceID = fdp->ConsumeIntegralInRange<int32_t>(0, 5);
+ int32_t deviceGeneration = fdp->ConsumeIntegralInRange<int32_t>(0, 5);
+ meventID = fdp->ConsumeIntegral<int32_t>();
+
+ // Create mocked objects.
+ mFuzzEventHub = std::make_shared<FuzzEventHub>(fdp);
+ mFuzzPolicy = new FuzzInputReaderPolicy(fdp);
+ mFuzzListener = new FuzzInputListener();
+ mFuzzContext = std::make_unique<FuzzInputReaderContext>(mFuzzEventHub, mFuzzPolicy,
+ mFuzzListener, fdp);
+
+ InputDeviceIdentifier identifier;
+ identifier.name = deviceName;
+ identifier.location = deviceLocation;
+ mFuzzDevice = std::make_unique<InputDevice>(mFuzzContext.get(), deviceID, deviceGeneration,
+ identifier);
+ mFuzzPolicy->getReaderConfiguration(&mPolicyConfig);
+ }
+
+ ~FuzzContainer() {}
+
+ void configureDevice() {
+ nsecs_t arbitraryTime = fdp->ConsumeIntegral<nsecs_t>();
+ mFuzzDevice->configure(arbitraryTime, &mPolicyConfig, 0);
+ mFuzzDevice->reset(arbitraryTime);
+ }
+
+ void addProperty(const String8& key, const String8& value) {
+ mFuzzEventHub->addProperty(key, value);
+ configureDevice();
+ }
+
+ InputReaderConfiguration& getPolicyConfig() { return mPolicyConfig; }
+
+ template <class T, typename... Args>
+ T& getMapper(Args... args) {
+ T& mapper = mFuzzDevice->addMapper<T>(fdp->ConsumeIntegral<int32_t>(), args...);
+ configureDevice();
+ return mapper;
+ }
+};
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp b/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp
new file mode 100644
index 0000000..7f91000
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/InputClassifierFuzzer.cpp
@@ -0,0 +1,120 @@
+/*
+ * Copyright 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 <MapperHelpers.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include "InputClassifier.h"
+#include "InputClassifierConverter.h"
+
+namespace android {
+
+static constexpr int32_t MAX_AXES = 64;
+
+// Used by two fuzz operations and a bit lengthy, so pulled out into a function.
+NotifyMotionArgs generateFuzzedMotionArgs(FuzzedDataProvider &fdp) {
+ // Create a basic motion event for testing
+ PointerProperties properties;
+ properties.id = 0;
+ properties.toolType = AMOTION_EVENT_TOOL_TYPE_FINGER;
+ PointerCoords coords;
+ coords.clear();
+ for (int32_t i = 0; i < fdp.ConsumeIntegralInRange<int32_t>(0, MAX_AXES); i++) {
+ coords.setAxisValue(fdp.ConsumeIntegral<int32_t>(), fdp.ConsumeFloatingPoint<float>());
+ }
+
+ nsecs_t downTime = 2;
+ NotifyMotionArgs motionArgs(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/,
+ downTime /*eventTime*/, fdp.ConsumeIntegral<int32_t>() /*deviceId*/,
+ AINPUT_SOURCE_ANY, ADISPLAY_ID_DEFAULT,
+ fdp.ConsumeIntegral<uint32_t>() /*policyFlags*/,
+ AMOTION_EVENT_ACTION_DOWN,
+ fdp.ConsumeIntegral<int32_t>() /*actionButton*/,
+ fdp.ConsumeIntegral<int32_t>() /*flags*/, AMETA_NONE,
+ fdp.ConsumeIntegral<int32_t>() /*buttonState*/,
+ MotionClassification::NONE, AMOTION_EVENT_EDGE_FLAG_NONE,
+ 1 /*pointerCount*/, &properties, &coords,
+ fdp.ConsumeFloatingPoint<float>() /*xPrecision*/,
+ fdp.ConsumeFloatingPoint<float>() /*yPrecision*/,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION,
+ AMOTION_EVENT_INVALID_CURSOR_POSITION, downTime,
+ {} /*videoFrames*/);
+ return motionArgs;
+}
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
+ FuzzedDataProvider fdp(data, size);
+
+ sp<FuzzInputListener> mFuzzListener = new FuzzInputListener();
+ sp<InputClassifierInterface> mClassifier = new InputClassifier(mFuzzListener);
+
+ while (fdp.remaining_bytes() > 0) {
+ fdp.PickValueInArray<std::function<void()>>({
+ [&]() -> void {
+ // SendToNextStage_NotifyConfigurationChangedArgs
+ NotifyConfigurationChangedArgs
+ args(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/,
+ fdp.ConsumeIntegral<nsecs_t>() /*eventTime*/);
+ mClassifier->notifyConfigurationChanged(&args);
+ },
+ [&]() -> void {
+ // SendToNextStage_NotifyKeyArgs
+ NotifyKeyArgs keyArgs(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/,
+ fdp.ConsumeIntegral<nsecs_t>() /*eventTime*/,
+ fdp.ConsumeIntegral<int32_t>() /*deviceId*/,
+ AINPUT_SOURCE_KEYBOARD, ADISPLAY_ID_DEFAULT,
+ fdp.ConsumeIntegral<uint32_t>() /*policyFlags*/,
+ AKEY_EVENT_ACTION_DOWN,
+ fdp.ConsumeIntegral<int32_t>() /*flags*/, AKEYCODE_HOME,
+ fdp.ConsumeIntegral<int32_t>() /*scanCode*/, AMETA_NONE,
+ fdp.ConsumeIntegral<nsecs_t>() /*downTime*/);
+
+ mClassifier->notifyKey(&keyArgs);
+ },
+ [&]() -> void {
+ // SendToNextStage_NotifyMotionArgs
+ NotifyMotionArgs motionArgs = generateFuzzedMotionArgs(fdp);
+ mClassifier->notifyMotion(&motionArgs);
+ },
+ [&]() -> void {
+ // SendToNextStage_NotifySwitchArgs
+ NotifySwitchArgs switchArgs(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/,
+ fdp.ConsumeIntegral<nsecs_t>() /*eventTime*/,
+ fdp.ConsumeIntegral<uint32_t>() /*policyFlags*/,
+ fdp.ConsumeIntegral<uint32_t>() /*switchValues*/,
+ fdp.ConsumeIntegral<uint32_t>() /*switchMask*/);
+
+ mClassifier->notifySwitch(&switchArgs);
+ },
+ [&]() -> void {
+ // SendToNextStage_NotifyDeviceResetArgs
+ NotifyDeviceResetArgs resetArgs(fdp.ConsumeIntegral<uint32_t>() /*sequenceNum*/,
+ fdp.ConsumeIntegral<nsecs_t>() /*eventTime*/,
+ fdp.ConsumeIntegral<int32_t>() /*deviceId*/);
+
+ mClassifier->notifyDeviceReset(&resetArgs);
+ },
+ [&]() -> void {
+ // InputClassifierConverterTest
+ const NotifyMotionArgs motionArgs = generateFuzzedMotionArgs(fdp);
+ hardware::input::common::V1_0::MotionEvent motionEvent =
+ notifyMotionArgsToHalMotionEvent(motionArgs);
+ },
+ })();
+ }
+ return 0;
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/InputReaderDeviceFuzzer.cpp b/services/inputflinger/tests/fuzzers/InputReaderDeviceFuzzer.cpp
new file mode 100644
index 0000000..9194891
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/InputReaderDeviceFuzzer.cpp
@@ -0,0 +1,103 @@
+/*
+ * Copyright 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 <InputReader.h>
+#include <MapperHelpers.h>
+#include <fuzzer/FuzzedDataProvider.h>
+#include <chrono>
+#include <thread>
+
+namespace android {
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
+ std::shared_ptr<FuzzedDataProvider> fdp = std::make_shared<FuzzedDataProvider>(data, size);
+
+ sp<FuzzInputListener> fuzzListener = new FuzzInputListener();
+ sp<FuzzInputReaderPolicy> fuzzPolicy = new FuzzInputReaderPolicy(fdp);
+ std::shared_ptr<FuzzEventHub> fuzzEventHub = std::make_shared<FuzzEventHub>(fdp);
+ std::unique_ptr<InputReader> reader =
+ std::make_unique<InputReader>(fuzzEventHub, fuzzPolicy, fuzzListener);
+
+ fuzzEventHub->addEvents(fdp);
+ reader->start();
+
+ // Loop through mapper operations until randomness is exhausted.
+ while (fdp->remaining_bytes() > 0) {
+ fdp->PickValueInArray<std::function<void()>>({
+ [&]() -> void {
+ std::string dump;
+ reader->dump(dump);
+ },
+ [&]() -> void { reader->monitor(); },
+ [&]() -> void { fuzzEventHub->addEvents(fdp); },
+ [&]() -> void {
+ std::vector<InputDeviceInfo> inputDevices;
+ reader->getInputDevices(inputDevices);
+ },
+ [&]() -> void { reader->isInputDeviceEnabled(fdp->ConsumeIntegral<int32_t>()); },
+ [&]() -> void {
+ reader->getScanCodeState(fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void {
+ reader->getKeyCodeState(fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void {
+ reader->getSwitchState(fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void { reader->toggleCapsLockState(fdp->ConsumeIntegral<int32_t>()); },
+ [&]() -> void {
+ size_t count = fdp->ConsumeIntegralInRange<size_t>(1, 1024);
+ uint8_t* outFlags = new uint8_t[count];
+ reader->hasKeys(fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<uint32_t>(), count, nullptr, outFlags);
+ delete[] outFlags;
+ },
+ [&]() -> void {
+ reader->requestRefreshConfiguration(fdp->ConsumeIntegral<uint32_t>());
+ },
+ [&]() -> void {
+ // 260 is slightly higher than the maximum intended size of 256.
+ size_t count = fdp->ConsumeIntegralInRange<size_t>(0, 260);
+ nsecs_t pattern[count];
+
+ for (size_t i = 0; i < count; i++) pattern[i] = fdp->ConsumeIntegral<nsecs_t>();
+
+ reader->vibrate(fdp->ConsumeIntegral<int32_t>(), pattern, count,
+ fdp->ConsumeIntegral<ssize_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void {
+ reader->cancelVibrate(fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void {
+ reader->canDispatchToDisplay(fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ })();
+ }
+
+ reader->stop();
+ return 0;
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp
new file mode 100644
index 0000000..854e2fd
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/KeyboardInputFuzzer.cpp
@@ -0,0 +1,99 @@
+/*
+ * Copyright 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 <FuzzContainer.h>
+#include <KeyboardInputMapper.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+void addProperty(FuzzContainer& fuzzer, std::shared_ptr<FuzzedDataProvider> fdp) {
+ // Pick a random property to set for the mapper to have set.
+ fdp->PickValueInArray<std::function<void()>>(
+ {[&]() -> void {
+ fuzzer.addProperty(String8("keyboard.orientationAware"), String8("1"));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("keyboard.orientationAware"),
+ String8(fdp->ConsumeRandomLengthString(100).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("keyboard.doNotWakeByDefault"),
+ String8(fdp->ConsumeRandomLengthString(100).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("keyboard.handlesKeyRepeat"),
+ String8(fdp->ConsumeRandomLengthString(100).data()));
+ }})();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
+ std::shared_ptr<FuzzedDataProvider> fdp = std::make_shared<FuzzedDataProvider>(data, size);
+ FuzzContainer fuzzer = FuzzContainer(fdp);
+
+ KeyboardInputMapper& mapper =
+ fuzzer.getMapper<KeyboardInputMapper>(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ auto policyConfig = fuzzer.getPolicyConfig();
+
+ // Loop through mapper operations until randomness is exhausted.
+ while (fdp->remaining_bytes() > 0) {
+ fdp->PickValueInArray<std::function<void()>>({
+ [&]() -> void { addProperty(fuzzer, fdp); },
+ [&]() -> void {
+ std::string dump;
+ mapper.dump(dump);
+ },
+ [&]() -> void {
+ InputDeviceInfo info;
+ mapper.populateDeviceInfo(&info);
+ },
+ [&]() -> void { mapper.getSources(); },
+ [&]() -> void {
+ mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig,
+ fdp->ConsumeIntegral<uint32_t>());
+ },
+ [&]() -> void { mapper.reset(fdp->ConsumeIntegral<nsecs_t>()); },
+ [&]() -> void {
+ RawEvent rawEvent{fdp->ConsumeIntegral<nsecs_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>()};
+ mapper.process(&rawEvent);
+ },
+ [&]() -> void {
+ mapper.getKeyCodeState(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void {
+ mapper.getScanCodeState(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void {
+ mapper.markSupportedKeyCodes(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<size_t>(), nullptr, nullptr);
+ },
+ [&]() -> void { mapper.getMetaState(); },
+ [&]() -> void { mapper.updateMetaState(fdp->ConsumeIntegral<int32_t>()); },
+ [&]() -> void { mapper.getAssociatedDisplayId(); },
+ })();
+ }
+
+ return 0;
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/MapperHelpers.h b/services/inputflinger/tests/fuzzers/MapperHelpers.h
new file mode 100644
index 0000000..edfb68d
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/MapperHelpers.h
@@ -0,0 +1,224 @@
+/*
+ * Copyright 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.
+ */
+
+#pragma once
+
+#include <InputDevice.h>
+#include <InputMapper.h>
+#include <InputReader.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+class FuzzEventHub : public EventHubInterface {
+ InputDeviceIdentifier mIdentifier;
+ std::vector<TouchVideoFrame> mVideoFrames;
+ PropertyMap mFuzzConfig;
+ std::mutex mEventLock;
+ size_t mCount = 0;
+ RawEvent mBuf[256];
+ std::shared_ptr<FuzzedDataProvider> fdp;
+
+public:
+ FuzzEventHub(std::shared_ptr<FuzzedDataProvider> fdp) : fdp(fdp) {}
+ ~FuzzEventHub() {}
+ void addProperty(const String8& key, const String8 value) {
+ mFuzzConfig.addProperty(key, value);
+ }
+ void addEvents(std::shared_ptr<FuzzedDataProvider> fdp) {
+ std::lock_guard<std::mutex> guard(mEventLock);
+ mCount = fdp->ConsumeIntegralInRange<size_t>(0, 256);
+
+ for (size_t i = 0; i < mCount; i++)
+ mBuf[i] = {fdp->ConsumeIntegral<nsecs_t>(), fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(), fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>()};
+ }
+ uint32_t getDeviceClasses(int32_t deviceId) const override {
+ return fdp->ConsumeIntegral<uint32_t>();
+ }
+ InputDeviceIdentifier getDeviceIdentifier(int32_t deviceId) const override {
+ return mIdentifier;
+ }
+ int32_t getDeviceControllerNumber(int32_t deviceId) const override {
+ return fdp->ConsumeIntegral<int32_t>();
+ }
+ void getConfiguration(int32_t deviceId, PropertyMap* outConfiguration) const override {
+ *outConfiguration = mFuzzConfig;
+ }
+ status_t getAbsoluteAxisInfo(int32_t deviceId, int axis,
+ RawAbsoluteAxisInfo* outAxisInfo) const override {
+ return fdp->ConsumeIntegral<status_t>();
+ }
+ bool hasRelativeAxis(int32_t deviceId, int axis) const override { return fdp->ConsumeBool(); }
+ bool hasInputProperty(int32_t deviceId, int property) const override {
+ return fdp->ConsumeBool();
+ }
+ status_t mapKey(int32_t deviceId, int32_t scanCode, int32_t usageCode, int32_t metaState,
+ int32_t* outKeycode, int32_t* outMetaState, uint32_t* outFlags) const override {
+ return fdp->ConsumeIntegral<status_t>();
+ }
+ status_t mapAxis(int32_t deviceId, int32_t scanCode, AxisInfo* outAxisInfo) const override {
+ return fdp->ConsumeIntegral<status_t>();
+ }
+ void setExcludedDevices(const std::vector<std::string>& devices) override {}
+ size_t getEvents(int timeoutMillis, RawEvent* buffer, size_t bufferSize) override {
+ std::lock_guard<std::mutex> guard(mEventLock);
+ for (size_t i = 0; i < mCount; i++) buffer[i] = mBuf[i];
+
+ return mCount;
+ }
+ std::vector<TouchVideoFrame> getVideoFrames(int32_t deviceId) override { return mVideoFrames; }
+ int32_t getScanCodeState(int32_t deviceId, int32_t scanCode) const override {
+ return fdp->ConsumeIntegral<int32_t>();
+ }
+ int32_t getKeyCodeState(int32_t deviceId, int32_t keyCode) const override {
+ return fdp->ConsumeIntegral<int32_t>();
+ }
+ int32_t getSwitchState(int32_t deviceId, int32_t sw) const override {
+ return fdp->ConsumeIntegral<int32_t>();
+ }
+ status_t getAbsoluteAxisValue(int32_t deviceId, int32_t axis,
+ int32_t* outValue) const override {
+ return fdp->ConsumeIntegral<status_t>();
+ }
+ bool markSupportedKeyCodes(int32_t deviceId, size_t numCodes, const int32_t* keyCodes,
+ uint8_t* outFlags) const override {
+ return fdp->ConsumeBool();
+ }
+ bool hasScanCode(int32_t deviceId, int32_t scanCode) const override {
+ return fdp->ConsumeBool();
+ }
+ bool hasLed(int32_t deviceId, int32_t led) const override { return fdp->ConsumeBool(); }
+ void setLedState(int32_t deviceId, int32_t led, bool on) override {}
+ void getVirtualKeyDefinitions(
+ int32_t deviceId, std::vector<VirtualKeyDefinition>& outVirtualKeys) const override {}
+ sp<KeyCharacterMap> getKeyCharacterMap(int32_t deviceId) const override { return nullptr; }
+ bool setKeyboardLayoutOverlay(int32_t deviceId, const sp<KeyCharacterMap>& map) override {
+ return fdp->ConsumeBool();
+ }
+ void vibrate(int32_t deviceId, nsecs_t duration) override {}
+ void cancelVibrate(int32_t deviceId) override {}
+ void requestReopenDevices() override {}
+ void wake() override {}
+ void dump(std::string& dump) override {}
+ void monitor() override {}
+ bool isDeviceEnabled(int32_t deviceId) override { return fdp->ConsumeBool(); }
+ status_t enableDevice(int32_t deviceId) override { return fdp->ConsumeIntegral<status_t>(); }
+ status_t disableDevice(int32_t deviceId) override { return fdp->ConsumeIntegral<status_t>(); }
+};
+
+class FuzzPointerController : public PointerControllerInterface {
+ std::shared_ptr<FuzzedDataProvider> fdp;
+
+public:
+ FuzzPointerController(std::shared_ptr<FuzzedDataProvider> fdp) : fdp(fdp) {}
+ ~FuzzPointerController() {}
+ bool getBounds(float* outMinX, float* outMinY, float* outMaxX, float* outMaxY) const override {
+ return fdp->ConsumeBool();
+ }
+ void move(float deltaX, float deltaY) override {}
+ void setButtonState(int32_t buttonState) override {}
+ int32_t getButtonState() const override { return fdp->ConsumeIntegral<int32_t>(); }
+ void setPosition(float x, float y) override {}
+ void getPosition(float* outX, float* outY) const override {}
+ void fade(Transition transition) override {}
+ void unfade(Transition transition) override {}
+ void setPresentation(Presentation presentation) override {}
+ void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
+ BitSet32 spotIdBits, int32_t displayId) override {}
+ void clearSpots() override {}
+ int32_t getDisplayId() const override { return fdp->ConsumeIntegral<int32_t>(); }
+ void setDisplayViewport(const DisplayViewport& displayViewport) override {}
+};
+
+class FuzzInputReaderPolicy : public InputReaderPolicyInterface {
+ TouchAffineTransformation mTransform;
+ std::shared_ptr<FuzzPointerController> mPointerController;
+ std::shared_ptr<FuzzedDataProvider> fdp;
+
+protected:
+ ~FuzzInputReaderPolicy() {}
+
+public:
+ FuzzInputReaderPolicy(std::shared_ptr<FuzzedDataProvider> fdp) : fdp(fdp) {
+ mPointerController = std::make_shared<FuzzPointerController>(fdp);
+ }
+ void getReaderConfiguration(InputReaderConfiguration* outConfig) override {}
+ std::shared_ptr<PointerControllerInterface> obtainPointerController(int32_t deviceId) override {
+ return mPointerController;
+ }
+ void notifyInputDevicesChanged(const std::vector<InputDeviceInfo>& inputDevices) override {}
+ sp<KeyCharacterMap> getKeyboardLayoutOverlay(const InputDeviceIdentifier& identifier) override {
+ return nullptr;
+ }
+ std::string getDeviceAlias(const InputDeviceIdentifier& identifier) {
+ return fdp->ConsumeRandomLengthString(32);
+ }
+ TouchAffineTransformation getTouchAffineTransformation(const std::string& inputDeviceDescriptor,
+ int32_t surfaceRotation) override {
+ return mTransform;
+ }
+ void setTouchAffineTransformation(const TouchAffineTransformation t) { mTransform = t; }
+};
+
+class FuzzInputListener : public virtual InputListenerInterface {
+protected:
+ ~FuzzInputListener() {}
+
+public:
+ FuzzInputListener() {}
+ void notifyConfigurationChanged(const NotifyConfigurationChangedArgs* args) override {}
+ void notifyKey(const NotifyKeyArgs* args) override {}
+ void notifyMotion(const NotifyMotionArgs* args) override {}
+ void notifySwitch(const NotifySwitchArgs* args) override {}
+ void notifyDeviceReset(const NotifyDeviceResetArgs* args) override {}
+};
+
+class FuzzInputReaderContext : public InputReaderContext {
+ std::shared_ptr<EventHubInterface> mEventHub;
+ sp<InputReaderPolicyInterface> mPolicy;
+ sp<InputListenerInterface> mListener;
+ std::shared_ptr<FuzzedDataProvider> fdp;
+
+public:
+ FuzzInputReaderContext(std::shared_ptr<EventHubInterface> eventHub,
+ const sp<InputReaderPolicyInterface>& policy,
+ const sp<InputListenerInterface>& listener,
+ std::shared_ptr<FuzzedDataProvider> fdp)
+ : mEventHub(eventHub), mPolicy(policy), mListener(listener), fdp(fdp) {}
+ ~FuzzInputReaderContext() {}
+ void updateGlobalMetaState() override {}
+ int32_t getGlobalMetaState() { return fdp->ConsumeIntegral<int32_t>(); }
+ void disableVirtualKeysUntil(nsecs_t time) override {}
+ bool shouldDropVirtualKey(nsecs_t now, int32_t keyCode, int32_t scanCode) override {
+ return fdp->ConsumeBool();
+ }
+ void fadePointer() override {}
+ std::shared_ptr<PointerControllerInterface> getPointerController(int32_t deviceId) override {
+ return mPolicy->obtainPointerController(0);
+ }
+ void requestTimeoutAtTime(nsecs_t when) override {}
+ int32_t bumpGeneration() override { return fdp->ConsumeIntegral<int32_t>(); }
+ void getExternalStylusDevices(std::vector<InputDeviceInfo>& outDevices) override {}
+ void dispatchExternalStylusState(const StylusState& outState) override {}
+ InputReaderPolicyInterface* getPolicy() override { return mPolicy.get(); }
+ InputListenerInterface* getListener() override { return mListener.get(); }
+ EventHubInterface* getEventHub() override { return mEventHub.get(); }
+ int32_t getNextId() override { return fdp->ConsumeIntegral<int32_t>(); }
+};
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp
new file mode 100644
index 0000000..336ecb6
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/MultiTouchInputFuzzer.cpp
@@ -0,0 +1,124 @@
+/*
+ * Copyright 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 <FuzzContainer.h>
+#include <MultiTouchInputMapper.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+void addProperty(FuzzContainer& fuzzer, std::shared_ptr<FuzzedDataProvider> fdp) {
+ // Pick a random property to set for the mapper to have set.
+ fdp->PickValueInArray<std::function<void()>>(
+ {[&]() -> void {
+ fuzzer.addProperty(String8("touch.deviceType"), String8("touchScreen"));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("touch.deviceType"),
+ String8(fdp->ConsumeRandomLengthString(8).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("touch.size.scale"),
+ String8(fdp->ConsumeRandomLengthString(8).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("touch.size.bias"),
+ String8(fdp->ConsumeRandomLengthString(8).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("touch.size.isSummed"),
+ String8(fdp->ConsumeRandomLengthString(8).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("touch.size.calibration"),
+ String8(fdp->ConsumeRandomLengthString(8).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("touch.pressure.scale"),
+ String8(fdp->ConsumeRandomLengthString(8).data()));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("touch.size.calibration"),
+ fdp->ConsumeBool() ? String8("diameter") : String8("area"));
+ },
+ [&]() -> void {
+ fuzzer.addProperty(String8("touch.pressure.calibration"),
+ String8(fdp->ConsumeRandomLengthString(8).data()));
+ }})();
+}
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
+ std::shared_ptr<FuzzedDataProvider> fdp = std::make_shared<FuzzedDataProvider>(data, size);
+ FuzzContainer fuzzer = FuzzContainer(fdp);
+
+ MultiTouchInputMapper& mapper = fuzzer.getMapper<MultiTouchInputMapper>();
+ auto policyConfig = fuzzer.getPolicyConfig();
+
+ // Loop through mapper operations until randomness is exhausted.
+ while (fdp->remaining_bytes() > 0) {
+ fdp->PickValueInArray<std::function<void()>>({
+ [&]() -> void { addProperty(fuzzer, fdp); },
+ [&]() -> void {
+ std::string dump;
+ mapper.dump(dump);
+ },
+ [&]() -> void {
+ InputDeviceInfo info;
+ mapper.populateDeviceInfo(&info);
+ },
+ [&]() -> void { mapper.getSources(); },
+ [&]() -> void {
+ mapper.configure(fdp->ConsumeIntegral<nsecs_t>(), &policyConfig,
+ fdp->ConsumeIntegral<uint32_t>());
+ },
+ [&]() -> void { mapper.reset(fdp->ConsumeIntegral<nsecs_t>()); },
+ [&]() -> void {
+ RawEvent rawEvent{fdp->ConsumeIntegral<nsecs_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>()};
+ mapper.process(&rawEvent);
+ },
+ [&]() -> void {
+ mapper.getKeyCodeState(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void {
+ mapper.getScanCodeState(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ [&]() -> void {
+ mapper.markSupportedKeyCodes(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<size_t>(), nullptr, nullptr);
+ },
+ [&]() -> void { mapper.cancelTouch(fdp->ConsumeIntegral<nsecs_t>()); },
+ [&]() -> void { mapper.timeoutExpired(fdp->ConsumeIntegral<nsecs_t>()); },
+ [&]() -> void {
+ StylusState state{fdp->ConsumeIntegral<nsecs_t>(),
+ fdp->ConsumeFloatingPoint<float>(),
+ fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>()};
+ mapper.updateExternalStylusState(state);
+ },
+ [&]() -> void { mapper.getAssociatedDisplayId(); },
+ })();
+ }
+
+ return 0;
+}
+
+} // namespace android
diff --git a/services/inputflinger/tests/fuzzers/SwitchInputFuzzer.cpp b/services/inputflinger/tests/fuzzers/SwitchInputFuzzer.cpp
new file mode 100644
index 0000000..ae7429c
--- /dev/null
+++ b/services/inputflinger/tests/fuzzers/SwitchInputFuzzer.cpp
@@ -0,0 +1,56 @@
+/*
+ * Copyright 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 <FuzzContainer.h>
+#include <SwitchInputMapper.h>
+#include <fuzzer/FuzzedDataProvider.h>
+
+namespace android {
+
+extern "C" int LLVMFuzzerTestOneInput(uint8_t* data, size_t size) {
+ std::shared_ptr<FuzzedDataProvider> fdp = std::make_shared<FuzzedDataProvider>(data, size);
+ FuzzContainer fuzzer = FuzzContainer(fdp);
+
+ SwitchInputMapper& mapper = fuzzer.getMapper<SwitchInputMapper>();
+ auto policyConfig = fuzzer.getPolicyConfig();
+
+ // Loop through mapper operations until randomness is exhausted.
+ while (fdp->remaining_bytes() > 0) {
+ fdp->PickValueInArray<std::function<void()>>({
+ [&]() -> void {
+ std::string dump;
+ mapper.dump(dump);
+ },
+ [&]() -> void { mapper.getSources(); },
+ [&]() -> void {
+ RawEvent rawEvent{fdp->ConsumeIntegral<nsecs_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>(),
+ fdp->ConsumeIntegral<int32_t>()};
+ mapper.process(&rawEvent);
+ },
+ [&]() -> void {
+ mapper.getSwitchState(fdp->ConsumeIntegral<uint32_t>(),
+ fdp->ConsumeIntegral<int32_t>());
+ },
+ })();
+ }
+
+ return 0;
+}
+
+} // namespace android
diff --git a/services/surfaceflinger/Android.bp b/services/surfaceflinger/Android.bp
index 2734ee9..12102e8 100644
--- a/services/surfaceflinger/Android.bp
+++ b/services/surfaceflinger/Android.bp
@@ -32,7 +32,7 @@
"android.hardware.graphics.composer@2.4",
"android.hardware.power@1.0",
"android.hardware.power@1.3",
- "android.hardware.power-cpp",
+ "android.hardware.power-V1-cpp",
"libbase",
"libbinder",
"libbufferhubqueue",
diff --git a/services/surfaceflinger/OWNERS b/services/surfaceflinger/OWNERS
index f273725..43a6e55 100644
--- a/services/surfaceflinger/OWNERS
+++ b/services/surfaceflinger/OWNERS
@@ -1,8 +1,6 @@
adyabr@google.com
-akrulec@google.com
alecmouri@google.com
chaviw@google.com
lpy@google.com
racarr@google.com
-stoza@google.com
vishnun@google.com
diff --git a/services/surfaceflinger/tests/Android.bp b/services/surfaceflinger/tests/Android.bp
index 1532855..faaf1e2 100644
--- a/services/surfaceflinger/tests/Android.bp
+++ b/services/surfaceflinger/tests/Android.bp
@@ -44,7 +44,7 @@
"libtrace_proto",
],
shared_libs: [
- "android.hardware.graphics.common-unstable-ndk_platform",
+ "android.hardware.graphics.common-V2-ndk_platform",
"android.hardware.graphics.common@1.2",
"android.hardware.graphics.composer@2.1",
"libandroid",