Merge "binder: OWNERS -= arve@"
diff --git a/libs/android_runtime_lazy/Android.bp b/libs/android_runtime_lazy/Android.bp
index b74923c..ac3e5b8 100644
--- a/libs/android_runtime_lazy/Android.bp
+++ b/libs/android_runtime_lazy/Android.bp
@@ -42,12 +42,13 @@
cc_library {
name: "libandroid_runtime_lazy",
vendor_available: true,
+ recovery_available: true,
double_loadable: true,
host_supported: true,
target: {
darwin: {
enabled: false,
- }
+ },
},
cflags: [
diff --git a/libs/binder/Android.bp b/libs/binder/Android.bp
index 56cf76f..dc153c9 100644
--- a/libs/binder/Android.bp
+++ b/libs/binder/Android.bp
@@ -25,6 +25,7 @@
name: "libbinder_headers",
export_include_dirs: ["include"],
vendor_available: true,
+ recovery_available: true,
host_supported: true,
// TODO(b/153609531): remove when no longer needed.
native_bridge_supported: true,
@@ -75,6 +76,7 @@
vndk: {
enabled: true,
},
+ recovery_available: true,
double_loadable: true,
host_supported: true,
// TODO(b/153609531): remove when no longer needed.
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 181f405..631a4b6 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -611,6 +611,8 @@
#if defined(__ANDROID_VNDK__)
constexpr int32_t kHeader = B_PACK_CHARS('V', 'N', 'D', 'R');
+#elif defined(__ANDROID_RECOVERY__)
+constexpr int32_t kHeader = B_PACK_CHARS('R', 'E', 'C', 'O');
#else
constexpr int32_t kHeader = B_PACK_CHARS('S', 'Y', 'S', 'T');
#endif
diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp
index 9c04e58..ee46fcb 100644
--- a/libs/binder/ndk/Android.bp
+++ b/libs/binder/ndk/Android.bp
@@ -54,6 +54,7 @@
defaults: ["libbinder_ndk_host_user"],
host_supported: true,
+ recovery_available: true,
llndk: {
symbol_file: "libbinder_ndk.map.txt",
@@ -155,6 +156,7 @@
name: "libbinder_headers_platform_shared",
export_include_dirs: ["include_cpp"],
vendor_available: true,
+ recovery_available: true,
host_supported: true,
// TODO(b/153609531): remove when no longer needed.
native_bridge_supported: true,
diff --git a/libs/binder/rust/src/parcel/parcelable_holder.rs b/libs/binder/rust/src/parcel/parcelable_holder.rs
index 3e75d1b..bccfd2d 100644
--- a/libs/binder/rust/src/parcel/parcelable_holder.rs
+++ b/libs/binder/rust/src/parcel/parcelable_holder.rs
@@ -16,13 +16,12 @@
use crate::binder::Stability;
use crate::error::{Result, StatusCode};
-use crate::parcel::{Parcel, Parcelable};
+use crate::parcel::{OwnedParcel, Parcel, Parcelable};
use crate::{impl_deserialize_for_parcelable, impl_serialize_for_parcelable};
-use downcast_rs::{impl_downcast, Downcast};
+use downcast_rs::{impl_downcast, DowncastSync};
use std::any::Any;
-use std::cell::RefCell;
-use std::rc::Rc;
+use std::sync::{Arc, Mutex};
/// Metadata that `ParcelableHolder` needs for all parcelables.
///
@@ -40,18 +39,18 @@
}
}
-trait AnyParcelable: Downcast + Parcelable + std::fmt::Debug {}
-impl_downcast!(AnyParcelable);
-impl<T> AnyParcelable for T where T: Downcast + Parcelable + std::fmt::Debug {}
+trait AnyParcelable: DowncastSync + Parcelable + std::fmt::Debug {}
+impl_downcast!(sync AnyParcelable);
+impl<T> AnyParcelable for T where T: DowncastSync + Parcelable + std::fmt::Debug {}
#[derive(Debug, Clone)]
enum ParcelableHolderData {
Empty,
Parcelable {
- parcelable: Rc<dyn AnyParcelable>,
+ parcelable: Arc<dyn AnyParcelable>,
name: String,
},
- Parcel(Parcel),
+ Parcel(OwnedParcel),
}
impl Default for ParcelableHolderData {
@@ -67,15 +66,15 @@
/// `ParcelableHolder` is currently not thread-safe (neither
/// `Send` nor `Sync`), mainly because it internally contains
/// a `Parcel` which in turn is not thread-safe.
-#[derive(Debug, Default, Clone)]
+#[derive(Debug, Default)]
pub struct ParcelableHolder {
- // This is a `RefCell` because of `get_parcelable`
+ // This is a `Mutex` because of `get_parcelable`
// which takes `&self` for consistency with C++.
// We could make `get_parcelable` take a `&mut self`
- // and get rid of the `RefCell` here for a performance
+ // and get rid of the `Mutex` here for a performance
// improvement, but then callers would require a mutable
// `ParcelableHolder` even for that getter method.
- data: RefCell<ParcelableHolderData>,
+ data: Mutex<ParcelableHolderData>,
stability: Stability,
}
@@ -83,7 +82,7 @@
/// Construct a new `ParcelableHolder` with the given stability.
pub fn new(stability: Stability) -> Self {
Self {
- data: RefCell::new(ParcelableHolderData::Empty),
+ data: Mutex::new(ParcelableHolderData::Empty),
stability,
}
}
@@ -93,20 +92,20 @@
/// Note that this method does not reset the stability,
/// only the contents.
pub fn reset(&mut self) {
- *self.data.get_mut() = ParcelableHolderData::Empty;
+ *self.data.get_mut().unwrap() = ParcelableHolderData::Empty;
// We could also clear stability here, but C++ doesn't
}
/// Set the parcelable contained in this `ParcelableHolder`.
- pub fn set_parcelable<T>(&mut self, p: Rc<T>) -> Result<()>
+ pub fn set_parcelable<T>(&mut self, p: Arc<T>) -> Result<()>
where
- T: Any + Parcelable + ParcelableMetadata + std::fmt::Debug,
+ T: Any + Parcelable + ParcelableMetadata + std::fmt::Debug + Send + Sync,
{
if self.stability > p.get_stability() {
return Err(StatusCode::BAD_VALUE);
}
- *self.data.get_mut() = ParcelableHolderData::Parcelable {
+ *self.data.get_mut().unwrap() = ParcelableHolderData::Parcelable {
parcelable: p,
name: T::get_descriptor().into(),
};
@@ -127,12 +126,12 @@
/// * `Ok(None)` if the holder is empty or the descriptor does not match
/// * `Ok(Some(_))` if the object holds a parcelable of type `T`
/// with the correct descriptor
- pub fn get_parcelable<T>(&self) -> Result<Option<Rc<T>>>
+ pub fn get_parcelable<T>(&self) -> Result<Option<Arc<T>>>
where
- T: Any + Parcelable + ParcelableMetadata + Default + std::fmt::Debug,
+ T: Any + Parcelable + ParcelableMetadata + Default + std::fmt::Debug + Send + Sync,
{
let parcelable_desc = T::get_descriptor();
- let mut data = self.data.borrow_mut();
+ let mut data = self.data.lock().unwrap();
match *data {
ParcelableHolderData::Empty => Ok(None),
ParcelableHolderData::Parcelable {
@@ -143,12 +142,13 @@
return Err(StatusCode::BAD_VALUE);
}
- match Rc::clone(parcelable).downcast_rc::<T>() {
+ match Arc::clone(parcelable).downcast_arc::<T>() {
Err(_) => Err(StatusCode::BAD_VALUE),
Ok(x) => Ok(Some(x)),
}
}
- ParcelableHolderData::Parcel(ref parcel) => {
+ ParcelableHolderData::Parcel(ref mut parcel) => {
+ let parcel = parcel.borrowed();
unsafe {
// Safety: 0 should always be a valid position.
parcel.set_data_position(0)?;
@@ -160,10 +160,10 @@
}
let mut parcelable = T::default();
- parcelable.read_from_parcel(parcel)?;
+ parcelable.read_from_parcel(&parcel)?;
- let parcelable = Rc::new(parcelable);
- let result = Rc::clone(&parcelable);
+ let parcelable = Arc::new(parcelable);
+ let result = Arc::clone(&parcelable);
*data = ParcelableHolderData::Parcelable { parcelable, name };
Ok(Some(result))
@@ -184,7 +184,8 @@
fn write_to_parcel(&self, parcel: &mut Parcel) -> Result<()> {
parcel.write(&self.stability)?;
- match *self.data.borrow() {
+ let mut data = self.data.lock().unwrap();
+ match *data {
ParcelableHolderData::Empty => parcel.write(&0i32),
ParcelableHolderData::Parcelable {
ref parcelable,
@@ -212,9 +213,10 @@
Ok(())
}
- ParcelableHolderData::Parcel(ref p) => {
+ ParcelableHolderData::Parcel(ref mut p) => {
+ let p = p.borrowed();
parcel.write(&p.get_data_size())?;
- parcel.append_all_from(p)
+ parcel.append_all_from(&p)
}
}
}
@@ -229,7 +231,7 @@
return Err(StatusCode::BAD_VALUE);
}
if data_size == 0 {
- *self.data.get_mut() = ParcelableHolderData::Empty;
+ *self.data.get_mut().unwrap() = ParcelableHolderData::Empty;
return Ok(());
}
@@ -240,9 +242,11 @@
.checked_add(data_size)
.ok_or(StatusCode::BAD_VALUE)?;
- let mut new_parcel = Parcel::new();
- new_parcel.append_from(parcel, data_start, data_size)?;
- *self.data.get_mut() = ParcelableHolderData::Parcel(new_parcel);
+ let mut new_parcel = OwnedParcel::new();
+ new_parcel
+ .borrowed()
+ .append_from(parcel, data_start, data_size)?;
+ *self.data.get_mut().unwrap() = ParcelableHolderData::Parcel(new_parcel);
unsafe {
// Safety: `append_from` checks if `data_size` overflows
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index 7bbe3d7..55ad3c6 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -1303,11 +1303,20 @@
}
TEST_P(BinderRpc, UseKernelBinderCallingId) {
+ bool okToFork = ProcessState::selfOrNull() == nullptr;
+
auto proc = createRpcTestSocketServerProcess({});
- // we can't allocate IPCThreadState so actually the first time should
- // succeed :(
- EXPECT_OK(proc.rootIface->useKernelBinderCallingId());
+ // If this process has used ProcessState already, then the forked process
+ // cannot use it at all. If this process hasn't used it (depending on the
+ // order tests are run), then the forked process can use it, and we'll only
+ // catch the invalid usage the second time. Such is the burden of global
+ // state!
+ if (okToFork) {
+ // we can't allocate IPCThreadState so actually the first time should
+ // succeed :(
+ EXPECT_OK(proc.rootIface->useKernelBinderCallingId());
+ }
// second time! we catch the error :)
EXPECT_EQ(DEAD_OBJECT, proc.rootIface->useKernelBinderCallingId().transactionError());
@@ -1999,5 +2008,6 @@
int main(int argc, char** argv) {
::testing::InitGoogleTest(&argc, argv);
android::base::InitLogging(argv, android::base::StderrLogger, android::base::DefaultAborter);
+
return RUN_ALL_TESTS();
}