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

Commit 9ae49349 authored by Steven Moreland's avatar Steven Moreland
Browse files

IThermalManagerTest: fix double-owned

The test object is owned by gtest and therefore also can't
be a callback (inheriting from RefBase which implies
ownership).

This bug is causing an abort now. To detect it automatically in the
type system, you can use the cflag
-DANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION .

Fixes: 240371998
Test: atest libpowermanager_test
Change-Id: I68a2403d33cdbba225aee95a5dd22a96371904ce
parent 8f60fa31
Loading
Loading
Loading
Loading
+29 −25
Original line number Original line Diff line number Diff line
@@ -33,26 +33,38 @@ using namespace android;
using namespace android::os;
using namespace android::os;
using namespace std::chrono_literals;
using namespace std::chrono_literals;


class IThermalServiceTest : public testing::Test,
class IThermalServiceTestListener : public BnThermalStatusListener {
                            public BnThermalStatusListener{
    public:
        virtual binder::Status onStatusChange(int status) override;
        std::condition_variable mCondition;
        int mListenerStatus = 0;
        std::mutex mMutex;
};

binder::Status IThermalServiceTestListener::onStatusChange(int status) {
    std::unique_lock<std::mutex> lock(mMutex);
    mListenerStatus = status;
    ALOGI("IThermalServiceTestListener::notifyListener %d", mListenerStatus);
    mCondition.notify_all();
    return binder::Status::ok();
}

class IThermalServiceTest : public testing::Test {
    public:
    public:
        IThermalServiceTest();
        IThermalServiceTest();
        void setThermalOverride(int level);
        void setThermalOverride(int level);
        virtual binder::Status onStatusChange(int status) override;
        int getStatusFromService();
        int getStatusFromService();
        void SetUp() override;
        void SetUp() override;
        void TearDown() override;
        void TearDown() override;
    protected:
    protected:
        sp<IThermalService> mThermalSvc;
        sp<IThermalService> mThermalSvc;
        std::condition_variable mCondition;
        int mListenerStatus;
        int mServiceStatus;
        int mServiceStatus;
        std::mutex mMutex;
        sp<IThermalServiceTestListener> mCallback;
};
};


IThermalServiceTest::IThermalServiceTest()
IThermalServiceTest::IThermalServiceTest()
 : mListenerStatus(0),
 : mServiceStatus(0),
   mServiceStatus(0) {
   mCallback(sp<IThermalServiceTestListener>::make()) {
}
}


void IThermalServiceTest::setThermalOverride(int level) {
void IThermalServiceTest::setThermalOverride(int level) {
@@ -60,14 +72,6 @@ void IThermalServiceTest::setThermalOverride(int level) {
    system(cmdStr.c_str());
    system(cmdStr.c_str());
}
}


binder::Status IThermalServiceTest::onStatusChange(int status) {
    std::unique_lock<std::mutex> lock(mMutex);
    mListenerStatus = status;
    ALOGI("IThermalServiceTest::notifyListener %d", mListenerStatus);
    mCondition.notify_all();
    return binder::Status::ok();
}

int IThermalServiceTest::getStatusFromService() {
int IThermalServiceTest::getStatusFromService() {
    int status;
    int status;
    binder::Status ret = mThermalSvc->getCurrentThermalStatus(&status);
    binder::Status ret = mThermalSvc->getCurrentThermalStatus(&status);
@@ -87,19 +91,19 @@ void IThermalServiceTest::SetUp() {
    mThermalSvc = interface_cast<IThermalService>(binder);
    mThermalSvc = interface_cast<IThermalService>(binder);
    EXPECT_NE(mThermalSvc, nullptr);
    EXPECT_NE(mThermalSvc, nullptr);
    // Lock mutex for operation, so listener will only be processed after wait_for is called
    // Lock mutex for operation, so listener will only be processed after wait_for is called
    std::unique_lock<std::mutex> lock(mMutex);
    std::unique_lock<std::mutex> lock(mCallback->mMutex);
    bool success = false;
    bool success = false;
    binder::Status ret = mThermalSvc->registerThermalStatusListener(this, &success);
    binder::Status ret = mThermalSvc->registerThermalStatusListener(mCallback, &success);
    // Check the result
    // Check the result
    ASSERT_TRUE(success);
    ASSERT_TRUE(success);
    ASSERT_TRUE(ret.isOk());
    ASSERT_TRUE(ret.isOk());
    // Wait for listener called after registration, shouldn't timeout
    // Wait for listener called after registration, shouldn't timeout
    EXPECT_NE(mCondition.wait_for(lock, 1s), std::cv_status::timeout);
    EXPECT_NE(mCallback->mCondition.wait_for(lock, 1s), std::cv_status::timeout);
}
}


void IThermalServiceTest::TearDown() {
void IThermalServiceTest::TearDown() {
    bool success = false;
    bool success = false;
    binder::Status ret = mThermalSvc->unregisterThermalStatusListener(this, &success);
    binder::Status ret = mThermalSvc->unregisterThermalStatusListener(mCallback, &success);
    ASSERT_TRUE(success);
    ASSERT_TRUE(success);
    ASSERT_TRUE(ret.isOk());
    ASSERT_TRUE(ret.isOk());
}
}
@@ -114,14 +118,14 @@ class IThermalListenerTest : public IThermalServiceTest, public testing::WithPar
TEST_P(IThermalListenerTest, TestListener) {
TEST_P(IThermalListenerTest, TestListener) {
    int level = GetParam();
    int level = GetParam();
    // Lock mutex for operation, so listener will only be processed after wait_for is called
    // Lock mutex for operation, so listener will only be processed after wait_for is called
    std::unique_lock<std::mutex> lock(mMutex);
    std::unique_lock<std::mutex> lock(mCallback->mMutex);
    // Set the override thermal status
    // Set the override thermal status
    setThermalOverride(level);
    setThermalOverride(level);
    // Wait for listener called, shouldn't timeout
    // Wait for listener called, shouldn't timeout
    EXPECT_NE(mCondition.wait_for(lock, 1s), std::cv_status::timeout);
    EXPECT_NE(mCallback->mCondition.wait_for(lock, 1s), std::cv_status::timeout);
    // Check the result
    // Check the result
    EXPECT_EQ(level, mListenerStatus);
    EXPECT_EQ(level, mCallback->mListenerStatus);
    ALOGI("Thermal listener status %d, expecting %d", mListenerStatus, level);
    ALOGI("Thermal listener status %d, expecting %d", mCallback->mListenerStatus, level);
}
}


INSTANTIATE_TEST_SUITE_P(TestListenerLevels, IThermalListenerTest, testing::Range(
INSTANTIATE_TEST_SUITE_P(TestListenerLevels, IThermalListenerTest, testing::Range(