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

Commit e639e642 authored by Treehugger Robot's avatar Treehugger Robot Committed by Android (Google) Code Review
Browse files

Merge changes I824b6019,Ib6f38933,I6d7229fd into main

* changes:
  Log when AIBinder_linkToDeath is called before AIBinder_DeathRecipient_setOnUnlink
  Log when AIBinder_linkToDeath is called with the same cookie
  libbinder_ndk_unit_test: AIBinder_linkToDeath multiple times
parents 42c06327 50c3d701
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -478,6 +478,21 @@ binder_status_t AIBinder_DeathRecipient::linkToDeath(const sp<IBinder>& binder,

    std::lock_guard<std::mutex> l(mDeathRecipientsMutex);

    if (mOnUnlinked && cookie &&
        std::find_if(mDeathRecipients.begin(), mDeathRecipients.end(),
                     [&cookie](android::sp<TransferDeathRecipient> recipient) {
                         return recipient->getCookie() == cookie;
                     }) != mDeathRecipients.end()) {
        ALOGE("Attempting to AIBinder_linkToDeath with the same cookie with an onUnlink callback. "
              "This will cause the onUnlinked callback to be called multiple times with the same "
              "cookie, which is usually not intended.");
    }
    if (!mOnUnlinked && cookie) {
        ALOGW("AIBinder_linkToDeath is being called with a non-null cookie and no onUnlink "
              "callback set. This might not be intended. AIBinder_DeathRecipient_setOnUnlinked "
              "should be called first.");
    }

    sp<TransferDeathRecipient> recipient =
            new TransferDeathRecipient(binder, cookie, this, mOnDied, mOnUnlinked);

+50 −0
Original line number Diff line number Diff line
@@ -697,6 +697,56 @@ TEST(NdkBinder, DeathRecipientDropBinderOnDied) {
    }
}

void LambdaOnUnlinkMultiple(void* cookie) {
    auto funcs = static_cast<DeathRecipientCookie*>(cookie);
    (*funcs->onUnlink)();
};

TEST(NdkBinder, DeathRecipientMultipleLinks) {
    using namespace std::chrono_literals;

    ndk::SpAIBinder binder;
    sp<IFoo> foo = IFoo::getService(IFoo::kSomeInstanceName, binder.getR());
    ASSERT_NE(nullptr, foo.get());
    ASSERT_NE(nullptr, binder);

    std::function<void(void)> onDeath = [&] {};

    std::mutex unlinkMutex;
    std::condition_variable unlinkCv;
    bool unlinkReceived = false;
    constexpr uint32_t kNumberOfLinksToDeath = 4;
    uint32_t countdown = kNumberOfLinksToDeath;

    std::function<void(void)> onUnlink = [&] {
        std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
        countdown--;
        if (countdown == 0) {
            unlinkReceived = true;
            unlinkCv.notify_one();
        }
    };

    DeathRecipientCookie* cookie = new DeathRecipientCookie{&onDeath, &onUnlink};

    ndk::ScopedAIBinder_DeathRecipient recipient(AIBinder_DeathRecipient_new(LambdaOnDeath));
    AIBinder_DeathRecipient_setOnUnlinked(recipient.get(), LambdaOnUnlinkMultiple);

    for (int32_t i = 0; i < kNumberOfLinksToDeath; i++) {
        EXPECT_EQ(STATUS_OK,
                  AIBinder_linkToDeath(binder.get(), recipient.get(), static_cast<void*>(cookie)));
    }

    foo = nullptr;
    binder = nullptr;

    std::unique_lock<std::mutex> lockUnlink(unlinkMutex);
    EXPECT_TRUE(unlinkCv.wait_for(lockUnlink, 5s, [&] { return unlinkReceived; }))
            << "countdown: " << countdown;
    EXPECT_TRUE(unlinkReceived);
    EXPECT_EQ(countdown, 0);
}

TEST(NdkBinder, RetrieveNonNdkService) {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wdeprecated-declarations"