Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6f69c67d authored by Steven Moreland's avatar Steven Moreland Committed by Gerrit Code Review
Browse files

Merge "libbinder: cache interface descriptor if empty"

parents bceee9e6 f2830fe7
Loading
Loading
Loading
Loading
+8 −9
Original line number Diff line number Diff line
@@ -47,6 +47,8 @@ std::atomic_bool BpBinder::sCountByUidEnabled(false);
binder_proxy_limit_callback BpBinder::sLimitCallback;
bool BpBinder::sBinderProxyThrottleCreate = false;

static StaticString16 kDescriptorUninit(u"<uninit descriptor>");

// Arbitrarily high value that probably distinguishes a bad behaving app
uint32_t BpBinder::sBinderProxyCountHighWatermark = 2500;
// Another arbitrary value a binder count needs to drop below before another callback will be called
@@ -211,6 +213,7 @@ BpBinder::BpBinder(Handle&& handle)
        mAlive(true),
        mObitsSent(false),
        mObituaries(nullptr),
        mDescriptorCache(kDescriptorUninit),
        mTrackedUid(-1) {
    extendObjectLifetime(OBJECT_LIFETIME_WEAK);
}
@@ -258,12 +261,12 @@ std::optional<int32_t> BpBinder::getDebugBinderHandle() const {

bool BpBinder::isDescriptorCached() const {
    Mutex::Autolock _l(mLock);
    return mDescriptorCache.size() ? true : false;
    return mDescriptorCache.string() != kDescriptorUninit.string();
}

const String16& BpBinder::getInterfaceDescriptor() const
{
    if (isDescriptorCached() == false) {
    if (!isDescriptorCached()) {
        sp<BpBinder> thiz = sp<BpBinder>::fromExisting(const_cast<BpBinder*>(this));

        Parcel data;
@@ -276,8 +279,7 @@ const String16& BpBinder::getInterfaceDescriptor() const
            Mutex::Autolock _l(mLock);
            // mDescriptorCache could have been assigned while the lock was
            // released.
            if (mDescriptorCache.size() == 0)
                mDescriptorCache = res;
            if (mDescriptorCache.string() == kDescriptorUninit.string()) mDescriptorCache = res;
        }
    }

@@ -369,10 +371,7 @@ status_t BpBinder::transact(
        if (data.dataSize() > LOG_TRANSACTIONS_OVER_SIZE) {
            Mutex::Autolock _l(mLock);
            ALOGW("Large outgoing transaction of %zu bytes, interface descriptor %s, code %d",
                  data.dataSize(),
                  mDescriptorCache.size() ? String8(mDescriptorCache).c_str()
                                          : "<uncached descriptor>",
                  code);
                  data.dataSize(), String8(mDescriptorCache).c_str(), code);
        }

        if (status == DEAD_OBJECT) mAlive = 0;
@@ -647,7 +646,7 @@ void BpBinder::onLastStrongRef(const void* /*id*/) {
    if(obits != nullptr) {
        if (!obits->isEmpty()) {
            ALOGI("onLastStrongRef automatically unlinking death recipients: %s",
                  mDescriptorCache.size() ? String8(mDescriptorCache).c_str() : "<uncached descriptor>");
                  String8(mDescriptorCache).c_str());
        }

        if (ipc) ipc->clearDeathNotification(binderHandle(), this);
+18 −0
Original line number Diff line number Diff line
@@ -172,6 +172,24 @@ TEST(BinderAllocation, PingTransaction) {
    a_binder->pingBinder();
}

TEST(BinderAllocation, InterfaceDescriptorTransaction) {
    sp<IBinder> a_binder = GetRemoteBinder();

    size_t mallocs = 0;
    const auto on_malloc = OnMalloc([&](size_t bytes) {
        mallocs++;
        // Happens to be SM package length. We could switch to forking
        // and registering our own service if it became an issue.
        EXPECT_EQ(bytes, 78);
    });

    a_binder->getInterfaceDescriptor();
    a_binder->getInterfaceDescriptor();
    a_binder->getInterfaceDescriptor();

    EXPECT_EQ(mallocs, 1);
}

TEST(BinderAllocation, SmallTransaction) {
    String16 empty_descriptor = String16("");
    sp<IServiceManager> manager = defaultServiceManager();