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