diff options
23 files changed, 374 insertions, 93 deletions
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp index b22cc2a508..be96306f55 100644 --- a/cmds/dumpstate/Android.bp +++ b/cmds/dumpstate/Android.bp @@ -128,6 +128,7 @@ cc_binary { "main.cpp", ], required: [ + "alloctop", "atrace", "bugreport_procdump", "dmabuf_dump", diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp index 5e83e3337f..bb0ffe650b 100644 --- a/cmds/dumpstate/dumpstate.cpp +++ b/cmds/dumpstate/dumpstate.cpp @@ -1257,6 +1257,15 @@ static void DumpIpAddrAndRules() { RunCommand("IP RULES v6", {"ip", "-6", "rule", "show"}); } +static void DumpKernelMemoryAllocations() { + if (!access("/proc/allocinfo", F_OK)) { + // Print the top 100 biggest memory allocations of at least one byte. + // The output is sorted by size, descending. + RunCommand("KERNEL MEMORY ALLOCATIONS", + {"alloctop", "--once", "--sort", "s", "--min", "1", "--lines", "100"}); + } +} + static Dumpstate::RunStatus RunDumpsysTextByPriority(const std::string& title, int priority, std::chrono::milliseconds timeout, std::chrono::milliseconds service_timeout) { @@ -1766,6 +1775,8 @@ Dumpstate::RunStatus Dumpstate::dumpstate() { DoKmsg(); + DumpKernelMemoryAllocations(); + DumpShutdownCheckpoints(); DumpIpAddrAndRules(); diff --git a/libs/binder/BackendUnifiedServiceManager.cpp b/libs/binder/BackendUnifiedServiceManager.cpp index 34d5a09948..ee3d6af742 100644 --- a/libs/binder/BackendUnifiedServiceManager.cpp +++ b/libs/binder/BackendUnifiedServiceManager.cpp @@ -15,6 +15,7 @@ */ #include "BackendUnifiedServiceManager.h" +#include <android-base/strings.h> #include <android/os/IAccessor.h> #include <android/os/IServiceManager.h> #include <binder/RpcSession.h> @@ -47,6 +48,9 @@ using AidlServiceManager = android::os::IServiceManager; using android::os::IAccessor; using binder::Status; +static const char* kUnsupportedOpNoServiceManager = + "Unsupported operation without a kernel binder servicemanager process"; + static const char* kStaticCachableList[] = { // go/keep-sorted start "accessibility", @@ -220,7 +224,10 @@ Status BackendUnifiedServiceManager::getService2(const ::std::string& name, os:: return Status::ok(); } os::Service service; - Status status = mTheRealServiceManager->getService2(name, &service); + Status status = Status::ok(); + if (mTheRealServiceManager) { + status = mTheRealServiceManager->getService2(name, &service); + } if (status.isOk()) { status = toBinderService(name, service, _out); @@ -237,7 +244,10 @@ Status BackendUnifiedServiceManager::checkService(const ::std::string& name, os: return Status::ok(); } - Status status = mTheRealServiceManager->checkService(name, &service); + Status status = Status::ok(); + if (mTheRealServiceManager) { + status = mTheRealServiceManager->checkService(name, &service); + } if (status.isOk()) { status = toBinderService(name, service, _out); if (status.isOk()) { @@ -315,66 +325,156 @@ Status BackendUnifiedServiceManager::toBinderService(const ::std::string& name, Status BackendUnifiedServiceManager::addService(const ::std::string& name, const sp<IBinder>& service, bool allowIsolated, int32_t dumpPriority) { - Status status = mTheRealServiceManager->addService(name, service, allowIsolated, dumpPriority); - // mEnableAddServiceCache is true by default. - if (kUseCacheInAddService && mEnableAddServiceCache && status.isOk()) { - return updateCache(name, service, - dumpPriority & android::os::IServiceManager::FLAG_IS_LAZY_SERVICE); + if (mTheRealServiceManager) { + Status status = + mTheRealServiceManager->addService(name, service, allowIsolated, dumpPriority); + // mEnableAddServiceCache is true by default. + if (kUseCacheInAddService && mEnableAddServiceCache && status.isOk()) { + return updateCache(name, service, + dumpPriority & android::os::IServiceManager::FLAG_IS_LAZY_SERVICE); + } + return status; } - return status; + return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION, + kUnsupportedOpNoServiceManager); } Status BackendUnifiedServiceManager::listServices(int32_t dumpPriority, ::std::vector<::std::string>* _aidl_return) { - return mTheRealServiceManager->listServices(dumpPriority, _aidl_return); + Status status = Status::ok(); + if (mTheRealServiceManager) { + status = mTheRealServiceManager->listServices(dumpPriority, _aidl_return); + } + if (!status.isOk()) return status; + + appendInjectedAccessorServices(_aidl_return); + + return status; } Status BackendUnifiedServiceManager::registerForNotifications( const ::std::string& name, const sp<os::IServiceCallback>& callback) { - return mTheRealServiceManager->registerForNotifications(name, callback); + if (mTheRealServiceManager) { + return mTheRealServiceManager->registerForNotifications(name, callback); + } + return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION, + kUnsupportedOpNoServiceManager); } Status BackendUnifiedServiceManager::unregisterForNotifications( const ::std::string& name, const sp<os::IServiceCallback>& callback) { - return mTheRealServiceManager->unregisterForNotifications(name, callback); + if (mTheRealServiceManager) { + return mTheRealServiceManager->unregisterForNotifications(name, callback); + } + return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION, + kUnsupportedOpNoServiceManager); } Status BackendUnifiedServiceManager::isDeclared(const ::std::string& name, bool* _aidl_return) { - return mTheRealServiceManager->isDeclared(name, _aidl_return); + Status status = Status::ok(); + if (mTheRealServiceManager) { + status = mTheRealServiceManager->isDeclared(name, _aidl_return); + } + if (!status.isOk()) return status; + + if (!*_aidl_return) { + forEachInjectedAccessorService([&](const std::string& instance) { + if (name == instance) { + *_aidl_return = true; + } + }); + } + + return status; } Status BackendUnifiedServiceManager::getDeclaredInstances( const ::std::string& iface, ::std::vector<::std::string>* _aidl_return) { - return mTheRealServiceManager->getDeclaredInstances(iface, _aidl_return); + Status status = Status::ok(); + if (mTheRealServiceManager) { + status = mTheRealServiceManager->getDeclaredInstances(iface, _aidl_return); + } + if (!status.isOk()) return status; + + forEachInjectedAccessorService([&](const std::string& instance) { + // Declared instances have the format + // <interface>/instance like foo.bar.ISomething/instance + // If it does not have that format, consider the instance to be "" + std::string_view name(instance); + if (base::ConsumePrefix(&name, iface + "/")) { + _aidl_return->emplace_back(name); + } else if (iface == instance) { + _aidl_return->push_back(""); + } + }); + + return status; } Status BackendUnifiedServiceManager::updatableViaApex( const ::std::string& name, ::std::optional<::std::string>* _aidl_return) { - return mTheRealServiceManager->updatableViaApex(name, _aidl_return); + if (mTheRealServiceManager) { + return mTheRealServiceManager->updatableViaApex(name, _aidl_return); + } + return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION, + kUnsupportedOpNoServiceManager); } Status BackendUnifiedServiceManager::getUpdatableNames(const ::std::string& apexName, ::std::vector<::std::string>* _aidl_return) { - return mTheRealServiceManager->getUpdatableNames(apexName, _aidl_return); + if (mTheRealServiceManager) { + return mTheRealServiceManager->getUpdatableNames(apexName, _aidl_return); + } + return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION, + kUnsupportedOpNoServiceManager); } Status BackendUnifiedServiceManager::getConnectionInfo( const ::std::string& name, ::std::optional<os::ConnectionInfo>* _aidl_return) { - return mTheRealServiceManager->getConnectionInfo(name, _aidl_return); + if (mTheRealServiceManager) { + return mTheRealServiceManager->getConnectionInfo(name, _aidl_return); + } + return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION, + kUnsupportedOpNoServiceManager); } Status BackendUnifiedServiceManager::registerClientCallback( const ::std::string& name, const sp<IBinder>& service, const sp<os::IClientCallback>& callback) { - return mTheRealServiceManager->registerClientCallback(name, service, callback); + if (mTheRealServiceManager) { + return mTheRealServiceManager->registerClientCallback(name, service, callback); + } + return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION, + kUnsupportedOpNoServiceManager); } Status BackendUnifiedServiceManager::tryUnregisterService(const ::std::string& name, const sp<IBinder>& service) { - return mTheRealServiceManager->tryUnregisterService(name, service); + if (mTheRealServiceManager) { + return mTheRealServiceManager->tryUnregisterService(name, service); + } + return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION, + kUnsupportedOpNoServiceManager); } Status BackendUnifiedServiceManager::getServiceDebugInfo( ::std::vector<os::ServiceDebugInfo>* _aidl_return) { - return mTheRealServiceManager->getServiceDebugInfo(_aidl_return); + if (mTheRealServiceManager) { + return mTheRealServiceManager->getServiceDebugInfo(_aidl_return); + } + return Status::fromExceptionCode(Status::EX_UNSUPPORTED_OPERATION, + kUnsupportedOpNoServiceManager); } [[clang::no_destroy]] static std::once_flag gUSmOnce; [[clang::no_destroy]] static sp<BackendUnifiedServiceManager> gUnifiedServiceManager; +static bool hasOutOfProcessServiceManager() { +#ifndef BINDER_WITH_KERNEL_IPC + return false; +#else +#if defined(__BIONIC__) && !defined(__ANDROID_VNDK__) + return android::base::GetBoolProperty("servicemanager.installed", true); +#else + return true; +#endif +#endif // BINDER_WITH_KERNEL_IPC +} + sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() { std::call_once(gUSmOnce, []() { #if defined(__BIONIC__) && !defined(__ANDROID_VNDK__) - /* wait for service manager */ { + /* wait for service manager */ + if (hasOutOfProcessServiceManager()) { using std::literals::chrono_literals::operator""s; using android::base::WaitForProperty; while (!WaitForProperty("servicemanager.ready", "true", 1s)) { @@ -384,7 +484,7 @@ sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager() { #endif sp<AidlServiceManager> sm = nullptr; - while (sm == nullptr) { + while (hasOutOfProcessServiceManager() && sm == nullptr) { sm = interface_cast<AidlServiceManager>( ProcessState::self()->getContextObject(nullptr)); if (sm == nullptr) { diff --git a/libs/binder/BackendUnifiedServiceManager.h b/libs/binder/BackendUnifiedServiceManager.h index 6a0d06a079..2496f62503 100644 --- a/libs/binder/BackendUnifiedServiceManager.h +++ b/libs/binder/BackendUnifiedServiceManager.h @@ -167,5 +167,9 @@ private: sp<BackendUnifiedServiceManager> getBackendUnifiedServiceManager(); android::binder::Status getInjectedAccessor(const std::string& name, android::os::Service* service); +void appendInjectedAccessorServices(std::vector<std::string>* list); +// Do not call any other service manager APIs that might take the accessor +// mutex because this will be holding it! +void forEachInjectedAccessorService(const std::function<void(const std::string&)>& f); } // namespace android diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp index 53435c357b..5c72ed3197 100644 --- a/libs/binder/IServiceManager.cpp +++ b/libs/binder/IServiceManager.cpp @@ -304,6 +304,25 @@ android::binder::Status getInjectedAccessor(const std::string& name, return android::binder::Status::ok(); } +void appendInjectedAccessorServices(std::vector<std::string>* list) { + LOG_ALWAYS_FATAL_IF(list == nullptr, + "Attempted to get list of services from Accessors with nullptr"); + std::lock_guard<std::mutex> lock(gAccessorProvidersMutex); + for (const auto& entry : gAccessorProviders) { + list->insert(list->end(), entry.mProvider->instances().begin(), + entry.mProvider->instances().end()); + } +} + +void forEachInjectedAccessorService(const std::function<void(const std::string&)>& f) { + std::lock_guard<std::mutex> lock(gAccessorProvidersMutex); + for (const auto& entry : gAccessorProviders) { + for (const auto& instance : entry.mProvider->instances()) { + f(instance); + } + } +} + sp<IServiceManager> defaultServiceManager() { std::call_once(gSmOnce, []() { diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp index a7bad4ef78..a97d111b97 100644 --- a/libs/binder/Parcel.cpp +++ b/libs/binder/Parcel.cpp @@ -1314,10 +1314,6 @@ status_t Parcel::writeUniqueFileDescriptorVector(const std::vector<unique_fd>& v status_t Parcel::writeUniqueFileDescriptorVector(const std::optional<std::vector<unique_fd>>& val) { return writeData(val); } -status_t Parcel::writeUniqueFileDescriptorVector( - const std::unique_ptr<std::vector<unique_fd>>& val) { - return writeData(val); -} status_t Parcel::writeStrongBinderVector(const std::vector<sp<IBinder>>& val) { return writeData(val); } status_t Parcel::writeStrongBinderVector(const std::optional<std::vector<sp<IBinder>>>& val) { return writeData(val); } @@ -1373,10 +1369,6 @@ status_t Parcel::readUtf8VectorFromUtf16Vector(std::vector<std::string>* val) co status_t Parcel::readUniqueFileDescriptorVector(std::optional<std::vector<unique_fd>>* val) const { return readData(val); } -status_t Parcel::readUniqueFileDescriptorVector( - std::unique_ptr<std::vector<unique_fd>>* val) const { - return readData(val); -} status_t Parcel::readUniqueFileDescriptorVector(std::vector<unique_fd>* val) const { return readData(val); } diff --git a/libs/binder/include/binder/IInterface.h b/libs/binder/include/binder/IInterface.h index cdee17c2ee..bb45ad2ad5 100644 --- a/libs/binder/include/binder/IInterface.h +++ b/libs/binder/include/binder/IInterface.h @@ -243,7 +243,6 @@ constexpr const char* const kManualInterfaces[] = { "android.media.IMediaHTTPService", "android.media.IMediaLogService", "android.media.IMediaMetadataRetriever", - "android.media.IMediaMetricsService", "android.media.IMediaPlayer", "android.media.IMediaPlayerClient", "android.media.IMediaPlayerService", diff --git a/libs/binder/include/binder/IServiceManager.h b/libs/binder/include/binder/IServiceManager.h index 7d79baa34d..d248f22e89 100644 --- a/libs/binder/include/binder/IServiceManager.h +++ b/libs/binder/include/binder/IServiceManager.h @@ -80,6 +80,14 @@ public: /** * Register a service. + * + * Note: + * This status_t return value may be an exception code from an underlying + * Status type that doesn't have a representive error code in + * utils/Errors.h. + * One example of this is a return value of -7 + * (Status::Exception::EX_UNSUPPORTED_OPERATION) when the service manager + * process is not installed on the device when addService is called. */ // NOLINTNEXTLINE(google-default-arguments) virtual status_t addService(const String16& name, const sp<IBinder>& service, diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h index 92c2d99402..9cd2ae9c25 100644 --- a/libs/binder/include/binder/Parcel.h +++ b/libs/binder/include/binder/Parcel.h @@ -383,11 +383,13 @@ public: LIBBINDER_EXPORTED status_t writeUniqueFileDescriptorVector(const std::optional<std::vector<binder::unique_fd>>& val); LIBBINDER_EXPORTED status_t - writeUniqueFileDescriptorVector(const std::unique_ptr<std::vector<binder::unique_fd>>& val) - __attribute__((deprecated("use std::optional version instead"))); - LIBBINDER_EXPORTED status_t writeUniqueFileDescriptorVector(const std::vector<binder::unique_fd>& val); + // WARNING: deprecated and incompatible with AIDL. You should use Parcelable + // definitions outside of Parcel to represent shared memory, such as + // IMemory or with ParcelFileDescriptor. We should remove this, or move it to be + // external to Parcel, it's not a very encapsulated API. + // // Writes a blob to the parcel. // If the blob is small, then it is stored in-place, otherwise it is // transferred by way of an anonymous shared memory region. Prefer sending @@ -401,8 +403,6 @@ public: // as long as it keeps a dup of the blob file descriptor handy for later. LIBBINDER_EXPORTED status_t writeDupImmutableBlobFileDescriptor(int fd); - LIBBINDER_EXPORTED status_t writeObject(const flat_binder_object& val, bool nullMetaData); - // Like Parcel.java's writeNoException(). Just writes a zero int32. // Currently the native implementation doesn't do any of the StrictMode // stack gathering and serialization that the Java implementation does. @@ -626,11 +626,13 @@ public: LIBBINDER_EXPORTED status_t readUniqueFileDescriptorVector(std::optional<std::vector<binder::unique_fd>>* val) const; LIBBINDER_EXPORTED status_t - readUniqueFileDescriptorVector(std::unique_ptr<std::vector<binder::unique_fd>>* val) const - __attribute__((deprecated("use std::optional version instead"))); - LIBBINDER_EXPORTED status_t readUniqueFileDescriptorVector(std::vector<binder::unique_fd>* val) const; + // WARNING: deprecated and incompatible with AIDL. You should use Parcelable + // definitions outside of Parcel to represent shared memory, such as + // IMemory or with ParcelFileDescriptor. We should remove this, or move it to be + // external to Parcel, it's not a very encapsulated API. + // // Reads a blob from the parcel. // The caller should call release() on the blob after reading its contents. LIBBINDER_EXPORTED status_t readBlob(size_t len, ReadableBlob* outBlob) const; @@ -679,6 +681,7 @@ private: // Set the capacity to `desired`, truncating the Parcel if necessary. status_t continueWrite(size_t desired); status_t truncateRpcObjects(size_t newObjectsSize); + status_t writeObject(const flat_binder_object& val, bool nullMetaData); status_t writePointer(uintptr_t val); status_t readPointer(uintptr_t *pArg) const; uintptr_t readPointer() const; diff --git a/libs/binder/include/binder/SafeInterface.h b/libs/binder/include/binder/SafeInterface.h index 0b4f196b8f..bcbd14f9d4 100644 --- a/libs/binder/include/binder/SafeInterface.h +++ b/libs/binder/include/binder/SafeInterface.h @@ -34,6 +34,13 @@ namespace android { namespace SafeInterface { +/** + * WARNING: Prefer to use AIDL-generated interfaces. Using SafeInterface to generate interfaces + * does not support tracing, and many other AIDL features out of the box. The general direction + * we should go is to migrate safe interface users to AIDL and then remove this so that there + * is only one thing to learn/use/test/integrate, not this as well. + */ + // ParcelHandler is responsible for writing/reading various types to/from a Parcel in a generic way class LIBBINDER_EXPORTED ParcelHandler { public: diff --git a/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp b/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp index 66be94f5b5..fb92e05de5 100644 --- a/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp +++ b/libs/binder/ndk/tests/binderVendorDoubleLoadTest.cpp @@ -30,6 +30,8 @@ #include <gtest/gtest.h> #include <sys/prctl.h> +static_assert(FLAG_PRIVATE_LOCAL != 0, "Build system configuration breaks stability"); + using namespace android; using ::android::binder::Status; using ::android::internal::Stability; diff --git a/libs/binder/rust/src/system_only.rs b/libs/binder/rust/src/system_only.rs index 1a58d6b44d..50aa336641 100644 --- a/libs/binder/rust/src/system_only.rs +++ b/libs/binder/rust/src/system_only.rs @@ -23,22 +23,17 @@ use std::ffi::{c_void, CStr, CString}; use std::os::raw::c_char; use libc::{sockaddr, sockaddr_un, sockaddr_vm, socklen_t}; -use std::sync::Arc; -use std::{fmt, mem, ptr}; +use std::boxed::Box; +use std::{mem, ptr}; /// Rust wrapper around ABinderRpc_Accessor objects for RPC binder service management. /// /// Dropping the `Accessor` will drop the underlying object and the binder it owns. +#[derive(Debug)] pub struct Accessor { accessor: *mut sys::ABinderRpc_Accessor, } -impl fmt::Debug for Accessor { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "ABinderRpc_Accessor({:p})", self.accessor) - } -} - /// Socket connection info required for libbinder to connect to a service. #[derive(Debug, Clone, Copy, PartialEq, Eq)] pub enum ConnectionInfo { @@ -70,7 +65,7 @@ impl Accessor { where F: Fn(&str) -> Option<ConnectionInfo> + Send + Sync + 'static, { - let callback: *mut c_void = Arc::into_raw(Arc::new(callback)) as *mut c_void; + let callback: *mut c_void = Box::into_raw(Box::new(callback)) as *mut c_void; let inst = CString::new(instance).unwrap(); // Safety: The function pointer is a valid connection_info callback. @@ -154,7 +149,7 @@ impl Accessor { /// the string within isize::MAX from the pointer. The memory must not be mutated for /// the duration of this function call and must be valid for reads from the pointer /// to the null terminator. - /// - The `cookie` parameter must be the cookie for an `Arc<F>` and + /// - The `cookie` parameter must be the cookie for a `Box<F>` and /// the caller must hold a ref-count to it. unsafe extern "C" fn connection_info<F>( instance: *const c_char, @@ -167,7 +162,7 @@ impl Accessor { log::error!("Cookie({cookie:p}) or instance({instance:p}) is null!"); return ptr::null_mut(); } - // Safety: The caller promises that `cookie` is for an Arc<F>. + // Safety: The caller promises that `cookie` is for a Box<F>. let callback = unsafe { (cookie as *const F).as_ref().unwrap() }; // Safety: The caller in libbinder_ndk will have already verified this is a valid @@ -212,19 +207,19 @@ impl Accessor { } } - /// Callback that decrements the ref-count. + /// Callback that drops the `Box<F>`. /// This is invoked from C++ when a binder is unlinked. /// /// # Safety /// - /// - The `cookie` parameter must be the cookie for an `Arc<F>` and + /// - The `cookie` parameter must be the cookie for a `Box<F>` and /// the owner must give up a ref-count to it. unsafe extern "C" fn cookie_decr_refcount<F>(cookie: *mut c_void) where F: Fn(&str) -> Option<ConnectionInfo> + Send + Sync + 'static, { - // Safety: The caller promises that `cookie` is for an Arc<F>. - unsafe { Arc::decrement_strong_count(cookie as *const F) }; + // Safety: The caller promises that `cookie` is for a Box<F>. + unsafe { std::mem::drop(Box::from_raw(cookie as *mut F)) }; } } @@ -301,7 +296,7 @@ impl AccessorProvider { where F: Fn(&str) -> Option<Accessor> + Send + Sync + 'static, { - let callback: *mut c_void = Arc::into_raw(Arc::new(provider)) as *mut c_void; + let callback: *mut c_void = Box::into_raw(Box::new(provider)) as *mut c_void; let c_str_instances: Vec<CString> = instances.iter().map(|s| CString::new(s.as_bytes()).unwrap()).collect(); let mut c_instances: Vec<*const c_char> = @@ -351,7 +346,7 @@ impl AccessorProvider { log::error!("Cookie({cookie:p}) or instance({instance:p}) is null!"); return ptr::null_mut(); } - // Safety: The caller promises that `cookie` is for an Arc<F>. + // Safety: The caller promises that `cookie` is for a Box<F>. let callback = unsafe { (cookie as *const F).as_ref().unwrap() }; let inst = { @@ -382,14 +377,14 @@ impl AccessorProvider { /// /// # Safety /// - /// - The `cookie` parameter must be the cookie for an `Arc<F>` and + /// - The `cookie` parameter must be the cookie for a `Box<F>` and /// the owner must give up a ref-count to it. unsafe extern "C" fn accessor_cookie_decr_refcount<F>(cookie: *mut c_void) where F: Fn(&str) -> Option<Accessor> + Send + Sync + 'static, { - // Safety: The caller promises that `cookie` is for an Arc<F>. - unsafe { Arc::decrement_strong_count(cookie as *const F) }; + // Safety: The caller promises that `cookie` is for a Box<F>. + unsafe { std::mem::drop(Box::from_raw(cookie as *mut F)) }; } } diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp index d6cb508d7f..391a57010a 100644 --- a/libs/binder/tests/binderLibTest.cpp +++ b/libs/binder/tests/binderLibTest.cpp @@ -44,6 +44,7 @@ #include <processgroup/processgroup.h> #include <utils/Flattenable.h> #include <utils/SystemClock.h> +#include "binder/IServiceManagerUnitTestHelper.h" #include <linux/sched.h> #include <sys/epoll.h> @@ -558,14 +559,14 @@ TEST_F(BinderLibTest, AddManagerToManager) { EXPECT_EQ(NO_ERROR, sm->addService(String16("binderLibTest-manager"), binder)); } +class LocalRegistrationCallbackImpl : public virtual IServiceManager::LocalRegistrationCallback { + void onServiceRegistration(const String16&, const sp<IBinder>&) override {} + virtual ~LocalRegistrationCallbackImpl() {} +}; + TEST_F(BinderLibTest, RegisterForNotificationsFailure) { auto sm = defaultServiceManager(); - using LocalRegistrationCallback = IServiceManager::LocalRegistrationCallback; - class LocalRegistrationCallbackImpl : public virtual LocalRegistrationCallback { - void onServiceRegistration(const String16&, const sp<IBinder>&) override {} - virtual ~LocalRegistrationCallbackImpl() {} - }; - sp<LocalRegistrationCallback> cb = sp<LocalRegistrationCallbackImpl>::make(); + sp<IServiceManager::LocalRegistrationCallback> cb = sp<LocalRegistrationCallbackImpl>::make(); EXPECT_EQ(BAD_VALUE, sm->registerForNotifications(String16("ValidName"), nullptr)); EXPECT_EQ(UNKNOWN_ERROR, sm->registerForNotifications(String16("InvalidName!$"), cb)); @@ -573,12 +574,7 @@ TEST_F(BinderLibTest, RegisterForNotificationsFailure) { TEST_F(BinderLibTest, UnregisterForNotificationsFailure) { auto sm = defaultServiceManager(); - using LocalRegistrationCallback = IServiceManager::LocalRegistrationCallback; - class LocalRegistrationCallbackImpl : public virtual LocalRegistrationCallback { - void onServiceRegistration(const String16&, const sp<IBinder>&) override {} - virtual ~LocalRegistrationCallbackImpl() {} - }; - sp<LocalRegistrationCallback> cb = sp<LocalRegistrationCallbackImpl>::make(); + sp<IServiceManager::LocalRegistrationCallback> cb = sp<LocalRegistrationCallbackImpl>::make(); EXPECT_EQ(OK, sm->registerForNotifications(String16("ValidName"), cb)); @@ -1667,6 +1663,43 @@ TEST(ServiceNotifications, Unregister) { EXPECT_EQ(sm->unregisterForNotifications(String16("RogerRafa"), cb), OK); } +// Make sure all IServiceManager APIs will function without an AIDL service +// manager registered on the device. +TEST(ServiceManagerNoAidlServer, SanityCheck) { + String16 kServiceName("no_services_exist"); + // This is what clients will see when there is no servicemanager process + // that registers itself as context object 0. + // Can't use setDefaultServiceManager() here because these test cases run in + // the same process and will abort when called twice or before/after + // defaultServiceManager(). + sp<IServiceManager> sm = getServiceManagerShimFromAidlServiceManagerForTests(nullptr); + auto status = sm->addService(kServiceName, sp<BBinder>::make()); + // CppBackendShim returns Status::exceptionCode as the status_t + EXPECT_EQ(status, Status::Exception::EX_UNSUPPORTED_OPERATION) << statusToString(status); + auto service = sm->checkService(String16("no_services_exist")); + EXPECT_TRUE(service == nullptr); + auto list = sm->listServices(android::IServiceManager::DUMP_FLAG_PRIORITY_ALL); + EXPECT_TRUE(list.isEmpty()); + bool declared = sm->isDeclared(kServiceName); + EXPECT_FALSE(declared); + list = sm->getDeclaredInstances(kServiceName); + EXPECT_TRUE(list.isEmpty()); + auto updatable = sm->updatableViaApex(kServiceName); + EXPECT_EQ(updatable, std::nullopt); + list = sm->getUpdatableNames(kServiceName); + EXPECT_TRUE(list.isEmpty()); + auto conInfo = sm->getConnectionInfo(kServiceName); + EXPECT_EQ(conInfo, std::nullopt); + auto cb = sp<LocalRegistrationCallbackImpl>::make(); + status = sm->registerForNotifications(kServiceName, cb); + EXPECT_EQ(status, UNKNOWN_ERROR) << statusToString(status); + status = sm->unregisterForNotifications(kServiceName, cb); + EXPECT_EQ(status, BAD_VALUE) << statusToString(status); + auto dbgInfos = sm->getServiceDebugInfo(); + EXPECT_TRUE(dbgInfos.empty()); + sm->enableAddServiceCache(true); +} + TEST_F(BinderLibTest, ThreadPoolAvailableThreads) { Parcel data, reply; sp<IBinder> server = addServer(); diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp index da5a8e3881..9f656ec96c 100644 --- a/libs/binder/tests/binderRpcTest.cpp +++ b/libs/binder/tests/binderRpcTest.cpp @@ -1328,6 +1328,109 @@ TEST_P(BinderRpcAccessor, InjectNoSockaddrProvided) { EXPECT_EQ(status, OK); } +class BinderRpcAccessorNoConnection : public ::testing::Test {}; + +TEST_F(BinderRpcAccessorNoConnection, listServices) { + const String16 kInstanceName("super.cool.service/better_than_default"); + const String16 kInstanceName2("super.cool.service/better_than_default2"); + + auto receipt = + addAccessorProvider({String8(kInstanceName).c_str(), String8(kInstanceName2).c_str()}, + [&](const String16&) -> sp<IBinder> { return nullptr; }); + EXPECT_FALSE(receipt.expired()); + Vector<String16> list = + defaultServiceManager()->listServices(IServiceManager::DUMP_FLAG_PRIORITY_ALL); + bool name1 = false; + bool name2 = false; + for (auto name : list) { + if (name == kInstanceName) name1 = true; + if (name == kInstanceName2) name2 = true; + } + EXPECT_TRUE(name1); + EXPECT_TRUE(name2); + status_t status = removeAccessorProvider(receipt); + EXPECT_EQ(status, OK); +} + +TEST_F(BinderRpcAccessorNoConnection, isDeclared) { + const String16 kInstanceName("super.cool.service/default"); + const String16 kInstanceName2("still_counts_as_declared"); + + auto receipt = + addAccessorProvider({String8(kInstanceName).c_str(), String8(kInstanceName2).c_str()}, + [&](const String16&) -> sp<IBinder> { return nullptr; }); + EXPECT_FALSE(receipt.expired()); + EXPECT_TRUE(defaultServiceManager()->isDeclared(kInstanceName)); + EXPECT_TRUE(defaultServiceManager()->isDeclared(kInstanceName2)); + EXPECT_FALSE(defaultServiceManager()->isDeclared(String16("doesnt_exist"))); + status_t status = removeAccessorProvider(receipt); + EXPECT_EQ(status, OK); +} + +TEST_F(BinderRpcAccessorNoConnection, getDeclaredInstances) { + const String16 kInstanceName("super.cool.service.IFoo/default"); + const String16 kInstanceName2("super.cool.service.IFoo/extra/default"); + const String16 kInstanceName3("super.cool.service.IFoo"); + + auto receipt = + addAccessorProvider({String8(kInstanceName).c_str(), String8(kInstanceName2).c_str(), + String8(kInstanceName3).c_str()}, + [&](const String16&) -> sp<IBinder> { return nullptr; }); + EXPECT_FALSE(receipt.expired()); + Vector<String16> list = + defaultServiceManager()->getDeclaredInstances(String16("super.cool.service.IFoo")); + // We would prefer ASSERT_EQ here, but we must call removeAccessorProvider + EXPECT_EQ(list.size(), 3u); + if (list.size() == 3) { + bool name1 = false; + bool name2 = false; + bool name3 = false; + for (auto name : list) { + if (name == String16("default")) name1 = true; + if (name == String16("extra/default")) name2 = true; + if (name == String16()) name3 = true; + } + EXPECT_TRUE(name1) << String8(list[0]); + EXPECT_TRUE(name2) << String8(list[1]); + EXPECT_TRUE(name3) << String8(list[2]); + } + + status_t status = removeAccessorProvider(receipt); + EXPECT_EQ(status, OK); +} + +TEST_F(BinderRpcAccessorNoConnection, getDeclaredWrongInstances) { + const String16 kInstanceName("super.cool.service.IFoo"); + + auto receipt = addAccessorProvider({String8(kInstanceName).c_str()}, + [&](const String16&) -> sp<IBinder> { return nullptr; }); + EXPECT_FALSE(receipt.expired()); + Vector<String16> list = defaultServiceManager()->getDeclaredInstances(String16("unknown")); + EXPECT_TRUE(list.empty()); + + status_t status = removeAccessorProvider(receipt); + EXPECT_EQ(status, OK); +} + +TEST_F(BinderRpcAccessorNoConnection, getDeclaredInstancesSlash) { + // This is treated as if there were no '/' and the declared instance is "" + const String16 kInstanceName("super.cool.service.IFoo/"); + + auto receipt = addAccessorProvider({String8(kInstanceName).c_str()}, + [&](const String16&) -> sp<IBinder> { return nullptr; }); + EXPECT_FALSE(receipt.expired()); + Vector<String16> list = + defaultServiceManager()->getDeclaredInstances(String16("super.cool.service.IFoo")); + bool name1 = false; + for (auto name : list) { + if (name == String16("")) name1 = true; + } + EXPECT_TRUE(name1); + + status_t status = removeAccessorProvider(receipt); + EXPECT_EQ(status, OK); +} + constexpr const char* kARpcInstance = "some.instance.name.IFoo/default"; const char* kARpcSupportedServices[] = { kARpcInstance, diff --git a/libs/binder/tests/binderSafeInterfaceTest.cpp b/libs/binder/tests/binderSafeInterfaceTest.cpp index 849dc7c4d5..45b2103637 100644 --- a/libs/binder/tests/binderSafeInterfaceTest.cpp +++ b/libs/binder/tests/binderSafeInterfaceTest.cpp @@ -789,7 +789,7 @@ TEST_F(SafeInterfaceTest, TestCallMeBack) { std::optional<int32_t> waitForCallback() { std::unique_lock<decltype(mMutex)> lock(mMutex); bool success = - mCondition.wait_for(lock, 100ms, [&]() { return static_cast<bool>(mValue); }); + mCondition.wait_for(lock, 1000ms, [&]() { return static_cast<bool>(mValue); }); return success ? mValue : std::nullopt; } @@ -858,7 +858,13 @@ TEST_F(SafeInterfaceTest, TestIncrementTwo) { ASSERT_EQ(b + 1, bPlusOne); } -extern "C" int main(int argc, char **argv) { +} // namespace tests +} // namespace android + +int main(int argc, char** argv) { + using namespace android; + using namespace android::tests; + testing::InitGoogleTest(&argc, argv); if (fork() == 0) { @@ -875,6 +881,3 @@ extern "C" int main(int argc, char **argv) { return RUN_ALL_TESTS(); } - -} // namespace tests -} // namespace android diff --git a/libs/binder/tests/binderUtilsHostTest.cpp b/libs/binder/tests/binderUtilsHostTest.cpp index a62ad96be1..ca70b6644b 100644 --- a/libs/binder/tests/binderUtilsHostTest.cpp +++ b/libs/binder/tests/binderUtilsHostTest.cpp @@ -89,8 +89,8 @@ TEST(UtilsHost, ExecuteLongRunning2) { } // ~CommandResult() called, child process is killed. - // Assert that the second sleep does not finish. - EXPECT_LT(millisSince(start), 6000); + // Assert that the last sleep does not finish. + EXPECT_LT(millisSince(start), 8000); } TEST(UtilsHost, KillWithSigKill) { diff --git a/libs/binder/tests/parcel_fuzzer/binder.cpp b/libs/binder/tests/parcel_fuzzer/binder.cpp index e378b864f7..20b6b44c62 100644 --- a/libs/binder/tests/parcel_fuzzer/binder.cpp +++ b/libs/binder/tests/parcel_fuzzer/binder.cpp @@ -318,8 +318,6 @@ std::vector<ParcelRead<::android::Parcel>> BINDER_PARCEL_READ_FUNCTIONS { PARCEL_READ_NO_STATUS(int, readParcelFileDescriptor), PARCEL_READ_WITH_STATUS(unique_fd, readUniqueFileDescriptor), - PARCEL_READ_WITH_STATUS(std::unique_ptr<std::vector<unique_fd>>, - readUniqueFileDescriptorVector), PARCEL_READ_WITH_STATUS(std::optional<std::vector<unique_fd>>, readUniqueFileDescriptorVector), PARCEL_READ_WITH_STATUS(std::vector<unique_fd>, readUniqueFileDescriptorVector), diff --git a/libs/binderdebug/stats.cpp b/libs/binderdebug/stats.cpp index 9c26afaa97..972fbd5295 100644 --- a/libs/binderdebug/stats.cpp +++ b/libs/binderdebug/stats.cpp @@ -22,9 +22,9 @@ #include <inttypes.h> -namespace android { +int main() { + using namespace android; -extern "C" int main() { // ignore args - we only print csv // we should use a csv library here for escaping, because @@ -58,5 +58,3 @@ extern "C" int main() { } return 0; } - -} // namespace android diff --git a/libs/binderdebug/tests/binderdebug_test.cpp b/libs/binderdebug/tests/binderdebug_test.cpp index ea799c06a2..ad2b581abc 100644 --- a/libs/binderdebug/tests/binderdebug_test.cpp +++ b/libs/binderdebug/tests/binderdebug_test.cpp @@ -60,8 +60,15 @@ TEST(BinderDebugTests, BinderThreads) { EXPECT_GE(pidInfo.threadCount, 1); } -extern "C" { +} // namespace test +} // namespace binderdebug +} // namespace android + int main(int argc, char** argv) { + using namespace android; + using namespace android::binderdebug; + using namespace android::binderdebug::test; + ::testing::InitGoogleTest(&argc, argv); // Create a child/client process to call into the main process so we can ensure @@ -84,7 +91,3 @@ int main(int argc, char** argv) { return RUN_ALL_TESTS(); } -} // extern "C" -} // namespace test -} // namespace binderdebug -} // namespace android diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp index a8d5fe7371..4874dbde9c 100644 --- a/libs/graphicsenv/GraphicsEnv.cpp +++ b/libs/graphicsenv/GraphicsEnv.cpp @@ -596,7 +596,7 @@ bool GraphicsEnv::shouldUseAngle() { // If path is set to nonempty and shouldUseNativeDriver is true, ANGLE will be used regardless. void GraphicsEnv::setAngleInfo(const std::string& path, const bool shouldUseNativeDriver, const std::string& packageName, - const std::vector<std::string> eglFeatures) { + const std::vector<std::string>& eglFeatures) { if (mShouldUseAngle) { // ANGLE is already set up for this application process, even if the application // needs to switch from apk to system or vice versa, the application process must @@ -606,11 +606,11 @@ void GraphicsEnv::setAngleInfo(const std::string& path, const bool shouldUseNati return; } - mAngleEglFeatures = std::move(eglFeatures); + mAngleEglFeatures = eglFeatures; ALOGV("setting ANGLE path to '%s'", path.c_str()); - mAnglePath = std::move(path); + mAnglePath = path; ALOGV("setting app package name to '%s'", packageName.c_str()); - mPackageName = std::move(packageName); + mPackageName = packageName; if (mAnglePath == "system") { mShouldUseSystemAngle = true; } diff --git a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h index b0ab0b9d22..452e48bb75 100644 --- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h +++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h @@ -114,7 +114,7 @@ public: // If shouldUseNativeDriver is true, it means native GLES drivers must be used for the process. // If path is set to nonempty and shouldUseNativeDriver is true, ANGLE will be used regardless. void setAngleInfo(const std::string& path, const bool shouldUseNativeDriver, - const std::string& packageName, const std::vector<std::string> eglFeatures); + const std::string& packageName, const std::vector<std::string>& eglFeatures); // Get the ANGLE driver namespace. android_namespace_t* getAngleNamespace(); // Get the app package name. diff --git a/libs/input/Android.bp b/libs/input/Android.bp index e4e81adf58..35d704a1b4 100644 --- a/libs/input/Android.bp +++ b/libs/input/Android.bp @@ -260,6 +260,7 @@ cc_library { shared_libs: [ "android.companion.virtualdevice.flags-aconfig-cc", + "libaconfig_storage_read_api_cc", "libbase", "libbinder", "libbinder_ndk", diff --git a/libs/input/tests/Android.bp b/libs/input/tests/Android.bp index 81c6175805..e04236b9f5 100644 --- a/libs/input/tests/Android.bp +++ b/libs/input/tests/Android.bp @@ -63,6 +63,7 @@ cc_test { }, }, shared_libs: [ + "libaconfig_storage_read_api_cc", "libbase", "libbinder", "libcutils", |