Merge "Add PersistableBundle ndk and AIDL type" into main
diff --git a/cmds/installd/otapreopt.cpp b/cmds/installd/otapreopt.cpp
index 822ab7f..8eb7458 100644
--- a/cmds/installd/otapreopt.cpp
+++ b/cmds/installd/otapreopt.cpp
@@ -514,6 +514,8 @@
// Make sure dex2oat is run with background priority.
dexopt_flags |= DEXOPT_BOOTCOMPLETE | DEXOPT_IDLE_BACKGROUND_JOB;
+ parameters_.compilation_reason = "ab-ota";
+
int res = dexopt(parameters_.apk_path,
parameters_.uid,
parameters_.pkgName,
diff --git a/cmds/installd/otapreopt_chroot.cpp b/cmds/installd/otapreopt_chroot.cpp
index c40caf5..c86adef 100644
--- a/cmds/installd/otapreopt_chroot.cpp
+++ b/cmds/installd/otapreopt_chroot.cpp
@@ -353,7 +353,7 @@
// Now go on and read dexopt lines from stdin and pass them on to otapreopt.
int count = 1;
- for (std::array<char, 1000> linebuf;
+ for (std::array<char, 10000> linebuf;
std::cin.clear(), std::cin.getline(&linebuf[0], linebuf.size()); ++count) {
// Subtract one from gcount() since getline() counts the newline.
std::string line(&linebuf[0], std::cin.gcount() - 1);
diff --git a/libs/binder/Binder.cpp b/libs/binder/Binder.cpp
index f22e90a..8243238 100644
--- a/libs/binder/Binder.cpp
+++ b/libs/binder/Binder.cpp
@@ -30,7 +30,6 @@
#include <binder/RecordedTransaction.h>
#include <binder/RpcServer.h>
#include <pthread.h>
-#include <utils/misc.h>
#include <inttypes.h>
#include <stdio.h>
@@ -271,7 +270,7 @@
bool mInheritRt = false;
// for below objects
- Mutex mLock;
+ RpcMutex mLock;
std::set<sp<RpcServerLink>> mRpcServerLinks;
BpBinder::ObjectManager mObjects;
@@ -307,7 +306,7 @@
return PERMISSION_DENIED;
}
Extras* e = getOrCreateExtras();
- AutoMutex lock(e->mLock);
+ RpcMutexUniqueLock lock(e->mLock);
if (mRecordingOn) {
LOG(INFO) << "Could not start Binder recording. Another is already in progress.";
return INVALID_OPERATION;
@@ -337,7 +336,7 @@
return PERMISSION_DENIED;
}
Extras* e = getOrCreateExtras();
- AutoMutex lock(e->mLock);
+ RpcMutexUniqueLock lock(e->mLock);
if (mRecordingOn) {
e->mRecordingFd.reset();
mRecordingOn = false;
@@ -405,7 +404,7 @@
if (kEnableKernelIpc && mRecordingOn && code != START_RECORDING_TRANSACTION) [[unlikely]] {
Extras* e = mExtras.load(std::memory_order_acquire);
- AutoMutex lock(e->mLock);
+ RpcMutexUniqueLock lock(e->mLock);
if (mRecordingOn) {
Parcel emptyReply;
timespec ts;
@@ -452,7 +451,7 @@
Extras* e = getOrCreateExtras();
LOG_ALWAYS_FATAL_IF(!e, "no memory");
- AutoMutex _l(e->mLock);
+ RpcMutexUniqueLock _l(e->mLock);
return e->mObjects.attach(objectID, object, cleanupCookie, func);
}
@@ -461,7 +460,7 @@
Extras* e = mExtras.load(std::memory_order_acquire);
if (!e) return nullptr;
- AutoMutex _l(e->mLock);
+ RpcMutexUniqueLock _l(e->mLock);
return e->mObjects.find(objectID);
}
@@ -469,7 +468,7 @@
Extras* e = mExtras.load(std::memory_order_acquire);
if (!e) return nullptr;
- AutoMutex _l(e->mLock);
+ RpcMutexUniqueLock _l(e->mLock);
return e->mObjects.detach(objectID);
}
@@ -477,7 +476,7 @@
Extras* e = getOrCreateExtras();
LOG_ALWAYS_FATAL_IF(!e, "no memory");
- AutoMutex _l(e->mLock);
+ RpcMutexUniqueLock _l(e->mLock);
doWithLock();
}
@@ -485,7 +484,7 @@
const void* makeArgs) {
Extras* e = getOrCreateExtras();
LOG_ALWAYS_FATAL_IF(!e, "no memory");
- AutoMutex _l(e->mLock);
+ RpcMutexUniqueLock _l(e->mLock);
return e->mObjects.lookupOrCreateWeak(objectID, make, makeArgs);
}
@@ -692,7 +691,7 @@
auto weakThis = wp<BBinder>::fromExisting(this);
Extras* e = getOrCreateExtras();
- AutoMutex _l(e->mLock);
+ RpcMutexUniqueLock _l(e->mLock);
auto rpcServer = RpcServer::make();
LOG_ALWAYS_FATAL_IF(rpcServer == nullptr, "RpcServer::make returns null");
auto link = sp<RpcServerLink>::make(rpcServer, keepAliveBinder, weakThis);
@@ -716,7 +715,7 @@
void BBinder::removeRpcServerLink(const sp<RpcServerLink>& link) {
Extras* e = mExtras.load(std::memory_order_acquire);
if (!e) return;
- AutoMutex _l(e->mLock);
+ RpcMutexUniqueLock _l(e->mLock);
(void)e->mRpcServerLinks.erase(link);
}
diff --git a/libs/binder/BpBinder.cpp b/libs/binder/BpBinder.cpp
index 3bc4f92..49038b1 100644
--- a/libs/binder/BpBinder.cpp
+++ b/libs/binder/BpBinder.cpp
@@ -23,7 +23,6 @@
#include <binder/IResultReceiver.h>
#include <binder/RpcSession.h>
#include <binder/Stability.h>
-#include <utils/Log.h>
#include <stdio.h>
@@ -38,7 +37,7 @@
// ---------------------------------------------------------------------------
-Mutex BpBinder::sTrackingLock;
+RpcMutex BpBinder::sTrackingLock;
std::unordered_map<int32_t, uint32_t> BpBinder::sTrackingMap;
std::unordered_map<int32_t, uint32_t> BpBinder::sLastLimitCallbackMap;
int BpBinder::sNumTrackedUids = 0;
@@ -163,7 +162,7 @@
int32_t trackedUid = -1;
if (sCountByUidEnabled) {
trackedUid = IPCThreadState::self()->getCallingUid();
- AutoMutex _l(sTrackingLock);
+ RpcMutexUniqueLock _l(sTrackingLock);
uint32_t trackedValue = sTrackingMap[trackedUid];
if (trackedValue & LIMIT_REACHED_MASK) [[unlikely]] {
if (sBinderProxyThrottleCreate) {
@@ -276,7 +275,7 @@
}
bool BpBinder::isDescriptorCached() const {
- Mutex::Autolock _l(mLock);
+ RpcMutexUniqueLock _l(mLock);
return mDescriptorCache.c_str() != kDescriptorUninit.c_str();
}
@@ -292,7 +291,7 @@
status_t err = thiz->transact(INTERFACE_TRANSACTION, data, &reply);
if (err == NO_ERROR) {
String16 res(reply.readString16());
- Mutex::Autolock _l(mLock);
+ RpcMutexUniqueLock _l(mLock);
// mDescriptorCache could have been assigned while the lock was
// released.
if (mDescriptorCache.c_str() == kDescriptorUninit.c_str()) mDescriptorCache = res;
@@ -385,7 +384,7 @@
status = IPCThreadState::self()->transact(binderHandle(), code, data, reply, flags);
}
if (data.dataSize() > LOG_TRANSACTIONS_OVER_SIZE) {
- Mutex::Autolock _l(mLock);
+ RpcMutexUniqueLock _l(mLock);
ALOGW("Large outgoing transaction of %zu bytes, interface descriptor %s, code %d",
data.dataSize(), String8(mDescriptorCache).c_str(), code);
}
@@ -431,7 +430,7 @@
"linkToDeath(): recipient must be non-NULL");
{
- AutoMutex _l(mLock);
+ RpcMutexUniqueLock _l(mLock);
if (!mObitsSent) {
if (!mObituaries) {
@@ -467,7 +466,7 @@
return INVALID_OPERATION;
}
- AutoMutex _l(mLock);
+ RpcMutexUniqueLock _l(mLock);
if (mObitsSent) {
return DEAD_OBJECT;
@@ -555,30 +554,30 @@
void* BpBinder::attachObject(const void* objectID, void* object, void* cleanupCookie,
object_cleanup_func func) {
- AutoMutex _l(mLock);
+ RpcMutexUniqueLock _l(mLock);
ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
return mObjects.attach(objectID, object, cleanupCookie, func);
}
void* BpBinder::findObject(const void* objectID) const
{
- AutoMutex _l(mLock);
+ RpcMutexUniqueLock _l(mLock);
return mObjects.find(objectID);
}
void* BpBinder::detachObject(const void* objectID) {
- AutoMutex _l(mLock);
+ RpcMutexUniqueLock _l(mLock);
return mObjects.detach(objectID);
}
void BpBinder::withLock(const std::function<void()>& doWithLock) {
- AutoMutex _l(mLock);
+ RpcMutexUniqueLock _l(mLock);
doWithLock();
}
sp<IBinder> BpBinder::lookupOrCreateWeak(const void* objectID, object_make_func make,
const void* makeArgs) {
- AutoMutex _l(mLock);
+ RpcMutexUniqueLock _l(mLock);
return mObjects.lookupOrCreateWeak(objectID, make, makeArgs);
}
@@ -602,7 +601,7 @@
IPCThreadState* ipc = IPCThreadState::self();
if (mTrackedUid >= 0) {
- AutoMutex _l(sTrackingLock);
+ RpcMutexUniqueLock _l(sTrackingLock);
uint32_t trackedValue = sTrackingMap[mTrackedUid];
if ((trackedValue & COUNTING_VALUE_MASK) == 0) [[unlikely]] {
ALOGE("Unexpected Binder Proxy tracking decrement in %p handle %d\n", this,
@@ -702,7 +701,7 @@
uint32_t BpBinder::getBinderProxyCount(uint32_t uid)
{
- AutoMutex _l(sTrackingLock);
+ RpcMutexUniqueLock _l(sTrackingLock);
auto it = sTrackingMap.find(uid);
if (it != sTrackingMap.end()) {
return it->second & COUNTING_VALUE_MASK;
@@ -717,7 +716,7 @@
void BpBinder::getCountByUid(Vector<uint32_t>& uids, Vector<uint32_t>& counts)
{
- AutoMutex _l(sTrackingLock);
+ RpcMutexUniqueLock _l(sTrackingLock);
uids.setCapacity(sTrackingMap.size());
counts.setCapacity(sTrackingMap.size());
for (const auto& it : sTrackingMap) {
@@ -731,12 +730,12 @@
void BpBinder::setCountByUidEnabled(bool enable) { sCountByUidEnabled.store(enable); }
void BpBinder::setLimitCallback(binder_proxy_limit_callback cb) {
- AutoMutex _l(sTrackingLock);
+ RpcMutexUniqueLock _l(sTrackingLock);
sLimitCallback = cb;
}
void BpBinder::setBinderProxyCountWatermarks(int high, int low) {
- AutoMutex _l(sTrackingLock);
+ RpcMutexUniqueLock _l(sTrackingLock);
sBinderProxyCountHighWatermark = high;
sBinderProxyCountLowWatermark = low;
}
diff --git a/libs/binder/Debug.cpp b/libs/binder/Debug.cpp
index c6e4fb3..7ae616e 100644
--- a/libs/binder/Debug.cpp
+++ b/libs/binder/Debug.cpp
@@ -19,8 +19,6 @@
#include <binder/ProcessState.h>
-#include <utils/misc.h>
-
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
diff --git a/libs/binder/FdTrigger.cpp b/libs/binder/FdTrigger.cpp
index 8ee6cb0..a1fbbf3 100644
--- a/libs/binder/FdTrigger.cpp
+++ b/libs/binder/FdTrigger.cpp
@@ -21,12 +21,15 @@
#include <poll.h>
-#include <android-base/macros.h>
-#include <android-base/scopeguard.h>
+#include <binder/Functional.h>
#include "RpcState.h"
+#include "Utils.h"
+
namespace android {
+using namespace android::binder::impl;
+
std::unique_ptr<FdTrigger> FdTrigger::make() {
auto ret = std::make_unique<FdTrigger>();
#ifndef BINDER_RPC_SINGLE_THREADED
@@ -74,10 +77,9 @@
"Only one thread should be polling on Fd!");
transportFd.setPollingState(true);
- auto pollingStateGuard =
- android::base::make_scope_guard([&]() { transportFd.setPollingState(false); });
+ auto pollingStateGuard = make_scope_guard([&]() { transportFd.setPollingState(false); });
- int ret = TEMP_FAILURE_RETRY(poll(pfd, arraysize(pfd), -1));
+ int ret = TEMP_FAILURE_RETRY(poll(pfd, countof(pfd), -1));
if (ret < 0) {
return -errno;
}
diff --git a/libs/binder/FdTrigger.h b/libs/binder/FdTrigger.h
index 5fbf290..dba1dc9 100644
--- a/libs/binder/FdTrigger.h
+++ b/libs/binder/FdTrigger.h
@@ -17,7 +17,6 @@
#include <memory>
-#include <android-base/result.h>
#include <android-base/unique_fd.h>
#include <utils/Errors.h>
diff --git a/libs/binder/IInterface.cpp b/libs/binder/IInterface.cpp
index 2780bd4..dea2603 100644
--- a/libs/binder/IInterface.cpp
+++ b/libs/binder/IInterface.cpp
@@ -15,7 +15,6 @@
*/
#define LOG_TAG "IInterface"
-#include <utils/Log.h>
#include <binder/IInterface.h>
namespace android {
diff --git a/libs/binder/IPCThreadState.cpp b/libs/binder/IPCThreadState.cpp
index da58251..9341eff 100644
--- a/libs/binder/IPCThreadState.cpp
+++ b/libs/binder/IPCThreadState.cpp
@@ -22,7 +22,6 @@
#include <binder/BpBinder.h>
#include <binder/TextOutput.h>
-#include <android-base/macros.h>
#include <cutils/sched_policy.h>
#include <utils/CallStack.h>
#include <utils/Log.h>
@@ -395,7 +394,9 @@
}
void IPCThreadState::checkContextIsBinderForUse(const char* use) const {
- if (LIKELY(mServingStackPointerGuard == nullptr)) return;
+ if (mServingStackPointerGuard == nullptr) [[likely]] {
+ return;
+ }
if (!mServingStackPointer || mServingStackPointerGuard->address < mServingStackPointer) {
LOG_ALWAYS_FATAL("In context %s, %s does not make sense (binder sp: %p, guard: %p).",
@@ -832,7 +833,7 @@
}
if ((flags & TF_ONE_WAY) == 0) {
- if (UNLIKELY(mCallRestriction != ProcessState::CallRestriction::NONE)) {
+ if (mCallRestriction != ProcessState::CallRestriction::NONE) [[unlikely]] {
if (mCallRestriction == ProcessState::CallRestriction::ERROR_IF_NOT_ONEWAY) {
ALOGE("Process making non-oneway call (code: %u) but is restricted.", code);
CallStack::logStack("non-oneway call", CallStack::getCurrent(10).get(),
@@ -842,13 +843,13 @@
}
}
- #if 0
+#if 0
if (code == 4) { // relayout
ALOGI(">>>>>> CALLING transaction 4");
} else {
ALOGI(">>>>>> CALLING transaction %d", code);
}
- #endif
+#endif
if (reply) {
err = waitForResponse(reply);
} else {
diff --git a/libs/binder/IResultReceiver.cpp b/libs/binder/IResultReceiver.cpp
index cd92217..60ece72 100644
--- a/libs/binder/IResultReceiver.cpp
+++ b/libs/binder/IResultReceiver.cpp
@@ -18,7 +18,6 @@
#include <binder/IResultReceiver.h>
-#include <utils/Log.h>
#include <binder/Parcel.h>
#include <utils/String8.h>
diff --git a/libs/binder/IServiceManager.cpp b/libs/binder/IServiceManager.cpp
index 6034f2b..fe566fc 100644
--- a/libs/binder/IServiceManager.cpp
+++ b/libs/binder/IServiceManager.cpp
@@ -200,7 +200,7 @@
}
bool checkPermission(const String16& permission, pid_t pid, uid_t uid, bool logPermissionFailure) {
- static Mutex gPermissionControllerLock;
+ static std::mutex gPermissionControllerLock;
static sp<IPermissionController> gPermissionController;
sp<IPermissionController> pc;
diff --git a/libs/binder/MemoryDealer.cpp b/libs/binder/MemoryDealer.cpp
index 5b1cb7e..95bdbb4 100644
--- a/libs/binder/MemoryDealer.cpp
+++ b/libs/binder/MemoryDealer.cpp
@@ -155,7 +155,7 @@
void dump_l(String8& res, const char* what) const;
static const int kMemoryAlign;
- mutable Mutex mLock;
+ mutable std::mutex mLock;
LinkedList<chunk_t> mList;
size_t mHeapSize;
};
@@ -305,14 +305,14 @@
size_t SimpleBestFitAllocator::allocate(size_t size, uint32_t flags)
{
- Mutex::Autolock _l(mLock);
+ std::unique_lock<std::mutex> _l(mLock);
ssize_t offset = alloc(size, flags);
return offset;
}
status_t SimpleBestFitAllocator::deallocate(size_t offset)
{
- Mutex::Autolock _l(mLock);
+ std::unique_lock<std::mutex> _l(mLock);
chunk_t const * const freed = dealloc(offset);
if (freed) {
return NO_ERROR;
@@ -420,7 +420,7 @@
void SimpleBestFitAllocator::dump(const char* what) const
{
- Mutex::Autolock _l(mLock);
+ std::unique_lock<std::mutex> _l(mLock);
dump_l(what);
}
@@ -434,7 +434,7 @@
void SimpleBestFitAllocator::dump(String8& result,
const char* what) const
{
- Mutex::Autolock _l(mLock);
+ std::unique_lock<std::mutex> _l(mLock);
dump_l(result, what);
}
diff --git a/libs/binder/OS.h b/libs/binder/OS.h
index 8dc1f6a..bb7caa9 100644
--- a/libs/binder/OS.h
+++ b/libs/binder/OS.h
@@ -18,14 +18,13 @@
#include <stddef.h>
#include <cstdint>
-#include <android-base/result.h>
#include <android-base/unique_fd.h>
#include <binder/RpcTransport.h>
#include <utils/Errors.h>
namespace android::binder::os {
-android::base::Result<void> setNonBlocking(android::base::borrowed_fd fd);
+status_t setNonBlocking(android::base::borrowed_fd fd);
status_t getRandomBytes(uint8_t* data, size_t size);
diff --git a/libs/binder/OS_unix_base.cpp b/libs/binder/OS_unix_base.cpp
index 81933d5..a3cf117 100644
--- a/libs/binder/OS_unix_base.cpp
+++ b/libs/binder/OS_unix_base.cpp
@@ -15,29 +15,29 @@
*/
#include "OS.h"
+#include "Utils.h"
#include <android-base/file.h>
#include <binder/RpcTransportRaw.h>
#include <log/log.h>
#include <string.h>
-using android::base::ErrnoError;
-using android::base::Result;
-
namespace android::binder::os {
// Linux kernel supports up to 253 (from SCM_MAX_FD) for unix sockets.
constexpr size_t kMaxFdsPerMsg = 253;
-Result<void> setNonBlocking(android::base::borrowed_fd fd) {
+status_t setNonBlocking(android::base::borrowed_fd fd) {
int flags = TEMP_FAILURE_RETRY(fcntl(fd.get(), F_GETFL));
if (flags == -1) {
- return ErrnoError() << "Could not get flags for fd";
+ PLOGE("Failed setNonBlocking: Could not get flags for fd");
+ return -errno;
}
if (int ret = TEMP_FAILURE_RETRY(fcntl(fd.get(), F_SETFL, flags | O_NONBLOCK)); ret == -1) {
- return ErrnoError() << "Could not set non-blocking flag for fd";
+ PLOGE("Failed setNonBlocking: Could not set non-blocking flag for fd");
+ return -errno;
}
- return {};
+ return OK;
}
status_t getRandomBytes(uint8_t* data, size_t size) {
diff --git a/libs/binder/Parcel.cpp b/libs/binder/Parcel.cpp
index 17bdc45..94f3631 100644
--- a/libs/binder/Parcel.cpp
+++ b/libs/binder/Parcel.cpp
@@ -17,6 +17,7 @@
#define LOG_TAG "Parcel"
//#define LOG_NDEBUG 0
+#include <endian.h>
#include <errno.h>
#include <fcntl.h>
#include <inttypes.h>
@@ -32,6 +33,7 @@
#include <binder/Binder.h>
#include <binder/BpBinder.h>
+#include <binder/Functional.h>
#include <binder/IPCThreadState.h>
#include <binder/Parcel.h>
#include <binder/ProcessState.h>
@@ -39,15 +41,11 @@
#include <binder/Status.h>
#include <binder/TextOutput.h>
-#include <android-base/scopeguard.h>
#ifndef BINDER_DISABLE_BLOB
#include <cutils/ashmem.h>
#endif
-#include <utils/Flattenable.h>
-#include <utils/Log.h>
#include <utils/String16.h>
#include <utils/String8.h>
-#include <utils/misc.h>
#include "OS.h"
#include "RpcState.h"
@@ -94,6 +92,8 @@
namespace android {
+using namespace android::binder::impl;
+
// many things compile this into prebuilts on the stack
#ifdef __LP64__
static_assert(sizeof(Parcel) == 120);
@@ -586,7 +586,7 @@
}
const size_t savedDataPos = mDataPos;
- base::ScopeGuard scopeGuard = [&]() { mDataPos = savedDataPos; };
+ auto scopeGuard = make_scope_guard([&]() { mDataPos = savedDataPos; });
rpcFields->mObjectPositions.reserve(otherRpcFields->mObjectPositions.size());
if (otherRpcFields->mFds != nullptr) {
diff --git a/libs/binder/ProcessState.cpp b/libs/binder/ProcessState.cpp
index 8ec4af9..0344eb0 100644
--- a/libs/binder/ProcessState.cpp
+++ b/libs/binder/ProcessState.cpp
@@ -18,10 +18,9 @@
#include <binder/ProcessState.h>
-#include <android-base/result.h>
-#include <android-base/scopeguard.h>
#include <android-base/strings.h>
#include <binder/BpBinder.h>
+#include <binder/Functional.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/Stability.h>
@@ -32,6 +31,7 @@
#include <utils/Thread.h>
#include "Static.h"
+#include "Utils.h"
#include "binder_module.h"
#include <errno.h>
@@ -60,6 +60,8 @@
namespace android {
+using namespace android::binder::impl;
+
class PoolThread : public Thread
{
public:
@@ -189,7 +191,7 @@
void ProcessState::startThreadPool()
{
- AutoMutex _l(mLock);
+ std::unique_lock<std::mutex> _l(mLock);
if (!mThreadPoolStarted) {
if (mMaxThreads == 0) {
// see also getThreadPoolMaxTotalThreadCount
@@ -203,7 +205,7 @@
bool ProcessState::becomeContextManager()
{
- AutoMutex _l(mLock);
+ std::unique_lock<std::mutex> _l(mLock);
flat_binder_object obj {
.flags = FLAT_BINDER_FLAG_TXN_SECURITY_CTX,
@@ -310,7 +312,7 @@
{
sp<IBinder> result;
- AutoMutex _l(mLock);
+ std::unique_lock<std::mutex> _l(mLock);
if (handle == 0 && the_context_object != nullptr) return the_context_object;
@@ -374,7 +376,7 @@
void ProcessState::expungeHandle(int32_t handle, IBinder* binder)
{
- AutoMutex _l(mLock);
+ std::unique_lock<std::mutex> _l(mLock);
handle_entry* e = lookupHandleLocked(handle);
@@ -430,7 +432,7 @@
size_t ProcessState::getThreadPoolMaxTotalThreadCount() const {
pthread_mutex_lock(&mThreadCountLock);
- base::ScopeGuard detachGuard = [&]() { pthread_mutex_unlock(&mThreadCountLock); };
+ auto detachGuard = make_scope_guard([&]() { pthread_mutex_unlock(&mThreadCountLock); });
if (mThreadPoolStarted) {
LOG_ALWAYS_FATAL_IF(mKernelStartedThreads > mMaxThreads + 1,
@@ -512,31 +514,31 @@
return mDriverName;
}
-static base::Result<int> open_driver(const char* driver) {
- int fd = open(driver, O_RDWR | O_CLOEXEC);
- if (fd < 0) {
- return base::ErrnoError() << "Opening '" << driver << "' failed";
+static base::unique_fd open_driver(const char* driver) {
+ auto fd = base::unique_fd(open(driver, O_RDWR | O_CLOEXEC));
+ if (!fd.ok()) {
+ PLOGE("Opening '%s' failed", driver);
+ return {};
}
int vers = 0;
- status_t result = ioctl(fd, BINDER_VERSION, &vers);
+ int result = ioctl(fd.get(), BINDER_VERSION, &vers);
if (result == -1) {
- close(fd);
- return base::ErrnoError() << "Binder ioctl to obtain version failed";
+ PLOGE("Binder ioctl to obtain version failed");
+ return {};
}
if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
- close(fd);
- return base::Error() << "Binder driver protocol(" << vers
- << ") does not match user space protocol("
- << BINDER_CURRENT_PROTOCOL_VERSION
- << ")! ioctl() return value: " << result;
+ ALOGE("Binder driver protocol(%d) does not match user space protocol(%d)! "
+ "ioctl() return value: %d",
+ vers, BINDER_CURRENT_PROTOCOL_VERSION, result);
+ return {};
}
size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
- result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
+ result = ioctl(fd.get(), BINDER_SET_MAX_THREADS, &maxThreads);
if (result == -1) {
ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
}
uint32_t enable = DEFAULT_ENABLE_ONEWAY_SPAM_DETECTION;
- result = ioctl(fd, BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable);
+ result = ioctl(fd.get(), BINDER_ENABLE_ONEWAY_SPAM_DETECTION, &enable);
if (result == -1) {
ALOGE_IF(ProcessState::isDriverFeatureEnabled(
ProcessState::DriverFeature::ONEWAY_SPAM_DETECTION),
@@ -561,28 +563,27 @@
mThreadPoolStarted(false),
mThreadPoolSeq(1),
mCallRestriction(CallRestriction::NONE) {
- base::Result<int> opened = open_driver(driver);
+ base::unique_fd opened = open_driver(driver);
if (opened.ok()) {
// mmap the binder, providing a chunk of virtual address space to receive transactions.
mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE,
- opened.value(), 0);
+ opened.get(), 0);
if (mVMStart == MAP_FAILED) {
- close(opened.value());
// *sigh*
- opened = base::Error()
- << "Using " << driver << " failed: unable to mmap transaction memory.";
+ ALOGE("Using %s failed: unable to mmap transaction memory.", driver);
+ opened.reset();
mDriverName.clear();
}
}
#ifdef __ANDROID__
- LOG_ALWAYS_FATAL_IF(!opened.ok(), "Binder driver '%s' could not be opened. Terminating: %s",
- driver, opened.error().message().c_str());
+ LOG_ALWAYS_FATAL_IF(!opened.ok(), "Binder driver '%s' could not be opened. Terminating.",
+ driver);
#endif
if (opened.ok()) {
- mDriverFD = opened.value();
+ mDriverFD = opened.release();
}
}
diff --git a/libs/binder/RecordedTransaction.cpp b/libs/binder/RecordedTransaction.cpp
index 3246706..cedd3af 100644
--- a/libs/binder/RecordedTransaction.cpp
+++ b/libs/binder/RecordedTransaction.cpp
@@ -16,12 +16,13 @@
#include <android-base/file.h>
#include <android-base/logging.h>
-#include <android-base/scopeguard.h>
#include <android-base/unique_fd.h>
+#include <binder/Functional.h>
#include <binder/RecordedTransaction.h>
#include <sys/mman.h>
#include <algorithm>
+using namespace android::binder::impl;
using android::Parcel;
using android::base::borrowed_fd;
using android::base::unique_fd;
@@ -218,7 +219,7 @@
size_t memoryMappedSize = chunkPayloadSize + mmapPayloadStartOffset;
void* mappedMemory =
mmap(NULL, memoryMappedSize, PROT_READ, MAP_SHARED, fd.get(), mmapPageAlignedStart);
- auto mmap_guard = android::base::make_scope_guard(
+ auto mmap_guard = make_scope_guard(
[mappedMemory, memoryMappedSize] { munmap(mappedMemory, memoryMappedSize); });
transaction_checksum_t* payloadMap =
diff --git a/libs/binder/RpcServer.cpp b/libs/binder/RpcServer.cpp
index 07ab093..1ba20b3 100644
--- a/libs/binder/RpcServer.cpp
+++ b/libs/binder/RpcServer.cpp
@@ -25,12 +25,11 @@
#include <thread>
#include <vector>
-#include <android-base/scopeguard.h>
+#include <binder/Functional.h>
#include <binder/Parcel.h>
#include <binder/RpcServer.h>
#include <binder/RpcTransportRaw.h>
#include <log/log.h>
-#include <utils/Compat.h>
#include "BuildFlags.h"
#include "FdTrigger.h"
@@ -45,7 +44,7 @@
constexpr size_t kSessionIdBytes = 32;
-using base::ScopeGuard;
+using namespace android::binder::impl;
using base::unique_fd;
RpcServer::RpcServer(std::unique_ptr<RpcTransportCtx> ctx) : mCtx(std::move(ctx)) {}
@@ -231,10 +230,7 @@
}
unique_fd fd(std::move(std::get<unique_fd>(fds.back())));
- if (auto res = binder::os::setNonBlocking(fd); !res.ok()) {
- ALOGE("Failed setNonBlocking: %s", res.error().message().c_str());
- return res.error().code() == 0 ? UNKNOWN_ERROR : -res.error().code();
- }
+ if (status_t res = binder::os::setNonBlocking(fd); res != OK) return res;
*out = RpcTransportFd(std::move(fd));
return OK;
@@ -458,11 +454,12 @@
LOG_ALWAYS_FATAL_IF(threadId == server->mConnectingThreads.end(),
"Must establish connection on owned thread");
thisThread = std::move(threadId->second);
- ScopeGuard detachGuard = [&]() {
+ auto detachGuardLambda = [&]() {
thisThread.detach();
_l.unlock();
server->mShutdownCv.notify_all();
};
+ auto detachGuard = make_scope_guard(std::ref(detachGuardLambda));
server->mConnectingThreads.erase(threadId);
if (status != OK || server->mShutdownTrigger->isTriggered()) {
@@ -548,7 +545,7 @@
return;
}
- detachGuard.Disable();
+ detachGuard.release();
session->preJoinThreadOwnership(std::move(thisThread));
}
diff --git a/libs/binder/RpcSession.cpp b/libs/binder/RpcSession.cpp
index fa8f2b5..c895b21 100644
--- a/libs/binder/RpcSession.cpp
+++ b/libs/binder/RpcSession.cpp
@@ -26,14 +26,12 @@
#include <string_view>
-#include <android-base/macros.h>
-#include <android-base/scopeguard.h>
#include <binder/BpBinder.h>
+#include <binder/Functional.h>
#include <binder/Parcel.h>
#include <binder/RpcServer.h>
#include <binder/RpcTransportRaw.h>
#include <binder/Stability.h>
-#include <utils/Compat.h>
#include <utils/String8.h>
#include "BuildFlags.h"
@@ -52,6 +50,7 @@
namespace android {
+using namespace android::binder::impl;
using base::unique_fd;
RpcSession::RpcSession(std::unique_ptr<RpcTransportCtx> ctx) : mCtx(std::move(ctx)) {
@@ -194,10 +193,7 @@
fd = request();
if (!fd.ok()) return BAD_VALUE;
}
- if (auto res = binder::os::setNonBlocking(fd); !res.ok()) {
- ALOGE("setupPreconnectedClient: %s", res.error().message().c_str());
- return res.error().code() == 0 ? UNKNOWN_ERROR : -res.error().code();
- }
+ if (status_t res = binder::os::setNonBlocking(fd); res != OK) return res;
RpcTransportFd transportFd(std::move(fd));
status_t status = initAndAddConnection(std::move(transportFd), sessionId, incoming);
@@ -412,7 +408,9 @@
}
private:
- DISALLOW_COPY_AND_ASSIGN(JavaThreadAttacher);
+ JavaThreadAttacher(const JavaThreadAttacher&) = delete;
+ void operator=(const JavaThreadAttacher&) = delete;
+
bool mAttached = false;
static JavaVM* getJavaVM() {
@@ -497,7 +495,7 @@
if (auto status = initShutdownTrigger(); status != OK) return status;
auto oldProtocolVersion = mProtocolVersion;
- auto cleanup = base::ScopeGuard([&] {
+ auto cleanup = make_scope_guard([&] {
// if any threads are started, shut them down
(void)shutdownAndWait(true);
@@ -577,7 +575,7 @@
if (status_t status = connectAndInit(mId, true /*incoming*/); status != OK) return status;
}
- cleanup.Disable();
+ cleanup.release();
return OK;
}
diff --git a/libs/binder/RpcState.cpp b/libs/binder/RpcState.cpp
index 26a2f4f..008e5d2 100644
--- a/libs/binder/RpcState.cpp
+++ b/libs/binder/RpcState.cpp
@@ -18,9 +18,8 @@
#include "RpcState.h"
-#include <android-base/macros.h>
-#include <android-base/scopeguard.h>
#include <binder/BpBinder.h>
+#include <binder/Functional.h>
#include <binder/IPCThreadState.h>
#include <binder/RpcServer.h>
@@ -39,6 +38,8 @@
namespace android {
+using namespace android::binder::impl;
+
#if RPC_FLAKE_PRONE
void rpcMaybeWaitToFlake() {
[[clang::no_destroy]] static std::random_device r;
@@ -357,7 +358,7 @@
status_t RpcState::rpcSend(
const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session,
const char* what, iovec* iovs, int niovs,
- const std::optional<android::base::function_ref<status_t()>>& altPoll,
+ const std::optional<SmallFunction<status_t()>>& altPoll,
const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds) {
for (int i = 0; i < niovs; i++) {
LOG_RPC_DETAIL("Sending %s (part %d of %d) on RpcTransport %p: %s",
@@ -412,10 +413,8 @@
return false;
}
#else
- // TODO(b/305983144)
- // don't restrict on other platforms, though experimental should
- // only really be used for testing, we don't have a good way to see
- // what is shipping outside of Android
+ ALOGE("Cannot use experimental RPC binder protocol outside of Android.");
+ return false;
#endif
} else if (version >= RPC_WIRE_PROTOCOL_VERSION_NEXT) {
ALOGE("Cannot use RPC binder protocol version %u which is unknown (current protocol "
@@ -602,25 +601,24 @@
{const_cast<uint8_t*>(data.data()), data.dataSize()},
objectTableSpan.toIovec(),
};
- if (status_t status = rpcSend(
- connection, session, "transaction", iovs, arraysize(iovs),
- [&] {
- if (waitUs > kWaitLogUs) {
- ALOGE("Cannot send command, trying to process pending refcounts. Waiting "
- "%zuus. Too many oneway calls?",
- waitUs);
- }
+ auto altPoll = [&] {
+ if (waitUs > kWaitLogUs) {
+ ALOGE("Cannot send command, trying to process pending refcounts. Waiting "
+ "%zuus. Too many oneway calls?",
+ waitUs);
+ }
- if (waitUs > 0) {
- usleep(waitUs);
- waitUs = std::min(kWaitMaxUs, waitUs * 2);
- } else {
- waitUs = 1;
- }
+ if (waitUs > 0) {
+ usleep(waitUs);
+ waitUs = std::min(kWaitMaxUs, waitUs * 2);
+ } else {
+ waitUs = 1;
+ }
- return drainCommands(connection, session, CommandType::CONTROL_ONLY);
- },
- rpcFields->mFds.get());
+ return drainCommands(connection, session, CommandType::CONTROL_ONLY);
+ };
+ if (status_t status = rpcSend(connection, session, "transaction", iovs, countof(iovs),
+ std::ref(altPoll), rpcFields->mFds.get());
status != OK) {
// rpcSend calls shutdownAndWait, so all refcounts should be reset. If we ever tolerate
// errors here, then we may need to undo the binder-sent counts for the transaction as
@@ -692,7 +690,7 @@
{&rpcReply, rpcReplyWireSize},
{data.data(), data.size()},
};
- if (status_t status = rpcRec(connection, session, "reply body", iovs, arraysize(iovs), nullptr);
+ if (status_t status = rpcRec(connection, session, "reply body", iovs, countof(iovs), nullptr);
status != OK)
return status;
@@ -762,7 +760,7 @@
.bodySize = sizeof(RpcDecStrong),
};
iovec iovs[]{{&cmd, sizeof(cmd)}, {&body, sizeof(body)}};
- return rpcSend(connection, session, "dec ref", iovs, arraysize(iovs), std::nullopt);
+ return rpcSend(connection, session, "dec ref", iovs, countof(iovs), std::nullopt);
}
status_t RpcState::getAndExecuteCommand(const sp<RpcSession::RpcConnection>& connection,
@@ -811,11 +809,11 @@
origGuard = kernelBinderState->pushGetCallingSpGuard(&spGuard);
}
- base::ScopeGuard guardUnguard = [&]() {
+ auto guardUnguard = make_scope_guard([&]() {
if (kernelBinderState != nullptr) {
kernelBinderState->restoreGetCallingSpGuard(origGuard);
}
- };
+ });
#endif // BINDER_WITH_KERNEL_IPC
switch (command.command) {
@@ -1145,7 +1143,7 @@
{const_cast<uint8_t*>(reply.data()), reply.dataSize()},
objectTableSpan.toIovec(),
};
- return rpcSend(connection, session, "reply", iovs, arraysize(iovs), std::nullopt,
+ return rpcSend(connection, session, "reply", iovs, countof(iovs), std::nullopt,
rpcFields->mFds.get());
}
diff --git a/libs/binder/RpcState.h b/libs/binder/RpcState.h
index 1fe71a5..2a954e6 100644
--- a/libs/binder/RpcState.h
+++ b/libs/binder/RpcState.h
@@ -16,6 +16,7 @@
#pragma once
#include <android-base/unique_fd.h>
+#include <binder/Functional.h>
#include <binder/IBinder.h>
#include <binder/Parcel.h>
#include <binder/RpcSession.h>
@@ -190,7 +191,7 @@
[[nodiscard]] status_t rpcSend(
const sp<RpcSession::RpcConnection>& connection, const sp<RpcSession>& session,
const char* what, iovec* iovs, int niovs,
- const std::optional<android::base::function_ref<status_t()>>& altPoll,
+ const std::optional<binder::impl::SmallFunction<status_t()>>& altPoll,
const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds =
nullptr);
[[nodiscard]] status_t rpcRec(
diff --git a/libs/binder/RpcTransportRaw.cpp b/libs/binder/RpcTransportRaw.cpp
index c089811..ffa3151 100644
--- a/libs/binder/RpcTransportRaw.cpp
+++ b/libs/binder/RpcTransportRaw.cpp
@@ -29,6 +29,8 @@
namespace android {
+using namespace android::binder::impl;
+
// RpcTransport with TLS disabled.
class RpcTransportRaw : public RpcTransport {
public:
@@ -54,7 +56,7 @@
status_t interruptableWriteFully(
FdTrigger* fdTrigger, iovec* iovs, int niovs,
- const std::optional<android::base::function_ref<status_t()>>& altPoll,
+ const std::optional<SmallFunction<status_t()>>& altPoll,
const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds)
override {
bool sentFds = false;
@@ -70,7 +72,7 @@
status_t interruptableReadFully(
FdTrigger* fdTrigger, iovec* iovs, int niovs,
- const std::optional<android::base::function_ref<status_t()>>& altPoll,
+ const std::optional<SmallFunction<status_t()>>& altPoll,
std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds) override {
auto recv = [&](iovec* iovs, int niovs) -> ssize_t {
return binder::os::receiveMessageFromSocket(mSocket, iovs, niovs, ancillaryFds);
diff --git a/libs/binder/RpcTransportTipcAndroid.cpp b/libs/binder/RpcTransportTipcAndroid.cpp
index 0c81d83..188ba3b 100644
--- a/libs/binder/RpcTransportTipcAndroid.cpp
+++ b/libs/binder/RpcTransportTipcAndroid.cpp
@@ -26,8 +26,7 @@
#include "RpcState.h"
#include "RpcTransportUtils.h"
-using android::base::Error;
-using android::base::Result;
+using namespace android::binder::impl;
namespace android {
@@ -75,7 +74,7 @@
status_t interruptableWriteFully(
FdTrigger* fdTrigger, iovec* iovs, int niovs,
- const std::optional<android::base::function_ref<status_t()>>& altPoll,
+ const std::optional<SmallFunction<status_t()>>& altPoll,
const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds)
override {
auto writeFn = [&](iovec* iovs, size_t niovs) -> ssize_t {
@@ -93,7 +92,7 @@
status_t interruptableReadFully(
FdTrigger* fdTrigger, iovec* iovs, int niovs,
- const std::optional<android::base::function_ref<status_t()>>& altPoll,
+ const std::optional<SmallFunction<status_t()>>& altPoll,
std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* /*ancillaryFds*/)
override {
auto readFn = [&](iovec* iovs, size_t niovs) -> ssize_t {
diff --git a/libs/binder/RpcTransportTls.cpp b/libs/binder/RpcTransportTls.cpp
index efb09e9..fef4be4 100644
--- a/libs/binder/RpcTransportTls.cpp
+++ b/libs/binder/RpcTransportTls.cpp
@@ -29,6 +29,8 @@
#include "RpcState.h"
#include "Utils.h"
+#include <sstream>
+
#define SHOULD_LOG_TLS_DETAIL false
#if SHOULD_LOG_TLS_DETAIL
@@ -38,6 +40,9 @@
#endif
namespace android {
+
+using namespace android::binder::impl;
+
namespace {
// Implement BIO for socket that ignores SIGPIPE.
@@ -181,10 +186,9 @@
// |sslError| should be from Ssl::getError().
// If |sslError| is WANT_READ / WANT_WRITE, poll for POLLIN / POLLOUT respectively. Otherwise
// return error. Also return error if |fdTrigger| is triggered before or during poll().
- status_t pollForSslError(
- const android::RpcTransportFd& fd, int sslError, FdTrigger* fdTrigger,
- const char* fnString, int additionalEvent,
- const std::optional<android::base::function_ref<status_t()>>& altPoll) {
+ status_t pollForSslError(const android::RpcTransportFd& fd, int sslError, FdTrigger* fdTrigger,
+ const char* fnString, int additionalEvent,
+ const std::optional<SmallFunction<status_t()>>& altPoll) {
switch (sslError) {
case SSL_ERROR_WANT_READ:
return handlePoll(POLLIN | additionalEvent, fd, fdTrigger, fnString, altPoll);
@@ -200,7 +204,7 @@
status_t handlePoll(int event, const android::RpcTransportFd& fd, FdTrigger* fdTrigger,
const char* fnString,
- const std::optional<android::base::function_ref<status_t()>>& altPoll) {
+ const std::optional<SmallFunction<status_t()>>& altPoll) {
status_t ret;
if (altPoll) {
ret = (*altPoll)();
@@ -284,12 +288,12 @@
status_t pollRead(void) override;
status_t interruptableWriteFully(
FdTrigger* fdTrigger, iovec* iovs, int niovs,
- const std::optional<android::base::function_ref<status_t()>>& altPoll,
+ const std::optional<SmallFunction<status_t()>>& altPoll,
const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds)
override;
status_t interruptableReadFully(
FdTrigger* fdTrigger, iovec* iovs, int niovs,
- const std::optional<android::base::function_ref<status_t()>>& altPoll,
+ const std::optional<SmallFunction<status_t()>>& altPoll,
std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds) override;
bool isWaiting() override { return mSocket.isInPollingState(); };
@@ -320,7 +324,7 @@
status_t RpcTransportTls::interruptableWriteFully(
FdTrigger* fdTrigger, iovec* iovs, int niovs,
- const std::optional<android::base::function_ref<status_t()>>& altPoll,
+ const std::optional<SmallFunction<status_t()>>& altPoll,
const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds) {
(void)ancillaryFds;
@@ -366,7 +370,7 @@
status_t RpcTransportTls::interruptableReadFully(
FdTrigger* fdTrigger, iovec* iovs, int niovs,
- const std::optional<android::base::function_ref<status_t()>>& altPoll,
+ const std::optional<SmallFunction<status_t()>>& altPoll,
std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds) {
(void)ancillaryFds;
diff --git a/libs/binder/RpcTransportUtils.h b/libs/binder/RpcTransportUtils.h
index 32f0db8..a0e502e 100644
--- a/libs/binder/RpcTransportUtils.h
+++ b/libs/binder/RpcTransportUtils.h
@@ -27,7 +27,7 @@
status_t interruptableReadOrWrite(
const android::RpcTransportFd& socket, FdTrigger* fdTrigger, iovec* iovs, int niovs,
SendOrReceive sendOrReceiveFun, const char* funName, int16_t event,
- const std::optional<android::base::function_ref<status_t()>>& altPoll) {
+ const std::optional<binder::impl::SmallFunction<status_t()>>& altPoll) {
MAYBE_WAIT_IN_FLAKE_MODE;
if (niovs < 0) {
diff --git a/libs/binder/ServiceManagerHost.cpp b/libs/binder/ServiceManagerHost.cpp
index 2b67f03..9482e3e 100644
--- a/libs/binder/ServiceManagerHost.cpp
+++ b/libs/binder/ServiceManagerHost.cpp
@@ -56,16 +56,16 @@
[[nodiscard]] const std::optional<unsigned int>& hostPort() const { return mPort; }
private:
- DISALLOW_COPY_AND_ASSIGN(AdbForwarder);
+ AdbForwarder(const AdbForwarder&) = delete;
+ void operator=(const AdbForwarder&) = delete;
explicit AdbForwarder(unsigned int port) : mPort(port) {}
std::optional<unsigned int> mPort;
};
std::optional<AdbForwarder> AdbForwarder::forward(unsigned int devicePort) {
auto result =
execute({"adb", "forward", "tcp:0", "tcp:" + std::to_string(devicePort)}, nullptr);
- if (!result.ok()) {
- ALOGE("Unable to run `adb forward tcp:0 tcp:%d`: %s", devicePort,
- result.error().message().c_str());
+ if (!result.has_value()) {
+ ALOGE("Unable to run `adb forward tcp:0 tcp:%d`", devicePort);
return std::nullopt;
}
// Must end with exit code 0 (`has_value() && value() == 0`)
@@ -94,9 +94,8 @@
if (!mPort.has_value()) return;
auto result = execute({"adb", "forward", "--remove", "tcp:" + std::to_string(*mPort)}, nullptr);
- if (!result.ok()) {
- ALOGE("Unable to run `adb forward --remove tcp:%d`: %s", *mPort,
- result.error().message().c_str());
+ if (!result.has_value()) {
+ ALOGE("Unable to run `adb forward --remove tcp:%d`", *mPort);
return;
}
// Must end with exit code 0 (`has_value() && value() == 0`)
@@ -130,8 +129,7 @@
serviceDispatcherArgs.insert(serviceDispatcherArgs.begin(), prefix.begin(), prefix.end());
auto result = execute(std::move(serviceDispatcherArgs), &CommandResult::stdoutEndsWithNewLine);
- if (!result.ok()) {
- ALOGE("%s", result.error().message().c_str());
+ if (!result.has_value()) {
return nullptr;
}
diff --git a/libs/binder/ServiceManagerHost.h b/libs/binder/ServiceManagerHost.h
index c5310da..941ba3a 100644
--- a/libs/binder/ServiceManagerHost.h
+++ b/libs/binder/ServiceManagerHost.h
@@ -16,7 +16,6 @@
#pragma once
-#include <android-base/macros.h>
#include <android/os/IServiceManager.h>
namespace android {
diff --git a/libs/binder/Utils.h b/libs/binder/Utils.h
index dd632c0..c8431aa 100644
--- a/libs/binder/Utils.h
+++ b/libs/binder/Utils.h
@@ -22,6 +22,22 @@
#include <log/log.h>
#include <utils/Errors.h>
+#define PLOGE_VA_ARGS(...) , ##__VA_ARGS__
+#define PLOGE(fmt, ...) ALOGE(fmt ": %s" PLOGE_VA_ARGS(__VA_ARGS__), strerror(errno))
+
+/* TEMP_FAILURE_RETRY is not available on macOS and Trusty. */
+#ifndef TEMP_FAILURE_RETRY
+/* Used to retry syscalls that can return EINTR. */
+#define TEMP_FAILURE_RETRY(exp) \
+ ({ \
+ __typeof__(exp) _rc; \
+ do { \
+ _rc = (exp); \
+ } while (_rc == -1 && errno == EINTR); \
+ _rc; \
+ })
+#endif
+
#define TEST_AND_RETURN(value, expr) \
do { \
if (!(expr)) { \
@@ -32,6 +48,17 @@
namespace android {
+/**
+ * Get the size of a statically initialized array.
+ *
+ * \param N the array to get the size of.
+ * \return the size of the array.
+ */
+template <typename T, size_t N>
+constexpr size_t countof(T (&)[N]) {
+ return N;
+}
+
// avoid optimizations
void zeroMemory(uint8_t* data, size_t size);
diff --git a/libs/binder/UtilsHost.cpp b/libs/binder/UtilsHost.cpp
index 52b8f69..3db038f 100644
--- a/libs/binder/UtilsHost.cpp
+++ b/libs/binder/UtilsHost.cpp
@@ -25,6 +25,8 @@
#include <log/log.h>
+#include "Utils.h"
+
namespace android {
CommandResult::~CommandResult() {
@@ -72,8 +74,8 @@
return ss.str();
}
-android::base::Result<CommandResult> execute(std::vector<std::string> argStringVec,
- const std::function<bool(const CommandResult&)>& end) {
+std::optional<CommandResult> execute(std::vector<std::string> argStringVec,
+ const std::function<bool(const CommandResult&)>& end) {
// turn vector<string> into null-terminated char* vector.
std::vector<char*> argv;
argv.reserve(argStringVec.size() + 1);
@@ -82,14 +84,21 @@
CommandResult ret;
android::base::unique_fd outWrite;
- if (!android::base::Pipe(&ret.outPipe, &outWrite))
- return android::base::ErrnoError() << "pipe() for outPipe";
+ if (!android::base::Pipe(&ret.outPipe, &outWrite)) {
+ PLOGE("pipe() for outPipe");
+ return {};
+ }
android::base::unique_fd errWrite;
- if (!android::base::Pipe(&ret.errPipe, &errWrite))
- return android::base::ErrnoError() << "pipe() for errPipe";
+ if (!android::base::Pipe(&ret.errPipe, &errWrite)) {
+ PLOGE("pipe() for errPipe");
+ return {};
+ }
int pid = fork();
- if (pid == -1) return android::base::ErrnoError() << "fork()";
+ if (pid == -1) {
+ PLOGE("fork()");
+ return {};
+ }
if (pid == 0) {
// child
ret.outPipe.reset();
@@ -140,12 +149,19 @@
*errPollFd = {.fd = ret.errPipe.get(), .events = POLLIN};
}
int pollRet = poll(fds, nfds, 1000 /* ms timeout */);
- if (pollRet == -1) return android::base::ErrnoError() << "poll()";
+ if (pollRet == -1) {
+ PLOGE("poll()");
+ return {};
+ }
- if (!handlePoll(&ret.outPipe, outPollFd, &ret.stdoutStr))
- return android::base::ErrnoError() << "read(stdout)";
- if (!handlePoll(&ret.errPipe, errPollFd, &ret.stderrStr))
- return android::base::ErrnoError() << "read(stderr)";
+ if (!handlePoll(&ret.outPipe, outPollFd, &ret.stdoutStr)) {
+ PLOGE("read(stdout)");
+ return {};
+ }
+ if (!handlePoll(&ret.errPipe, errPollFd, &ret.stderrStr)) {
+ PLOGE("read(stderr)");
+ return {};
+ }
if (end && end(ret)) return ret;
}
@@ -154,7 +170,10 @@
while (ret.pid.has_value()) {
int status;
auto exitPid = waitpid(pid, &status, 0);
- if (exitPid == -1) return android::base::ErrnoError() << "waitpid(" << pid << ")";
+ if (exitPid == -1) {
+ PLOGE("waitpid(%d)", pid);
+ return {};
+ }
if (exitPid == pid) {
if (WIFEXITED(status)) {
ret.pid = std::nullopt;
diff --git a/libs/binder/UtilsHost.h b/libs/binder/UtilsHost.h
index 98ac4e0..5de0980 100644
--- a/libs/binder/UtilsHost.h
+++ b/libs/binder/UtilsHost.h
@@ -23,8 +23,8 @@
#include <vector>
#include <android-base/macros.h>
-#include <android-base/result.h>
#include <android-base/unique_fd.h>
+#include <utils/Errors.h>
/**
* Log a lot more information about host-device binder communication, when debugging issues.
@@ -67,7 +67,8 @@
}
private:
- DISALLOW_COPY_AND_ASSIGN(CommandResult);
+ CommandResult(const CommandResult&) = delete;
+ void operator=(const CommandResult&) = delete;
};
std::ostream& operator<<(std::ostream& os, const CommandResult& res);
@@ -94,6 +95,6 @@
//
// If the parent process has encountered any errors for system calls, return ExecuteError with
// the proper errno set.
-android::base::Result<CommandResult> execute(std::vector<std::string> argStringVec,
- const std::function<bool(const CommandResult&)>& end);
+std::optional<CommandResult> execute(std::vector<std::string> argStringVec,
+ const std::function<bool(const CommandResult&)>& end);
} // namespace android
diff --git a/libs/binder/include/binder/BpBinder.h b/libs/binder/include/binder/BpBinder.h
index 28fb9f1..d78ea0d 100644
--- a/libs/binder/include/binder/BpBinder.h
+++ b/libs/binder/include/binder/BpBinder.h
@@ -18,7 +18,7 @@
#include <android-base/unique_fd.h>
#include <binder/IBinder.h>
-#include <utils/Mutex.h>
+#include <binder/RpcThreads.h>
#include <map>
#include <optional>
@@ -193,7 +193,7 @@
void reportOneDeath(const Obituary& obit);
bool isDescriptorCached() const;
- mutable Mutex mLock;
+ mutable RpcMutex mLock;
volatile int32_t mAlive;
volatile int32_t mObitsSent;
Vector<Obituary>* mObituaries;
@@ -201,7 +201,7 @@
mutable String16 mDescriptorCache;
int32_t mTrackedUid;
- static Mutex sTrackingLock;
+ static RpcMutex sTrackingLock;
static std::unordered_map<int32_t,uint32_t> sTrackingMap;
static int sNumTrackedUids;
static std::atomic_bool sCountByUidEnabled;
diff --git a/libs/binder/include/binder/Functional.h b/libs/binder/include/binder/Functional.h
new file mode 100644
index 0000000..08e3b21
--- /dev/null
+++ b/libs/binder/include/binder/Functional.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+#include <functional>
+#include <memory>
+
+namespace android::binder::impl {
+
+template <typename F>
+constexpr void assert_small_callable() {
+ // While this buffer (std::function::__func::__buf_) is an implementation detail generally not
+ // accessible to users, it's a good bet to assume its size to be around 3 pointers.
+ constexpr size_t kFunctionBufferSize = 3 * sizeof(void*);
+
+ static_assert(sizeof(F) <= kFunctionBufferSize,
+ "Supplied callable is larger than std::function optimization buffer. "
+ "Try using std::ref, but make sure lambda lives long enough to be called.");
+}
+
+template <typename F>
+std::unique_ptr<void, std::function<void(void*)>> make_scope_guard(F&& f) {
+ assert_small_callable<decltype(std::bind(f))>();
+ return {reinterpret_cast<void*>(true), std::bind(f)};
+}
+
+template <typename T>
+class SmallFunction : public std::function<T> {
+public:
+ template <typename F>
+ SmallFunction(F&& f) : std::function<T>(f) {
+ assert_small_callable<F>();
+ }
+};
+
+} // namespace android::binder::impl
diff --git a/libs/binder/include/binder/Parcel.h b/libs/binder/include/binder/Parcel.h
index 98d12bb..6961abc 100644
--- a/libs/binder/include/binder/Parcel.h
+++ b/libs/binder/include/binder/Parcel.h
@@ -33,7 +33,6 @@
#include <utils/RefBase.h>
#include <utils/String16.h>
#include <utils/Vector.h>
-#include <utils/Flattenable.h>
#include <binder/IInterface.h>
#include <binder/Parcelable.h>
diff --git a/libs/binder/include/binder/ProcessState.h b/libs/binder/include/binder/ProcessState.h
index 9dc370b..3672702 100644
--- a/libs/binder/include/binder/ProcessState.h
+++ b/libs/binder/include/binder/ProcessState.h
@@ -17,13 +17,13 @@
#pragma once
#include <binder/IBinder.h>
-#include <utils/KeyedVector.h>
-#include <utils/Mutex.h>
#include <utils/String16.h>
#include <utils/String8.h>
#include <pthread.h>
+#include <mutex>
+
// ---------------------------------------------------------------------------
namespace android {
@@ -178,7 +178,7 @@
// Time when thread pool was emptied
int64_t mStarvationStartTimeMs;
- mutable Mutex mLock; // protects everything below.
+ mutable std::mutex mLock; // protects everything below.
Vector<handle_entry> mHandleToObject;
diff --git a/libs/binder/include/binder/RpcSession.h b/libs/binder/include/binder/RpcSession.h
index cb64603..e3805ac 100644
--- a/libs/binder/include/binder/RpcSession.h
+++ b/libs/binder/include/binder/RpcSession.h
@@ -15,7 +15,6 @@
*/
#pragma once
-#include <android-base/threads.h>
#include <android-base/unique_fd.h>
#include <binder/IBinder.h>
#include <binder/RpcThreads.h>
diff --git a/libs/binder/include/binder/RpcTransport.h b/libs/binder/include/binder/RpcTransport.h
index 6db9ad9..115a173 100644
--- a/libs/binder/include/binder/RpcTransport.h
+++ b/libs/binder/include/binder/RpcTransport.h
@@ -25,10 +25,10 @@
#include <variant>
#include <vector>
-#include <android-base/function_ref.h>
#include <android-base/unique_fd.h>
#include <utils/Errors.h>
+#include <binder/Functional.h>
#include <binder/RpcCertificateFormat.h>
#include <binder/RpcThreads.h>
@@ -85,13 +85,13 @@
* error - interrupted (failure or trigger)
*/
[[nodiscard]] virtual status_t interruptableWriteFully(
- FdTrigger *fdTrigger, iovec *iovs, int niovs,
- const std::optional<android::base::function_ref<status_t()>> &altPoll,
- const std::vector<std::variant<base::unique_fd, base::borrowed_fd>> *ancillaryFds) = 0;
+ FdTrigger* fdTrigger, iovec* iovs, int niovs,
+ const std::optional<binder::impl::SmallFunction<status_t()>>& altPoll,
+ const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds) = 0;
[[nodiscard]] virtual status_t interruptableReadFully(
- FdTrigger *fdTrigger, iovec *iovs, int niovs,
- const std::optional<android::base::function_ref<status_t()>> &altPoll,
- std::vector<std::variant<base::unique_fd, base::borrowed_fd>> *ancillaryFds) = 0;
+ FdTrigger* fdTrigger, iovec* iovs, int niovs,
+ const std::optional<binder::impl::SmallFunction<status_t()>>& altPoll,
+ std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds) = 0;
/**
* Check whether any threads are blocked while polling the transport
diff --git a/libs/binder/rust/src/binder.rs b/libs/binder/rust/src/binder.rs
index a08cb7a..78f8877 100644
--- a/libs/binder/rust/src/binder.rs
+++ b/libs/binder/rust/src/binder.rs
@@ -21,6 +21,7 @@
use crate::proxy::{DeathRecipient, SpIBinder, WpIBinder};
use crate::sys;
+use downcast_rs::{impl_downcast, DowncastSync};
use std::borrow::Borrow;
use std::cmp::Ordering;
use std::convert::TryFrom;
@@ -51,7 +52,7 @@
/// interfaces) must implement this trait.
///
/// This is equivalent `IInterface` in C++.
-pub trait Interface: Send + Sync {
+pub trait Interface: Send + Sync + DowncastSync {
/// Convert this binder object into a generic [`SpIBinder`] reference.
fn as_binder(&self) -> SpIBinder {
panic!("This object was not a Binder object and cannot be converted into an SpIBinder.")
@@ -66,6 +67,8 @@
}
}
+impl_downcast!(sync Interface);
+
/// Implemented by sync interfaces to specify what the associated async interface is.
/// Generic to handle the fact that async interfaces are generic over a thread pool.
///
@@ -143,7 +146,7 @@
/// When using the AIDL backend, users need only implement the high-level AIDL-defined
/// interface. The AIDL compiler then generates a container struct that wraps
/// the user-defined service and implements `Remotable`.
-pub trait Remotable: Send + Sync {
+pub trait Remotable: Send + Sync + 'static {
/// The Binder interface descriptor string.
///
/// This string is a unique identifier for a Binder interface, and should be
@@ -893,6 +896,23 @@
$crate::binder_impl::IBinderInternal::set_requesting_sid(&mut binder, features.set_requesting_sid);
$crate::Strong::new(Box::new(binder))
}
+
+ /// Tries to downcast the interface to another type.
+ /// When receiving this object from a binder call, make sure that the object received is
+ /// a binder native object and that is of the right type for the Downcast:
+ ///
+ /// let binder = received_object.as_binder();
+ /// if !binder.is_remote() {
+ /// let binder_native: Binder<BnFoo> = binder.try_into()?;
+ /// let original_object = binder_native.downcast_binder::<MyFoo>();
+ /// // Check that returned type is not None before using it
+ /// }
+ ///
+ /// Handle the error cases instead of just calling `unwrap` or `expect` to prevent a
+ /// malicious caller to mount a Denial of Service attack.
+ pub fn downcast_binder<T: $interface>(&self) -> Option<&T> {
+ self.0.as_any().downcast_ref::<T>()
+ }
}
impl $crate::binder_impl::Remotable for $native {
@@ -1004,7 +1024,7 @@
$(
// Async interface trait implementations.
- impl<P: $crate::BinderAsyncPool> $crate::FromIBinder for dyn $async_interface<P> {
+ impl<P: $crate::BinderAsyncPool + 'static> $crate::FromIBinder for dyn $async_interface<P> {
fn try_from(mut ibinder: $crate::SpIBinder) -> std::result::Result<$crate::Strong<dyn $async_interface<P>>, $crate::StatusCode> {
use $crate::binder_impl::AssociateClass;
@@ -1030,27 +1050,27 @@
}
}
- impl<P: $crate::BinderAsyncPool> $crate::binder_impl::Serialize for dyn $async_interface<P> + '_ {
+ impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::Serialize for dyn $async_interface<P> + '_ {
fn serialize(&self, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
let binder = $crate::Interface::as_binder(self);
parcel.write(&binder)
}
}
- impl<P: $crate::BinderAsyncPool> $crate::binder_impl::SerializeOption for dyn $async_interface<P> + '_ {
+ impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::SerializeOption for dyn $async_interface<P> + '_ {
fn serialize_option(this: Option<&Self>, parcel: &mut $crate::binder_impl::BorrowedParcel<'_>) -> std::result::Result<(), $crate::StatusCode> {
parcel.write(&this.map($crate::Interface::as_binder))
}
}
- impl<P: $crate::BinderAsyncPool> std::fmt::Debug for dyn $async_interface<P> + '_ {
+ impl<P: $crate::BinderAsyncPool + 'static> std::fmt::Debug for dyn $async_interface<P> + '_ {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.pad(stringify!($async_interface))
}
}
/// Convert a &dyn $async_interface to Strong<dyn $async_interface>
- impl<P: $crate::BinderAsyncPool> std::borrow::ToOwned for dyn $async_interface<P> {
+ impl<P: $crate::BinderAsyncPool + 'static> std::borrow::ToOwned for dyn $async_interface<P> {
type Owned = $crate::Strong<dyn $async_interface<P>>;
fn to_owned(&self) -> Self::Owned {
self.as_binder().into_interface()
@@ -1058,11 +1078,11 @@
}
}
- impl<P: $crate::BinderAsyncPool> $crate::binder_impl::ToAsyncInterface<P> for dyn $interface {
+ impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::ToAsyncInterface<P> for dyn $interface {
type Target = dyn $async_interface<P>;
}
- impl<P: $crate::BinderAsyncPool> $crate::binder_impl::ToSyncInterface for dyn $async_interface<P> {
+ impl<P: $crate::BinderAsyncPool + 'static> $crate::binder_impl::ToSyncInterface for dyn $async_interface<P> {
type Target = dyn $interface;
}
)?
diff --git a/libs/binder/tests/binderAllocationLimits.cpp b/libs/binder/tests/binderAllocationLimits.cpp
index 6712c9c..7e0b594 100644
--- a/libs/binder/tests/binderAllocationLimits.cpp
+++ b/libs/binder/tests/binderAllocationLimits.cpp
@@ -16,6 +16,7 @@
#include <android-base/logging.h>
#include <binder/Binder.h>
+#include <binder/Functional.h>
#include <binder/IServiceManager.h>
#include <binder/Parcel.h>
#include <binder/RpcServer.h>
@@ -28,6 +29,8 @@
#include <functional>
#include <vector>
+using namespace android::binder::impl;
+
static android::String8 gEmpty(""); // make sure first allocation from optimization runs
struct DestructionAction {
@@ -172,6 +175,18 @@
a_binder->pingBinder();
}
+TEST(BinderAllocation, MakeScopeGuard) {
+ const auto m = ScopeDisallowMalloc();
+ {
+ auto guard1 = make_scope_guard([] {});
+ guard1.release();
+
+ auto guard2 = make_scope_guard([&guard1, ptr = imaginary_use] {
+ if (ptr == nullptr) guard1.release();
+ });
+ }
+}
+
TEST(BinderAllocation, InterfaceDescriptorTransaction) {
sp<IBinder> a_binder = GetRemoteBinder();
diff --git a/libs/binder/tests/binderHostDeviceTest.cpp b/libs/binder/tests/binderHostDeviceTest.cpp
index 0075688..0ae536c 100644
--- a/libs/binder/tests/binderHostDeviceTest.cpp
+++ b/libs/binder/tests/binderHostDeviceTest.cpp
@@ -75,7 +75,7 @@
public:
void SetUp() override {
auto debuggableResult = execute(Split("adb shell getprop ro.debuggable", " "), nullptr);
- ASSERT_THAT(debuggableResult, Ok());
+ ASSERT_TRUE(debuggableResult.has_value());
ASSERT_EQ(0, debuggableResult->exitCode) << *debuggableResult;
auto debuggableBool = ParseBool(Trim(debuggableResult->stdoutStr));
ASSERT_NE(ParseBoolResult::kError, debuggableBool) << Trim(debuggableResult->stdoutStr);
@@ -84,7 +84,7 @@
}
auto lsResult = execute(Split("adb shell which servicedispatcher", " "), nullptr);
- ASSERT_THAT(lsResult, Ok());
+ ASSERT_TRUE(lsResult.has_value());
if (lsResult->exitCode != 0) {
GTEST_SKIP() << "b/182914638: until feature is fully enabled, skip test on devices "
"without servicedispatcher";
@@ -95,7 +95,7 @@
auto service = execute({"adb", "shell", kServiceBinary, kServiceName, kDescriptor},
&CommandResult::stdoutEndsWithNewLine);
- ASSERT_THAT(service, Ok());
+ ASSERT_TRUE(service.has_value());
ASSERT_EQ(std::nullopt, service->exitCode) << *service;
mService = std::move(*service);
}
diff --git a/libs/binder/tests/binderLibTest.cpp b/libs/binder/tests/binderLibTest.cpp
index 341e9ce..f3969f1 100644
--- a/libs/binder/tests/binderLibTest.cpp
+++ b/libs/binder/tests/binderLibTest.cpp
@@ -29,17 +29,17 @@
#include <android-base/properties.h>
#include <android-base/result-gmock.h>
-#include <android-base/result.h>
-#include <android-base/scopeguard.h>
#include <android-base/strings.h>
#include <android-base/unique_fd.h>
#include <binder/Binder.h>
#include <binder/BpBinder.h>
+#include <binder/Functional.h>
#include <binder/IBinder.h>
#include <binder/IPCThreadState.h>
#include <binder/IServiceManager.h>
#include <binder/RpcServer.h>
#include <binder/RpcSession.h>
+#include <utils/Flattenable.h>
#include <linux/sched.h>
#include <sys/epoll.h>
@@ -52,6 +52,7 @@
#define ARRAY_SIZE(array) (sizeof array / sizeof array[0])
using namespace android;
+using namespace android::binder::impl;
using namespace std::string_literals;
using namespace std::chrono_literals;
using android::base::testing::HasValue;
@@ -1325,7 +1326,7 @@
ASSERT_EQ(0, ret);
// Restore the original file limits when the test finishes
- base::ScopeGuard guardUnguard([&]() { setrlimit(RLIMIT_NOFILE, &origNofile); });
+ auto guardUnguard = make_scope_guard([&]() { setrlimit(RLIMIT_NOFILE, &origNofile); });
rlimit testNofile = {1024, 1024};
ret = setrlimit(RLIMIT_NOFILE, &testNofile);
diff --git a/libs/binder/tests/binderRpcTest.cpp b/libs/binder/tests/binderRpcTest.cpp
index bc34d4c..bbb310a 100644
--- a/libs/binder/tests/binderRpcTest.cpp
+++ b/libs/binder/tests/binderRpcTest.cpp
@@ -35,6 +35,7 @@
#include <trusty/tipc.h>
#endif // BINDER_RPC_TO_TRUSTY_TEST
+#include "../Utils.h"
#include "binderRpcTestCommon.h"
#include "binderRpcTestFixture.h"
@@ -1197,7 +1198,7 @@
{.fd = serverFd.get(), .events = POLLIN, .revents = 0},
{.fd = connectFd.get(), .events = POLLOUT, .revents = 0},
};
- ret = TEMP_FAILURE_RETRY(poll(pfd, arraysize(pfd), -1));
+ ret = TEMP_FAILURE_RETRY(poll(pfd, countof(pfd), -1));
LOG_ALWAYS_FATAL_IF(ret < 0, "Error polling: %s", strerror(errno));
if (pfd[0].revents & POLLIN) {
diff --git a/libs/binder/tests/binderRpcTestCommon.h b/libs/binder/tests/binderRpcTestCommon.h
index 786fab8..c3070dd 100644
--- a/libs/binder/tests/binderRpcTestCommon.h
+++ b/libs/binder/tests/binderRpcTestCommon.h
@@ -74,8 +74,7 @@
#ifdef __ANDROID__
return base::GetProperty("ro.build.version.codename", "") != "REL";
#else
- // TODO(b/305983144): restrict on other platforms
- return true;
+ return false;
#endif
}
diff --git a/libs/binder/tests/binderRpcWireProtocolTest.cpp b/libs/binder/tests/binderRpcWireProtocolTest.cpp
index 7ec7c99..e59dc82 100644
--- a/libs/binder/tests/binderRpcWireProtocolTest.cpp
+++ b/libs/binder/tests/binderRpcWireProtocolTest.cpp
@@ -15,7 +15,6 @@
*/
#include <android-base/logging.h>
-#include <android-base/macros.h>
#include <android-base/properties.h>
#include <android-base/strings.h>
#include <binder/Parcel.h>
diff --git a/libs/binder/tests/binderSafeInterfaceTest.cpp b/libs/binder/tests/binderSafeInterfaceTest.cpp
index 1c13866..cbbbe74 100644
--- a/libs/binder/tests/binderSafeInterfaceTest.cpp
+++ b/libs/binder/tests/binderSafeInterfaceTest.cpp
@@ -28,6 +28,7 @@
#include <gtest/gtest.h>
#pragma clang diagnostic pop
+#include <utils/Flattenable.h>
#include <utils/LightRefBase.h>
#include <utils/NativeHandle.h>
diff --git a/libs/binder/tests/binderUtilsHostTest.cpp b/libs/binder/tests/binderUtilsHostTest.cpp
index 25e286c..6301c74 100644
--- a/libs/binder/tests/binderUtilsHostTest.cpp
+++ b/libs/binder/tests/binderUtilsHostTest.cpp
@@ -32,7 +32,7 @@
TEST(UtilsHost, ExecuteImmediately) {
auto result = execute({"echo", "foo"}, nullptr);
- ASSERT_THAT(result, Ok());
+ ASSERT_TRUE(result.has_value());
EXPECT_THAT(result->exitCode, Optional(EX_OK));
EXPECT_EQ(result->stdoutStr, "foo\n");
}
@@ -58,7 +58,7 @@
EXPECT_GE(elapsedMs, 1000);
EXPECT_LT(elapsedMs, 2000);
- ASSERT_THAT(result, Ok());
+ ASSERT_TRUE(result.has_value());
EXPECT_EQ(std::nullopt, result->exitCode);
EXPECT_EQ(result->stdoutStr, "foo\n");
}
@@ -83,7 +83,7 @@
EXPECT_GE(elapsedMs, 4000);
EXPECT_LT(elapsedMs, 6000);
- ASSERT_THAT(result, Ok());
+ ASSERT_TRUE(result.has_value());
EXPECT_EQ(std::nullopt, result->exitCode);
EXPECT_EQ(result->stdoutStr, "foo\n");
}
@@ -104,7 +104,7 @@
return false;
});
- ASSERT_THAT(result, Ok());
+ ASSERT_TRUE(result.has_value());
EXPECT_EQ(std::nullopt, result->exitCode);
EXPECT_THAT(result->signal, Optional(SIGKILL));
}
diff --git a/libs/binder/tests/parcel_fuzzer/Android.bp b/libs/binder/tests/parcel_fuzzer/Android.bp
index 383795e..fe79f8e 100644
--- a/libs/binder/tests/parcel_fuzzer/Android.bp
+++ b/libs/binder/tests/parcel_fuzzer/Android.bp
@@ -32,7 +32,11 @@
host_supported: true,
fuzz_config: {
- cc: ["smoreland@google.com"],
+ cc: [
+ "smoreland@google.com",
+ "waghpawan@google.com",
+ ],
+ use_for_presubmit: true,
},
srcs: [
diff --git a/libs/binder/tests/parcel_fuzzer/binder.cpp b/libs/binder/tests/parcel_fuzzer/binder.cpp
index 416ffad..ffeca2d 100644
--- a/libs/binder/tests/parcel_fuzzer/binder.cpp
+++ b/libs/binder/tests/parcel_fuzzer/binder.cpp
@@ -25,6 +25,7 @@
#include <binder/ParcelableHolder.h>
#include <binder/PersistableBundle.h>
#include <binder/Status.h>
+#include <utils/Flattenable.h>
#include "../../Utils.h"
diff --git a/libs/binder/tests/unit_fuzzers/RecordedTransactionFileFuzz.cpp b/libs/binder/tests/unit_fuzzers/RecordedTransactionFileFuzz.cpp
index e494366..0706182 100644
--- a/libs/binder/tests/unit_fuzzers/RecordedTransactionFileFuzz.cpp
+++ b/libs/binder/tests/unit_fuzzers/RecordedTransactionFileFuzz.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <android-base/macros.h>
#include <binder/RecordedTransaction.h>
#include <filesystem>
@@ -35,8 +34,8 @@
if (transaction.has_value()) {
intermediateFile = std::tmpfile();
- android::base::unique_fd fdForWriting(fileno(intermediateFile));
- auto writeStatus ATTRIBUTE_UNUSED = transaction.value().dumpToFile(fdForWriting);
+ android::base::unique_fd fdForWriting(dup(fileno(intermediateFile)));
+ auto writeStatus [[maybe_unused]] = transaction.value().dumpToFile(fdForWriting);
std::fclose(intermediateFile);
}
diff --git a/libs/binder/tests/unit_fuzzers/RecordedTransactionFuzz.cpp b/libs/binder/tests/unit_fuzzers/RecordedTransactionFuzz.cpp
index 33a653e..9289f6a 100644
--- a/libs/binder/tests/unit_fuzzers/RecordedTransactionFuzz.cpp
+++ b/libs/binder/tests/unit_fuzzers/RecordedTransactionFuzz.cpp
@@ -14,7 +14,6 @@
* limitations under the License.
*/
-#include <android-base/macros.h>
#include <binder/RecordedTransaction.h>
#include <fuzzbinder/random_parcel.h>
#include <filesystem>
@@ -55,7 +54,7 @@
if (transaction.has_value()) {
std::FILE* intermediateFile = std::tmpfile();
android::base::unique_fd fdForWriting(dup(fileno(intermediateFile)));
- auto writeStatus ATTRIBUTE_UNUSED = transaction.value().dumpToFile(fdForWriting);
+ auto writeStatus [[maybe_unused]] = transaction.value().dumpToFile(fdForWriting);
std::fclose(intermediateFile);
}
diff --git a/libs/binder/trusty/OS.cpp b/libs/binder/trusty/OS.cpp
index 43e06e0..0d18b0b 100644
--- a/libs/binder/trusty/OS.cpp
+++ b/libs/binder/trusty/OS.cpp
@@ -26,13 +26,11 @@
#include "../OS.h"
#include "TrustyStatus.h"
-using android::base::Result;
-
namespace android::binder::os {
-Result<void> setNonBlocking(android::base::borrowed_fd /*fd*/) {
+status_t setNonBlocking(android::base::borrowed_fd /*fd*/) {
// Trusty IPC syscalls are all non-blocking by default.
- return {};
+ return OK;
}
status_t getRandomBytes(uint8_t* data, size_t size) {
diff --git a/libs/binder/trusty/RpcTransportTipcTrusty.cpp b/libs/binder/trusty/RpcTransportTipcTrusty.cpp
index 692f82d..6bb45e2 100644
--- a/libs/binder/trusty/RpcTransportTipcTrusty.cpp
+++ b/libs/binder/trusty/RpcTransportTipcTrusty.cpp
@@ -29,6 +29,8 @@
namespace android {
+using namespace android::binder::impl;
+
// RpcTransport for Trusty.
class RpcTransportTipcTrusty : public RpcTransport {
public:
@@ -45,7 +47,7 @@
status_t interruptableWriteFully(
FdTrigger* /*fdTrigger*/, iovec* iovs, int niovs,
- const std::optional<android::base::function_ref<status_t()>>& /*altPoll*/,
+ const std::optional<SmallFunction<status_t()>>& /*altPoll*/,
const std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds)
override {
if (niovs < 0) {
@@ -115,7 +117,7 @@
status_t interruptableReadFully(
FdTrigger* /*fdTrigger*/, iovec* iovs, int niovs,
- const std::optional<android::base::function_ref<status_t()>>& /*altPoll*/,
+ const std::optional<SmallFunction<status_t()>>& /*altPoll*/,
std::vector<std::variant<base::unique_fd, base::borrowed_fd>>* ancillaryFds) override {
if (niovs < 0) {
return BAD_VALUE;
diff --git a/libs/binder/trusty/binderRpcTest/manifest.json b/libs/binder/trusty/binderRpcTest/manifest.json
index 1cefac5..6e20b8a 100644
--- a/libs/binder/trusty/binderRpcTest/manifest.json
+++ b/libs/binder/trusty/binderRpcTest/manifest.json
@@ -2,5 +2,5 @@
"uuid": "9dbe9fb8-60fd-4bdd-af86-03e95d7ad78b",
"app_name": "binderRpcTest",
"min_heap": 262144,
- "min_stack": 16384
+ "min_stack": 20480
}
diff --git a/libs/binder/trusty/include/binder/RpcServerTrusty.h b/libs/binder/trusty/include/binder/RpcServerTrusty.h
index 8924b36..aa476f9 100644
--- a/libs/binder/trusty/include/binder/RpcServerTrusty.h
+++ b/libs/binder/trusty/include/binder/RpcServerTrusty.h
@@ -17,7 +17,6 @@
#pragma once
#include <android-base/expected.h>
-#include <android-base/macros.h>
#include <android-base/unique_fd.h>
#include <binder/IBinder.h>
#include <binder/RpcServer.h>
@@ -83,7 +82,8 @@
// Both this class and RpcServer have multiple non-copyable fields,
// including mPortAcl below which can't be copied because mUuidPtrs
// holds pointers into it
- DISALLOW_COPY_AND_ASSIGN(RpcServerTrusty);
+ RpcServerTrusty(const RpcServerTrusty&) = delete;
+ void operator=(const RpcServerTrusty&) = delete;
friend sp<RpcServerTrusty>;
explicit RpcServerTrusty(std::unique_ptr<RpcTransportCtx> ctx, std::string&& portName,
diff --git a/libs/binder/trusty/logging.cpp b/libs/binder/trusty/logging.cpp
index b4243af..88a1075 100644
--- a/libs/binder/trusty/logging.cpp
+++ b/libs/binder/trusty/logging.cpp
@@ -22,7 +22,6 @@
#include <iostream>
#include <string>
-#include <android-base/macros.h>
#include <android-base/strings.h>
namespace android {
diff --git a/libs/graphicsenv/GraphicsEnv.cpp b/libs/graphicsenv/GraphicsEnv.cpp
index ed5d5c1..394a000 100644
--- a/libs/graphicsenv/GraphicsEnv.cpp
+++ b/libs/graphicsenv/GraphicsEnv.cpp
@@ -575,17 +575,23 @@
return mAngleNamespace;
}
- if (mAnglePath.empty() && !mShouldUseSystemAngle) {
- ALOGV("mAnglePath is empty and not using system ANGLE, abort creating ANGLE namespace");
+ // If ANGLE path is not set, it means ANGLE should not be used for this process;
+ // or if ANGLE path is set and set to use system ANGLE, then a namespace is not needed
+ // because:
+ // 1) if the default OpenGL ES driver is already ANGLE, then the loader will skip;
+ // 2) if the default OpenGL ES driver is native, then there's no symbol conflict;
+ // 3) if there's no OpenGL ES driver is preloaded, then there's no symbol conflict.
+ if (mAnglePath.empty() || mShouldUseSystemAngle) {
+ ALOGV("mAnglePath is empty or use system ANGLE, abort creating ANGLE namespace");
return nullptr;
}
// Construct the search paths for system ANGLE.
const char* const defaultLibraryPaths =
#if defined(__LP64__)
- "/vendor/lib64/egl:/system/lib64/egl";
+ "/vendor/lib64/egl:/system/lib64";
#else
- "/vendor/lib/egl:/system/lib/egl";
+ "/vendor/lib/egl:/system/lib";
#endif
// If the application process will run on top of system ANGLE, construct the namespace
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp
index 5b34ba1..b6a47fb 100644
--- a/libs/gui/BufferQueueConsumer.cpp
+++ b/libs/gui/BufferQueueConsumer.cpp
@@ -318,35 +318,44 @@
ATRACE_CALL();
ATRACE_BUFFER_INDEX(slot);
BQ_LOGV("detachBuffer: slot %d", slot);
- std::lock_guard<std::mutex> lock(mCore->mMutex);
+ sp<IProducerListener> listener;
+ {
+ std::lock_guard<std::mutex> lock(mCore->mMutex);
- if (mCore->mIsAbandoned) {
- BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
- return NO_INIT;
+ if (mCore->mIsAbandoned) {
+ BQ_LOGE("detachBuffer: BufferQueue has been abandoned");
+ return NO_INIT;
+ }
+
+ if (mCore->mSharedBufferMode || slot == mCore->mSharedBufferSlot) {
+ BQ_LOGE("detachBuffer: detachBuffer not allowed in shared buffer mode");
+ return BAD_VALUE;
+ }
+
+ if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
+ BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
+ slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
+ return BAD_VALUE;
+ } else if (!mSlots[slot].mBufferState.isAcquired()) {
+ BQ_LOGE("detachBuffer: slot %d is not owned by the consumer "
+ "(state = %s)", slot, mSlots[slot].mBufferState.string());
+ return BAD_VALUE;
+ }
+ if (mCore->mBufferReleasedCbEnabled) {
+ listener = mCore->mConnectedProducerListener;
+ }
+
+ mSlots[slot].mBufferState.detachConsumer();
+ mCore->mActiveBuffers.erase(slot);
+ mCore->mFreeSlots.insert(slot);
+ mCore->clearBufferSlotLocked(slot);
+ mCore->mDequeueCondition.notify_all();
+ VALIDATE_CONSISTENCY();
}
- if (mCore->mSharedBufferMode || slot == mCore->mSharedBufferSlot) {
- BQ_LOGE("detachBuffer: detachBuffer not allowed in shared buffer mode");
- return BAD_VALUE;
+ if (listener) {
+ listener->onBufferDetached(slot);
}
-
- if (slot < 0 || slot >= BufferQueueDefs::NUM_BUFFER_SLOTS) {
- BQ_LOGE("detachBuffer: slot index %d out of range [0, %d)",
- slot, BufferQueueDefs::NUM_BUFFER_SLOTS);
- return BAD_VALUE;
- } else if (!mSlots[slot].mBufferState.isAcquired()) {
- BQ_LOGE("detachBuffer: slot %d is not owned by the consumer "
- "(state = %s)", slot, mSlots[slot].mBufferState.string());
- return BAD_VALUE;
- }
-
- mSlots[slot].mBufferState.detachConsumer();
- mCore->mActiveBuffers.erase(slot);
- mCore->mFreeSlots.insert(slot);
- mCore->clearBufferSlotLocked(slot);
- mCore->mDequeueCondition.notify_all();
- VALIDATE_CONSISTENCY();
-
return NO_ERROR;
}
diff --git a/libs/gui/include/gui/IProducerListener.h b/libs/gui/include/gui/IProducerListener.h
index f7ffbb9..b15f501 100644
--- a/libs/gui/include/gui/IProducerListener.h
+++ b/libs/gui/include/gui/IProducerListener.h
@@ -49,6 +49,12 @@
// onBuffersFreed is called from IGraphicBufferConsumer::discardFreeBuffers
// to notify the producer that certain free buffers are discarded by the consumer.
virtual void onBuffersDiscarded(const std::vector<int32_t>& slots) = 0; // Asynchronous
+ // onBufferDetached is called from IGraphicBufferConsumer::detachBuffer to
+ // notify the producer that a buffer slot is free and ready to be dequeued.
+ //
+ // This is called without any lock held and can be called concurrently by
+ // multiple threads.
+ virtual void onBufferDetached(int /*slot*/) {} // Asynchronous
};
#ifndef NO_BINDER
diff --git a/libs/gui/tests/BufferQueue_test.cpp b/libs/gui/tests/BufferQueue_test.cpp
index 2f1fd3e..185ff83 100644
--- a/libs/gui/tests/BufferQueue_test.cpp
+++ b/libs/gui/tests/BufferQueue_test.cpp
@@ -1151,6 +1151,76 @@
ASSERT_EQ(true, output.bufferReplaced);
}
+struct BufferDetachedListener : public BnProducerListener {
+public:
+ BufferDetachedListener() = default;
+ virtual ~BufferDetachedListener() = default;
+
+ virtual void onBufferReleased() {}
+ virtual bool needsReleaseNotify() { return true; }
+ virtual void onBufferDetached(int slot) {
+ mDetachedSlots.push_back(slot);
+ }
+ const std::vector<int>& getDetachedSlots() const { return mDetachedSlots; }
+private:
+ std::vector<int> mDetachedSlots;
+};
+
+TEST_F(BufferQueueTest, TestConsumerDetachProducerListener) {
+ createBufferQueue();
+ sp<MockConsumer> mc(new MockConsumer);
+ ASSERT_EQ(OK, mConsumer->consumerConnect(mc, true));
+ IGraphicBufferProducer::QueueBufferOutput output;
+ sp<BufferDetachedListener> pl(new BufferDetachedListener);
+ ASSERT_EQ(OK, mProducer->connect(pl, NATIVE_WINDOW_API_CPU, true, &output));
+ ASSERT_EQ(OK, mProducer->setDequeueTimeout(0));
+ ASSERT_EQ(OK, mConsumer->setMaxAcquiredBufferCount(1));
+
+ sp<Fence> fence = Fence::NO_FENCE;
+ sp<GraphicBuffer> buffer = nullptr;
+ IGraphicBufferProducer::QueueBufferInput input(0ull, true,
+ HAL_DATASPACE_UNKNOWN, Rect::INVALID_RECT,
+ NATIVE_WINDOW_SCALING_MODE_FREEZE, 0, Fence::NO_FENCE);
+
+ int slots[2] = {};
+ status_t result = OK;
+ ASSERT_EQ(OK, mProducer->setMaxDequeuedBufferCount(2));
+
+ result = mProducer->dequeueBuffer(&slots[0], &fence, 0, 0, 0,
+ GRALLOC_USAGE_SW_READ_RARELY, nullptr, nullptr);
+ ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
+ ASSERT_EQ(OK, mProducer->requestBuffer(slots[0], &buffer));
+
+ result = mProducer->dequeueBuffer(&slots[1], &fence, 0, 0, 0,
+ GRALLOC_USAGE_SW_READ_RARELY, nullptr, nullptr);
+ ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
+ ASSERT_EQ(OK, mProducer->requestBuffer(slots[1], &buffer));
+
+ // Queue & detach one from two dequeued buffes.
+ ASSERT_EQ(OK, mProducer->queueBuffer(slots[1], input, &output));
+ BufferItem item{};
+ ASSERT_EQ(OK, mConsumer->acquireBuffer(&item, 0));
+ ASSERT_EQ(OK, mConsumer->detachBuffer(item.mSlot));
+
+ // Check whether the slot from IProducerListener is same to the detached slot.
+ ASSERT_EQ(pl->getDetachedSlots().size(), 1);
+ ASSERT_EQ(pl->getDetachedSlots()[0], slots[1]);
+
+ // Dequeue another buffer.
+ int slot;
+ result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
+ GRALLOC_USAGE_SW_READ_RARELY, nullptr, nullptr);
+ ASSERT_EQ(IGraphicBufferProducer::BUFFER_NEEDS_REALLOCATION, result);
+ ASSERT_EQ(OK, mProducer->requestBuffer(slot, &buffer));
+
+ // Dequeue should fail here, since we dequeued 3 buffers and one buffer was
+ // detached from consumer(Two buffers are dequeued, and the current max
+ // dequeued buffer count is two).
+ result = mProducer->dequeueBuffer(&slot, &fence, 0, 0, 0,
+ GRALLOC_USAGE_SW_READ_RARELY, nullptr, nullptr);
+ ASSERT_TRUE(result == WOULD_BLOCK || result == TIMED_OUT || result == INVALID_OPERATION);
+}
+
TEST_F(BufferQueueTest, TestStaleBufferHandleSentAfterDisconnect) {
createBufferQueue();
sp<MockConsumer> mc(new MockConsumer);
diff --git a/opengl/libs/EGL/Loader.cpp b/opengl/libs/EGL/Loader.cpp
index 04e2fff..10857a0 100644
--- a/opengl/libs/EGL/Loader.cpp
+++ b/opengl/libs/EGL/Loader.cpp
@@ -66,6 +66,8 @@
static const char* PERSIST_DRIVER_SUFFIX_PROPERTY = "persist.graphics.egl";
static const char* RO_DRIVER_SUFFIX_PROPERTY = "ro.hardware.egl";
static const char* RO_BOARD_PLATFORM_PROPERTY = "ro.board.platform";
+static const char* ANGLE_SUFFIX_VALUE = "angle";
+static const char* VENDOR_ANGLE_BUILD = "ro.gfx.angle.supported";
static const char* HAL_SUBNAME_KEY_PROPERTIES[3] = {
PERSIST_DRIVER_SUFFIX_PROPERTY,
@@ -80,6 +82,13 @@
"/vendor/lib/egl";
#endif
+static const char* const SYSTEM_LIB_DIR =
+#if defined(__LP64__)
+ "/system/lib64";
+#else
+ "/system/lib";
+#endif
+
static void* do_dlopen(const char* path, int mode) {
ATRACE_CALL();
return dlopen(path, mode);
@@ -434,98 +443,110 @@
}
}
+static std::string findLibrary(const std::string libraryName, const std::string searchPath,
+ const bool exact) {
+ if (exact) {
+ std::string absolutePath = searchPath + "/" + libraryName + ".so";
+ if (!access(absolutePath.c_str(), R_OK)) {
+ return absolutePath;
+ }
+ return std::string();
+ }
+
+ DIR* d = opendir(searchPath.c_str());
+ if (d != nullptr) {
+ struct dirent* e;
+ while ((e = readdir(d)) != nullptr) {
+ if (e->d_type == DT_DIR) {
+ continue;
+ }
+ if (!strcmp(e->d_name, "libGLES_android.so")) {
+ // always skip the software renderer
+ continue;
+ }
+ if (strstr(e->d_name, libraryName.c_str()) == e->d_name) {
+ if (!strcmp(e->d_name + strlen(e->d_name) - 3, ".so")) {
+ std::string result = searchPath + "/" + e->d_name;
+ closedir(d);
+ return result;
+ }
+ }
+ }
+ closedir(d);
+ }
+ // Driver not found. gah.
+ return std::string();
+}
+
static void* load_system_driver(const char* kind, const char* suffix, const bool exact) {
ATRACE_CALL();
- class MatchFile {
- public:
- static std::string find(const char* libraryName, const bool exact) {
- std::string absolutePath;
- if (findLibPath(absolutePath, libraryName, exact)) {
- return absolutePath;
- }
-
- // Driver not found. gah.
- return std::string();
- }
- private:
- static bool findLibPath(std::string& result, const std::string& pattern, bool exact) {
- const std::string vendorLibEglDirString = std::string(VENDOR_LIB_EGL_DIR);
- if (exact) {
- std::string absolutePath = vendorLibEglDirString + "/" + pattern + ".so";
- if (!access(absolutePath.c_str(), R_OK)) {
- result = absolutePath;
- return true;
- }
- return false;
- }
-
- DIR* d = opendir(VENDOR_LIB_EGL_DIR);
- if (d != nullptr) {
- struct dirent* e;
- while ((e = readdir(d)) != nullptr) {
- if (e->d_type == DT_DIR) {
- continue;
- }
- if (!strcmp(e->d_name, "libGLES_android.so")) {
- // always skip the software renderer
- continue;
- }
- if (strstr(e->d_name, pattern.c_str()) == e->d_name) {
- if (!strcmp(e->d_name + strlen(e->d_name) - 3, ".so")) {
- result = vendorLibEglDirString + "/" + e->d_name;
- closedir(d);
- return true;
- }
- }
- }
- closedir(d);
- }
- return false;
- }
- };
std::string libraryName = std::string("lib") + kind;
if (suffix) {
libraryName += std::string("_") + suffix;
} else if (!exact) {
- // Deprecated: we look for files that match
- // libGLES_*.so, or:
+ // Deprecated for devices launching in Android 14
+ // Look for files that match
+ // libGLES_*.so, or,
// libEGL_*.so, libGLESv1_CM_*.so, libGLESv2_*.so
libraryName += std::string("_");
}
- std::string absolutePath = MatchFile::find(libraryName.c_str(), exact);
+
+ void* dso = nullptr;
+
+ const bool AngleInVendor = property_get_bool(VENDOR_ANGLE_BUILD, false);
+ const bool isSuffixAngle = suffix != nullptr && strcmp(suffix, ANGLE_SUFFIX_VALUE) == 0;
+ // Only use sphal namespace when system ANGLE binaries are not the default drivers.
+ const bool useSphalNamespace = !isSuffixAngle || AngleInVendor;
+
+ const std::string absolutePath =
+ findLibrary(libraryName, useSphalNamespace ? VENDOR_LIB_EGL_DIR : SYSTEM_LIB_PATH,
+ exact);
if (absolutePath.empty()) {
// this happens often, we don't want to log an error
return nullptr;
}
- const char* const driver_absolute_path = absolutePath.c_str();
+ const char* const driverAbsolutePath = absolutePath.c_str();
- // Try to load drivers from the 'sphal' namespace, if it exist. Fall back to
- // the original routine when the namespace does not exist.
- // See /system/core/rootdir/etc/ld.config.txt for the configuration of the
- // sphal namespace.
- void* dso = do_android_load_sphal_library(driver_absolute_path,
- RTLD_NOW | RTLD_LOCAL);
+ // Currently the default driver is unlikely to be ANGLE on most devices,
+ // hence put this first.
+ if (useSphalNamespace) {
+ // Try to load drivers from the 'sphal' namespace, if it exist. Fall back to
+ // the original routine when the namespace does not exist.
+ // See /system/linkerconfig/contents/namespace for the configuration of the
+ // sphal namespace.
+ dso = do_android_load_sphal_library(driverAbsolutePath, RTLD_NOW | RTLD_LOCAL);
+ } else {
+ // Try to load drivers from the default namespace.
+ // See /system/linkerconfig/contents/namespace for the configuration of the
+ // default namespace.
+ dso = do_dlopen(driverAbsolutePath, RTLD_NOW | RTLD_LOCAL);
+ }
+
if (dso == nullptr) {
const char* err = dlerror();
- ALOGE("load_driver(%s): %s", driver_absolute_path, err ? err : "unknown");
+ ALOGE("load_driver(%s): %s", driverAbsolutePath, err ? err : "unknown");
return nullptr;
}
- ALOGD("loaded %s", driver_absolute_path);
+ ALOGV("loaded %s", driverAbsolutePath);
return dso;
}
static void* load_angle(const char* kind, android_namespace_t* ns) {
- const android_dlextinfo dlextinfo = {
- .flags = ANDROID_DLEXT_USE_NAMESPACE,
- .library_namespace = ns,
- };
-
std::string name = std::string("lib") + kind + "_angle.so";
+ void* so = nullptr;
- void* so = do_android_dlopen_ext(name.c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo);
+ if (android::GraphicsEnv::getInstance().shouldUseSystemAngle()) {
+ so = do_dlopen(name.c_str(), RTLD_NOW | RTLD_LOCAL);
+ } else {
+ const android_dlextinfo dlextinfo = {
+ .flags = ANDROID_DLEXT_USE_NAMESPACE,
+ .library_namespace = ns,
+ };
+ so = do_android_dlopen_ext(name.c_str(), RTLD_LOCAL | RTLD_NOW, &dlextinfo);
+ }
if (so) {
return so;
@@ -563,11 +584,13 @@
ATRACE_CALL();
android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
- if (!ns) {
+ // ANGLE namespace is used for loading ANGLE from apk, and hence if namespace is not
+ // constructed, it means ANGLE apk is not set to be the OpenGL ES driver.
+ // Hence skip if ANGLE apk and system ANGLE are not set to be the OpenGL ES driver.
+ if (!ns && !android::GraphicsEnv::getInstance().shouldUseSystemAngle()) {
return nullptr;
}
- android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::ANGLE);
driver_t* hnd = nullptr;
// ANGLE doesn't ship with GLES library, and thus we skip GLES driver.
@@ -588,10 +611,13 @@
}
void Loader::attempt_to_init_angle_backend(void* dso, egl_connection_t* cnx) {
- void* pANGLEGetDisplayPlatform = dlsym(dso, "ANGLEGetDisplayPlatform");
- if (pANGLEGetDisplayPlatform) {
+ cnx->angleGetDisplayPlatformFunc = dlsym(dso, "ANGLEGetDisplayPlatform");
+ cnx->angleResetDisplayPlatformFunc = dlsym(dso, "ANGLEResetDisplayPlatform");
+
+ if (cnx->angleGetDisplayPlatformFunc) {
ALOGV("ANGLE GLES library loaded");
cnx->angleLoaded = true;
+ android::GraphicsEnv::getInstance().setDriverToLoad(android::GpuStatsInfo::Driver::ANGLE);
} else {
ALOGV("Native GLES library loaded");
cnx->angleLoaded = false;
diff --git a/opengl/libs/EGL/egl_angle_platform.cpp b/opengl/libs/EGL/egl_angle_platform.cpp
index ee605c2..f0054a7 100644
--- a/opengl/libs/EGL/egl_angle_platform.cpp
+++ b/opengl/libs/EGL/egl_angle_platform.cpp
@@ -35,12 +35,6 @@
namespace angle {
-constexpr char kAngleEs2Lib[] = "libGLESv2_angle.so";
-constexpr int kAngleDlFlags = RTLD_LOCAL | RTLD_NOW;
-
-static GetDisplayPlatformFunc angleGetDisplayPlatform = nullptr;
-static ResetDisplayPlatformFunc angleResetDisplayPlatform = nullptr;
-
static time_t startTime = time(nullptr);
static const unsigned char* getTraceCategoryEnabledFlag(PlatformMethods* /*platform*/,
@@ -111,50 +105,19 @@
}
// Initialize function ptrs for ANGLE PlatformMethods struct, used for systrace
-bool initializeAnglePlatform(EGLDisplay dpy) {
- // Since we're inside libEGL, use dlsym to lookup fptr for ANGLEGetDisplayPlatform
- android_namespace_t* ns = android::GraphicsEnv::getInstance().getAngleNamespace();
- void* so = nullptr;
- if (ns) {
- const android_dlextinfo dlextinfo = {
- .flags = ANDROID_DLEXT_USE_NAMESPACE,
- .library_namespace = ns,
- };
- so = android_dlopen_ext(kAngleEs2Lib, kAngleDlFlags, &dlextinfo);
- if (so) {
- ALOGD("dlopen_ext from APK (%s) success at %p", kAngleEs2Lib, so);
- } else {
- ALOGE("dlopen_ext(\"%s\") failed: %s", kAngleEs2Lib, dlerror());
- return false;
- }
- } else {
- // If we are here, ANGLE is loaded as built-in gl driver in the sphal.
- so = android_load_sphal_library(kAngleEs2Lib, kAngleDlFlags);
- if (so) {
- ALOGD("dlopen (%s) success at %p", kAngleEs2Lib, so);
- } else {
- ALOGE("%s failed to dlopen %s: %s!", __FUNCTION__, kAngleEs2Lib, dlerror());
- return false;
- }
- }
-
- angleGetDisplayPlatform =
- reinterpret_cast<GetDisplayPlatformFunc>(dlsym(so, "ANGLEGetDisplayPlatform"));
-
- if (!angleGetDisplayPlatform) {
- ALOGE("dlsym lookup of ANGLEGetDisplayPlatform in libEGL_angle failed!");
- dlclose(so);
+bool initializeAnglePlatform(EGLDisplay dpy, android::egl_connection_t* const cnx) {
+ if (cnx->angleGetDisplayPlatformFunc == nullptr) {
+ ALOGE("ANGLEGetDisplayPlatform is not initialized!");
return false;
}
- angleResetDisplayPlatform =
- reinterpret_cast<ResetDisplayPlatformFunc>(dlsym(so, "ANGLEResetDisplayPlatform"));
+ GetDisplayPlatformFunc angleGetDisplayPlatform =
+ reinterpret_cast<GetDisplayPlatformFunc>(cnx->angleGetDisplayPlatformFunc);
PlatformMethods* platformMethods = nullptr;
if (!((angleGetDisplayPlatform)(dpy, g_PlatformMethodNames, g_NumPlatformMethods, nullptr,
&platformMethods))) {
ALOGE("ANGLEGetDisplayPlatform call failed!");
- dlclose(so);
return false;
}
if (platformMethods) {
@@ -166,8 +129,10 @@
return true;
}
-void resetAnglePlatform(EGLDisplay dpy) {
- if (angleResetDisplayPlatform) {
+void resetAnglePlatform(EGLDisplay dpy, android::egl_connection_t* const cnx) {
+ if (cnx->angleResetDisplayPlatformFunc) {
+ ResetDisplayPlatformFunc angleResetDisplayPlatform =
+ reinterpret_cast<ResetDisplayPlatformFunc>(cnx->angleResetDisplayPlatformFunc);
angleResetDisplayPlatform(dpy);
}
}
diff --git a/opengl/libs/EGL/egl_angle_platform.h b/opengl/libs/EGL/egl_angle_platform.h
index 6c24aa5..63806c2 100644
--- a/opengl/libs/EGL/egl_angle_platform.h
+++ b/opengl/libs/EGL/egl_angle_platform.h
@@ -25,8 +25,8 @@
namespace angle {
-bool initializeAnglePlatform(EGLDisplay dpy);
-void resetAnglePlatform(EGLDisplay dpy);
+bool initializeAnglePlatform(EGLDisplay dpy, android::egl_connection_t* const cnx);
+void resetAnglePlatform(EGLDisplay dpy, android::egl_connection_t* const cnx);
}; // namespace angle
diff --git a/opengl/libs/EGL/egl_display.cpp b/opengl/libs/EGL/egl_display.cpp
index 3317347..55a2682 100644
--- a/opengl/libs/EGL/egl_display.cpp
+++ b/opengl/libs/EGL/egl_display.cpp
@@ -168,7 +168,7 @@
if (dpy == EGL_NO_DISPLAY) {
ALOGE("eglGetPlatformDisplay failed!");
} else {
- if (!angle::initializeAnglePlatform(dpy)) {
+ if (!angle::initializeAnglePlatform(dpy, cnx)) {
ALOGE("initializeAnglePlatform failed!");
}
}
@@ -433,7 +433,7 @@
if (cnx->dso && disp.state == egl_display_t::INITIALIZED) {
// If we're using ANGLE reset any custom DisplayPlatform
if (cnx->angleLoaded) {
- angle::resetAnglePlatform(disp.dpy);
+ angle::resetAnglePlatform(disp.dpy, cnx);
}
if (cnx->egl.eglTerminate(disp.dpy) == EGL_FALSE) {
ALOGW("eglTerminate(%p) failed (%s)", disp.dpy,
diff --git a/opengl/libs/EGL/egldefs.h b/opengl/libs/EGL/egldefs.h
index 3bd37cb..90a3c19 100644
--- a/opengl/libs/EGL/egldefs.h
+++ b/opengl/libs/EGL/egldefs.h
@@ -42,7 +42,9 @@
libGles1(nullptr),
libGles2(nullptr),
systemDriverUnloaded(false),
- angleLoaded(false) {
+ angleLoaded(false),
+ angleGetDisplayPlatformFunc(nullptr),
+ angleResetDisplayPlatformFunc(nullptr) {
const char* const* entries = platform_names;
EGLFuncPointer* curr = reinterpret_cast<EGLFuncPointer*>(&platform);
while (*entries) {
@@ -75,6 +77,9 @@
bool systemDriverUnloaded;
bool angleLoaded; // Was ANGLE successfully loaded
+
+ void* angleGetDisplayPlatformFunc;
+ void* angleResetDisplayPlatformFunc;
};
extern gl_hooks_t gHooks[2];
diff --git a/services/inputflinger/dispatcher/LatencyAggregator.cpp b/services/inputflinger/dispatcher/LatencyAggregator.cpp
index 96d78c3..e09d97a 100644
--- a/services/inputflinger/dispatcher/LatencyAggregator.cpp
+++ b/services/inputflinger/dispatcher/LatencyAggregator.cpp
@@ -126,6 +126,7 @@
}
void LatencyAggregator::processStatistics(const InputEventTimeline& timeline) {
+ std::scoped_lock lock(mLock);
// Before we do any processing, check that we have not yet exceeded MAX_SIZE
if (mNumSketchEventsProcessed >= MAX_EVENTS_FOR_STATISTICS) {
return;
@@ -167,6 +168,7 @@
}
AStatsManager_PullAtomCallbackReturn LatencyAggregator::pullData(AStatsEventList* data) {
+ std::scoped_lock lock(mLock);
std::array<std::unique_ptr<SafeBytesField>, SketchIndex::SIZE> serializedDownData;
std::array<std::unique_ptr<SafeBytesField>, SketchIndex::SIZE> serializedMoveData;
for (size_t i = 0; i < SketchIndex::SIZE; i++) {
@@ -257,6 +259,7 @@
}
std::string LatencyAggregator::dump(const char* prefix) const {
+ std::scoped_lock lock(mLock);
std::string sketchDump = StringPrintf("%s Sketches:\n", prefix);
for (size_t i = 0; i < SketchIndex::SIZE; i++) {
const int64_t numDown = mDownSketches[i]->num_values();
diff --git a/services/inputflinger/dispatcher/LatencyAggregator.h b/services/inputflinger/dispatcher/LatencyAggregator.h
index 60b6813..d6d1686 100644
--- a/services/inputflinger/dispatcher/LatencyAggregator.h
+++ b/services/inputflinger/dispatcher/LatencyAggregator.h
@@ -16,6 +16,7 @@
#pragma once
+#include <android-base/thread_annotations.h>
#include <kll.h>
#include <statslog.h>
#include <utils/Timers.h>
@@ -61,10 +62,13 @@
~LatencyAggregator();
private:
+ // Binder call -- called on a binder thread. This is different from the thread where the rest of
+ // the public API is called.
static AStatsManager_PullAtomCallbackReturn pullAtomCallback(int32_t atom_tag,
AStatsEventList* data,
void* cookie);
AStatsManager_PullAtomCallbackReturn pullData(AStatsEventList* data);
+
// ---------- Slow event handling ----------
void processSlowEvent(const InputEventTimeline& timeline);
nsecs_t mLastSlowEventTime = 0;
@@ -74,14 +78,17 @@
size_t mNumEventsSinceLastSlowEventReport = 0;
// ---------- Statistics handling ----------
+ // Statistics is pulled rather than pushed. It's pulled on a binder thread, and therefore will
+ // be accessed by two different threads. The lock is needed to protect the pulled data.
+ mutable std::mutex mLock;
void processStatistics(const InputEventTimeline& timeline);
// Sketches
std::array<std::unique_ptr<dist_proc::aggregation::KllQuantile>, SketchIndex::SIZE>
- mDownSketches;
+ mDownSketches GUARDED_BY(mLock);
std::array<std::unique_ptr<dist_proc::aggregation::KllQuantile>, SketchIndex::SIZE>
- mMoveSketches;
+ mMoveSketches GUARDED_BY(mLock);
// How many events have been processed so far
- size_t mNumSketchEventsProcessed = 0;
+ size_t mNumSketchEventsProcessed GUARDED_BY(mLock) = 0;
};
} // namespace android::inputdispatcher
diff --git a/services/surfaceflinger/fuzzer/Android.bp b/services/surfaceflinger/fuzzer/Android.bp
index f76a8d7..9534bd8 100644
--- a/services/surfaceflinger/fuzzer/Android.bp
+++ b/services/surfaceflinger/fuzzer/Android.bp
@@ -73,9 +73,17 @@
],
fuzz_config: {
cc: [
- "android-media-fuzzing-reports@google.com",
+ "android-cogs-eng@google.com",
],
- componentid: 155276,
+ componentid: 1075131,
+ hotlists: [
+ "4593311",
+ ],
+ description: "The fuzzer targets the APIs of libsurfaceflinger library",
+ vector: "local_no_privileges_required",
+ service_privilege: "privileged",
+ users: "multi_user",
+ fuzzed_code_usage: "shipped",
},
}