xref: /aosp_15_r20/frameworks/native/services/powermanager/tests/IThermalManagerTest.cpp (revision 38e8c45f13ce32b0dcecb25141ffecaf386fa17f)
1*38e8c45fSAndroid Build Coastguard Worker /*
2*38e8c45fSAndroid Build Coastguard Worker  * Copyright (C) 2020 The Android Open Source Project
3*38e8c45fSAndroid Build Coastguard Worker  *
4*38e8c45fSAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
5*38e8c45fSAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
6*38e8c45fSAndroid Build Coastguard Worker  * You may obtain a copy of the License at
7*38e8c45fSAndroid Build Coastguard Worker  *
8*38e8c45fSAndroid Build Coastguard Worker  *      http://www.apache.org/licenses/LICENSE-2.0
9*38e8c45fSAndroid Build Coastguard Worker  *
10*38e8c45fSAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
11*38e8c45fSAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
12*38e8c45fSAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*38e8c45fSAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
14*38e8c45fSAndroid Build Coastguard Worker  * limitations under the License.
15*38e8c45fSAndroid Build Coastguard Worker  */
16*38e8c45fSAndroid Build Coastguard Worker 
17*38e8c45fSAndroid Build Coastguard Worker #define LOG_TAG "ThermalManagerTest"
18*38e8c45fSAndroid Build Coastguard Worker //#define LOG_NDEBUG 0
19*38e8c45fSAndroid Build Coastguard Worker 
20*38e8c45fSAndroid Build Coastguard Worker #include <thread>
21*38e8c45fSAndroid Build Coastguard Worker 
22*38e8c45fSAndroid Build Coastguard Worker #include <android/os/BnThermalStatusListener.h>
23*38e8c45fSAndroid Build Coastguard Worker #include <android/os/IThermalService.h>
24*38e8c45fSAndroid Build Coastguard Worker #include <binder/IPCThreadState.h>
25*38e8c45fSAndroid Build Coastguard Worker #include <binder/IServiceManager.h>
26*38e8c45fSAndroid Build Coastguard Worker #include <binder/Parcel.h>
27*38e8c45fSAndroid Build Coastguard Worker #include <condition_variable>
28*38e8c45fSAndroid Build Coastguard Worker #include <gtest/gtest.h>
29*38e8c45fSAndroid Build Coastguard Worker #include <powermanager/PowerManager.h>
30*38e8c45fSAndroid Build Coastguard Worker #include <utils/Log.h>
31*38e8c45fSAndroid Build Coastguard Worker 
32*38e8c45fSAndroid Build Coastguard Worker using namespace android;
33*38e8c45fSAndroid Build Coastguard Worker using namespace android::os;
34*38e8c45fSAndroid Build Coastguard Worker using namespace std::chrono_literals;
35*38e8c45fSAndroid Build Coastguard Worker 
36*38e8c45fSAndroid Build Coastguard Worker class IThermalServiceTestListener : public BnThermalStatusListener {
37*38e8c45fSAndroid Build Coastguard Worker     public:
38*38e8c45fSAndroid Build Coastguard Worker         virtual binder::Status onStatusChange(int status) override;
39*38e8c45fSAndroid Build Coastguard Worker         std::condition_variable mCondition;
40*38e8c45fSAndroid Build Coastguard Worker         int mListenerStatus = 0;
41*38e8c45fSAndroid Build Coastguard Worker         std::mutex mMutex;
42*38e8c45fSAndroid Build Coastguard Worker };
43*38e8c45fSAndroid Build Coastguard Worker 
onStatusChange(int status)44*38e8c45fSAndroid Build Coastguard Worker binder::Status IThermalServiceTestListener::onStatusChange(int status) {
45*38e8c45fSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mMutex);
46*38e8c45fSAndroid Build Coastguard Worker     mListenerStatus = status;
47*38e8c45fSAndroid Build Coastguard Worker     ALOGI("IThermalServiceTestListener::notifyListener %d", mListenerStatus);
48*38e8c45fSAndroid Build Coastguard Worker     mCondition.notify_all();
49*38e8c45fSAndroid Build Coastguard Worker     return binder::Status::ok();
50*38e8c45fSAndroid Build Coastguard Worker }
51*38e8c45fSAndroid Build Coastguard Worker 
52*38e8c45fSAndroid Build Coastguard Worker class IThermalServiceTest : public testing::Test {
53*38e8c45fSAndroid Build Coastguard Worker     public:
54*38e8c45fSAndroid Build Coastguard Worker         IThermalServiceTest();
55*38e8c45fSAndroid Build Coastguard Worker         void setThermalOverride(int level);
56*38e8c45fSAndroid Build Coastguard Worker         int getStatusFromService();
57*38e8c45fSAndroid Build Coastguard Worker         void SetUp() override;
58*38e8c45fSAndroid Build Coastguard Worker         void TearDown() override;
59*38e8c45fSAndroid Build Coastguard Worker     protected:
60*38e8c45fSAndroid Build Coastguard Worker         sp<IThermalService> mThermalSvc;
61*38e8c45fSAndroid Build Coastguard Worker         int mServiceStatus;
62*38e8c45fSAndroid Build Coastguard Worker         sp<IThermalServiceTestListener> mCallback;
63*38e8c45fSAndroid Build Coastguard Worker };
64*38e8c45fSAndroid Build Coastguard Worker 
IThermalServiceTest()65*38e8c45fSAndroid Build Coastguard Worker IThermalServiceTest::IThermalServiceTest()
66*38e8c45fSAndroid Build Coastguard Worker  : mServiceStatus(0),
67*38e8c45fSAndroid Build Coastguard Worker    mCallback(sp<IThermalServiceTestListener>::make()) {
68*38e8c45fSAndroid Build Coastguard Worker }
69*38e8c45fSAndroid Build Coastguard Worker 
setThermalOverride(int level)70*38e8c45fSAndroid Build Coastguard Worker void IThermalServiceTest::setThermalOverride(int level) {
71*38e8c45fSAndroid Build Coastguard Worker     std::string cmdStr = "cmd thermalservice override-status " + std::to_string(level);
72*38e8c45fSAndroid Build Coastguard Worker     system(cmdStr.c_str());
73*38e8c45fSAndroid Build Coastguard Worker }
74*38e8c45fSAndroid Build Coastguard Worker 
getStatusFromService()75*38e8c45fSAndroid Build Coastguard Worker int IThermalServiceTest::getStatusFromService() {
76*38e8c45fSAndroid Build Coastguard Worker     int status;
77*38e8c45fSAndroid Build Coastguard Worker     binder::Status ret = mThermalSvc->getCurrentThermalStatus(&status);
78*38e8c45fSAndroid Build Coastguard Worker     if (ret.isOk()) {
79*38e8c45fSAndroid Build Coastguard Worker         return status;
80*38e8c45fSAndroid Build Coastguard Worker     } else {
81*38e8c45fSAndroid Build Coastguard Worker         return BAD_VALUE;
82*38e8c45fSAndroid Build Coastguard Worker     }
83*38e8c45fSAndroid Build Coastguard Worker }
84*38e8c45fSAndroid Build Coastguard Worker 
SetUp()85*38e8c45fSAndroid Build Coastguard Worker void IThermalServiceTest::SetUp() {
86*38e8c45fSAndroid Build Coastguard Worker     setThermalOverride(0);
87*38e8c45fSAndroid Build Coastguard Worker     // use checkService() to avoid blocking if thermal service is not up yet
88*38e8c45fSAndroid Build Coastguard Worker     sp<IBinder> binder =
89*38e8c45fSAndroid Build Coastguard Worker         defaultServiceManager()->checkService(String16("thermalservice"));
90*38e8c45fSAndroid Build Coastguard Worker     EXPECT_NE(binder, nullptr);
91*38e8c45fSAndroid Build Coastguard Worker     mThermalSvc = interface_cast<IThermalService>(binder);
92*38e8c45fSAndroid Build Coastguard Worker     EXPECT_NE(mThermalSvc, nullptr);
93*38e8c45fSAndroid Build Coastguard Worker     // Lock mutex for operation, so listener will only be processed after wait_for is called
94*38e8c45fSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mCallback->mMutex);
95*38e8c45fSAndroid Build Coastguard Worker     bool success = false;
96*38e8c45fSAndroid Build Coastguard Worker     binder::Status ret = mThermalSvc->registerThermalStatusListener(mCallback, &success);
97*38e8c45fSAndroid Build Coastguard Worker     // Check the result
98*38e8c45fSAndroid Build Coastguard Worker     ASSERT_TRUE(success);
99*38e8c45fSAndroid Build Coastguard Worker     ASSERT_TRUE(ret.isOk());
100*38e8c45fSAndroid Build Coastguard Worker     // Wait for listener called after registration, shouldn't timeout
101*38e8c45fSAndroid Build Coastguard Worker     EXPECT_NE(mCallback->mCondition.wait_for(lock, 1s), std::cv_status::timeout);
102*38e8c45fSAndroid Build Coastguard Worker }
103*38e8c45fSAndroid Build Coastguard Worker 
TearDown()104*38e8c45fSAndroid Build Coastguard Worker void IThermalServiceTest::TearDown() {
105*38e8c45fSAndroid Build Coastguard Worker     bool success = false;
106*38e8c45fSAndroid Build Coastguard Worker     binder::Status ret = mThermalSvc->unregisterThermalStatusListener(mCallback, &success);
107*38e8c45fSAndroid Build Coastguard Worker     ASSERT_TRUE(success);
108*38e8c45fSAndroid Build Coastguard Worker     ASSERT_TRUE(ret.isOk());
109*38e8c45fSAndroid Build Coastguard Worker }
110*38e8c45fSAndroid Build Coastguard Worker 
111*38e8c45fSAndroid Build Coastguard Worker class IThermalListenerTest : public IThermalServiceTest, public testing::WithParamInterface<int32_t> {
112*38e8c45fSAndroid Build Coastguard Worker   public:
PrintParam(const testing::TestParamInfo<ParamType> & info)113*38e8c45fSAndroid Build Coastguard Worker     static auto PrintParam(const testing::TestParamInfo<ParamType> &info) {
114*38e8c45fSAndroid Build Coastguard Worker         return std::to_string(info.param);
115*38e8c45fSAndroid Build Coastguard Worker     }
116*38e8c45fSAndroid Build Coastguard Worker };
117*38e8c45fSAndroid Build Coastguard Worker 
TEST_P(IThermalListenerTest,TestListener)118*38e8c45fSAndroid Build Coastguard Worker TEST_P(IThermalListenerTest, TestListener) {
119*38e8c45fSAndroid Build Coastguard Worker     int level = GetParam();
120*38e8c45fSAndroid Build Coastguard Worker     // Lock mutex for operation, so listener will only be processed after wait_for is called
121*38e8c45fSAndroid Build Coastguard Worker     std::unique_lock<std::mutex> lock(mCallback->mMutex);
122*38e8c45fSAndroid Build Coastguard Worker     // Set the override thermal status
123*38e8c45fSAndroid Build Coastguard Worker     setThermalOverride(level);
124*38e8c45fSAndroid Build Coastguard Worker     // Wait for listener called, shouldn't timeout
125*38e8c45fSAndroid Build Coastguard Worker     EXPECT_NE(mCallback->mCondition.wait_for(lock, 1s), std::cv_status::timeout);
126*38e8c45fSAndroid Build Coastguard Worker     // Check the result
127*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(level, mCallback->mListenerStatus);
128*38e8c45fSAndroid Build Coastguard Worker     ALOGI("Thermal listener status %d, expecting %d", mCallback->mListenerStatus, level);
129*38e8c45fSAndroid Build Coastguard Worker }
130*38e8c45fSAndroid Build Coastguard Worker 
131*38e8c45fSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(TestListenerLevels, IThermalListenerTest, testing::Range(
132*38e8c45fSAndroid Build Coastguard Worker         static_cast<int>(ThermalStatus::THERMAL_STATUS_LIGHT),
133*38e8c45fSAndroid Build Coastguard Worker         static_cast<int>(ThermalStatus::THERMAL_STATUS_SHUTDOWN)),
134*38e8c45fSAndroid Build Coastguard Worker         IThermalListenerTest::PrintParam);
135*38e8c45fSAndroid Build Coastguard Worker 
136*38e8c45fSAndroid Build Coastguard Worker class IThermalLevelTest : public IThermalServiceTest, public testing::WithParamInterface<int32_t> {
137*38e8c45fSAndroid Build Coastguard Worker   public:
PrintParam(const testing::TestParamInfo<ParamType> & info)138*38e8c45fSAndroid Build Coastguard Worker     static auto PrintParam(const testing::TestParamInfo<ParamType> &info) {
139*38e8c45fSAndroid Build Coastguard Worker         return std::to_string(info.param);
140*38e8c45fSAndroid Build Coastguard Worker     }
141*38e8c45fSAndroid Build Coastguard Worker };
142*38e8c45fSAndroid Build Coastguard Worker 
TEST_P(IThermalLevelTest,TestGetStatusLevel)143*38e8c45fSAndroid Build Coastguard Worker TEST_P(IThermalLevelTest, TestGetStatusLevel) {
144*38e8c45fSAndroid Build Coastguard Worker     int level = GetParam();
145*38e8c45fSAndroid Build Coastguard Worker     setThermalOverride(level);
146*38e8c45fSAndroid Build Coastguard Worker     mServiceStatus = getStatusFromService();
147*38e8c45fSAndroid Build Coastguard Worker     EXPECT_EQ(level, mServiceStatus);
148*38e8c45fSAndroid Build Coastguard Worker }
149*38e8c45fSAndroid Build Coastguard Worker 
150*38e8c45fSAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(TestStatusLevels, IThermalLevelTest, testing::Range(
151*38e8c45fSAndroid Build Coastguard Worker         static_cast<int>(ThermalStatus::THERMAL_STATUS_NONE),
152*38e8c45fSAndroid Build Coastguard Worker         static_cast<int>(ThermalStatus::THERMAL_STATUS_SHUTDOWN)),
153*38e8c45fSAndroid Build Coastguard Worker         IThermalLevelTest::PrintParam);
154*38e8c45fSAndroid Build Coastguard Worker 
main(int argc,char ** argv)155*38e8c45fSAndroid Build Coastguard Worker int main(int argc, char **argv) {
156*38e8c45fSAndroid Build Coastguard Worker     std::unique_ptr<std::thread> binderLoop;
157*38e8c45fSAndroid Build Coastguard Worker     binderLoop = std::make_unique<std::thread>(
158*38e8c45fSAndroid Build Coastguard Worker             [&] { IPCThreadState::self()->joinThreadPool(true); });
159*38e8c45fSAndroid Build Coastguard Worker 
160*38e8c45fSAndroid Build Coastguard Worker     ::testing::InitGoogleTest(&argc, argv);
161*38e8c45fSAndroid Build Coastguard Worker     int status = RUN_ALL_TESTS();
162*38e8c45fSAndroid Build Coastguard Worker     ALOGV("Test result = %d\n", status);
163*38e8c45fSAndroid Build Coastguard Worker 
164*38e8c45fSAndroid Build Coastguard Worker     return status;
165*38e8c45fSAndroid Build Coastguard Worker }
166