diff options
| -rw-r--r-- | libs/android_runtime_lazy/Android.bp | 3 | ||||
| -rw-r--r-- | libs/binder/Android.bp | 2 | ||||
| -rw-r--r-- | libs/binder/OWNERS | 1 | ||||
| -rw-r--r-- | libs/binder/Parcel.cpp | 2 | ||||
| -rw-r--r-- | libs/binder/aidl/android/content/pm/StagedApexInfo.aidl | 3 | ||||
| -rw-r--r-- | libs/binder/ndk/Android.bp | 2 | ||||
| -rw-r--r-- | libs/binder/rust/src/parcel/parcelable_holder.rs | 70 | ||||
| -rw-r--r-- | libs/binder/tests/binderRpcTest.cpp | 16 |
8 files changed, 61 insertions, 38 deletions
diff --git a/libs/android_runtime_lazy/Android.bp b/libs/android_runtime_lazy/Android.bp index b74923cbfc..ac3e5b80fd 100644 --- a/libs/android_runtime_lazy/Android.bp +++ b/libs/android_runtime_lazy/Android.bp @@ -42,12 +42,13 @@ package { 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 56cf76f458..dc153c925f 100644 --- a/libs/binder/Android.bp +++ b/libs/binder/Android.bp @@ -25,6 +25,7 @@ cc_library_headers { 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 @@ cc_library { 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/OWNERS b/libs/binder/OWNERS index 1c8bdea27d..f954e74eba 100644 --- a/libs/binder/OWNERS +++ b/libs/binder/OWNERS @@ -1,5 +1,4 @@ # Bug component: 32456 -arve@google.com ctate@google.com hackbod@google.com maco@google.com diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index 181f4051b7..631a4b625f 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -611,6 +611,8 @@ void Parcel::updateWorkSourceRequestHeaderPosition() const { #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/aidl/android/content/pm/StagedApexInfo.aidl b/libs/binder/aidl/android/content/pm/StagedApexInfo.aidl index ece79895f7..bffab5e86b 100644 --- a/libs/binder/aidl/android/content/pm/StagedApexInfo.aidl +++ b/libs/binder/aidl/android/content/pm/StagedApexInfo.aidl @@ -27,4 +27,7 @@ parcelable StagedApexInfo { @utf8InCpp String diskImagePath; long versionCode; @utf8InCpp String versionName; + boolean hasBootClassPathJars; + boolean hasDex2OatBootClassPathJars; + boolean hasSystemServerClassPathJars; } diff --git a/libs/binder/ndk/Android.bp b/libs/binder/ndk/Android.bp index 9c04e581a2..ee46fcb884 100644 --- a/libs/binder/ndk/Android.bp +++ b/libs/binder/ndk/Android.bp @@ -54,6 +54,7 @@ cc_library { defaults: ["libbinder_ndk_host_user"], host_supported: true, + recovery_available: true, llndk: { symbol_file: "libbinder_ndk.map.txt", @@ -155,6 +156,7 @@ cc_library_headers { 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 3e75d1b11d..bccfd2d25e 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 @@ pub trait ParcelableMetadata { } } -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 @@ impl Default for ParcelableHolderData { /// `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 @@ impl ParcelableHolder { /// 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 @@ impl ParcelableHolder { /// 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 @@ impl ParcelableHolder { /// * `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 @@ impl ParcelableHolder { 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 @@ impl ParcelableHolder { } 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 @@ impl Parcelable for ParcelableHolder { 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 @@ impl Parcelable for ParcelableHolder { 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 @@ impl Parcelable for ParcelableHolder { 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 @@ impl Parcelable for ParcelableHolder { .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 7bbe3d7724..55ad3c6975 100644 --- a/libs/binder/tests/binderRpcTest.cpp +++ b/libs/binder/tests/binderRpcTest.cpp @@ -1303,11 +1303,20 @@ TEST_P(BinderRpc, Die) { } 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 @@ INSTANTIATE_TEST_CASE_P( int main(int argc, char** argv) { ::testing::InitGoogleTest(&argc, argv); android::base::InitLogging(argv, android::base::StderrLogger, android::base::DefaultAborter); + return RUN_ALL_TESTS(); } |