Merge "libbinder: remove obsolete getBlobAshmemSize" into main
diff --git a/cmds/dumpstate/Android.bp b/cmds/dumpstate/Android.bp
index b22cc2a..be96306 100644
--- a/cmds/dumpstate/Android.bp
+++ b/cmds/dumpstate/Android.bp
@@ -128,6 +128,7 @@
"main.cpp",
],
required: [
+ "alloctop",
"atrace",
"bugreport_procdump",
"dmabuf_dump",
diff --git a/cmds/dumpstate/dumpstate.cpp b/cmds/dumpstate/dumpstate.cpp
index 5e83e33..bb0ffe6 100644
--- a/cmds/dumpstate/dumpstate.cpp
+++ b/cmds/dumpstate/dumpstate.cpp
@@ -1257,6 +1257,15 @@
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 @@
DoKmsg();
+ DumpKernelMemoryAllocations();
+
DumpShutdownCheckpoints();
DumpIpAddrAndRules();
diff --git a/libs/binder/BackendUnifiedServiceManager.cpp b/libs/binder/BackendUnifiedServiceManager.cpp
index 34d5a09..ee3d6af 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 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 @@
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 @@
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::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 @@
#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 6a0d06a..2496f62 100644
--- a/libs/binder/BackendUnifiedServiceManager.h
+++ b/libs/binder/BackendUnifiedServiceManager.h
@@ -167,5 +167,9 @@
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 53435c3..5c72ed3 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -304,6 +304,25 @@
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 a7bad4e..a97d111 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -1314,10 +1314,6 @@
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::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 cdee17c..bb45ad2 100644
--- a/libs/binder/include/binder/IInterface.h
+++ b/libs/binder/include/binder/IInterface.h
@@ -243,7 +243,6 @@
"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 7d79baa..d248f22 100644
--- a/libs/binder/include/binder/IServiceManager.h
+++ b/libs/binder/include/binder/IServiceManager.h
@@ -80,6 +80,14 @@
/**
* 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 92c2d99..9cd2ae9 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -383,11 +383,13 @@
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 @@
// 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 @@
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 @@
// 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 0b4f196..bcbd14f 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 66be94f..fb92e05 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 1a58d6b..50aa336 100644
--- a/libs/binder/rust/src/system_only.rs
+++ b/libs/binder/rust/src/system_only.rs
@@ -23,22 +23,17 @@
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 @@
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 @@
/// 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 @@
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 @@
}
}
- /// 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 @@
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 @@
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 @@
///
/// # 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 d6cb508..391a570 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 @@
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, 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 @@
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 da5a8e3..9f656ec 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -1328,6 +1328,109 @@
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 849dc7c..45b2103 100644
--- a/libs/binder/tests/binderSafeInterfaceTest.cpp
+++ b/libs/binder/tests/binderSafeInterfaceTest.cpp
@@ -789,7 +789,7 @@
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 @@
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 @@
return RUN_ALL_TESTS();
}
-
-} // namespace tests
-} // namespace android
diff --git a/libs/binder/tests/binderUtilsHostTest.cpp b/libs/binder/tests/binderUtilsHostTest.cpp
index a62ad96..ca70b66 100644
--- a/libs/binder/tests/binderUtilsHostTest.cpp
+++ b/libs/binder/tests/binderUtilsHostTest.cpp
@@ -89,8 +89,8 @@
}
// ~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 e378b86..20b6b44 100644
--- a/libs/binder/tests/parcel_fuzzer/binder.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder.cpp
@@ -318,8 +318,6 @@
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 9c26afa..972fbd5 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 @@
}
return 0;
}
-
-} // namespace android
diff --git a/libs/binderdebug/tests/binderdebug_test.cpp b/libs/binderdebug/tests/binderdebug_test.cpp
index ea799c0..ad2b581 100644
--- a/libs/binderdebug/tests/binderdebug_test.cpp
+++ b/libs/binderdebug/tests/binderdebug_test.cpp
@@ -60,8 +60,15 @@
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 @@
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 a8d5fe7..4874dbd 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -596,7 +596,7 @@
// 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 @@
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 b0ab0b9..452e48b 100644
--- a/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
+++ b/libs/graphicsenv/include/graphicsenv/GraphicsEnv.h
@@ -114,7 +114,7 @@
// 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 e4e81ad..35d704a 100644
--- a/libs/input/Android.bp
+++ b/libs/input/Android.bp
@@ -260,6 +260,7 @@
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 81c6175..e04236b 100644
--- a/libs/input/tests/Android.bp
+++ b/libs/input/tests/Android.bp
@@ -63,6 +63,7 @@
},
},
shared_libs: [
+ "libaconfig_storage_read_api_cc",
"libbase",
"libbinder",
"libcutils",