1 /*
2  * Copyright (C) 2016 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <algorithm>
18 #include <cmath>
19 #include <string>
20 #include <vector>
21 
22 #define LOG_TAG "thermal_hidl_hal_test"
23 
24 #include <android-base/logging.h>
25 #include <android/hardware/thermal/1.0/IThermal.h>
26 #include <android/hardware/thermal/1.0/types.h>
27 #include <gtest/gtest.h>
28 #include <hidl/GtestPrinter.h>
29 #include <hidl/ServiceManagement.h>
30 #include <unistd.h>
31 
32 using ::android::hardware::hidl_string;
33 using ::android::hardware::hidl_vec;
34 using ::android::hardware::thermal::V1_0::CoolingDevice;
35 using ::android::hardware::thermal::V1_0::CpuUsage;
36 using ::android::hardware::thermal::V1_0::IThermal;
37 using ::android::hardware::thermal::V1_0::Temperature;
38 using ::android::hardware::thermal::V1_0::TemperatureType;
39 using ::android::hardware::thermal::V1_0::ThermalStatus;
40 using ::android::hardware::thermal::V1_0::ThermalStatusCode;
41 using ::android::hardware::Return;
42 using ::android::hardware::Void;
43 using ::android::sp;
44 
45 #define MONITORING_OPERATION_NUMBER 10
46 
47 #define MAX_DEVICE_TEMPERATURE 200
48 #define MAX_FAN_SPEED 20000
49 
50 // The main test class for THERMAL HIDL HAL.
51 class ThermalHidlTest : public testing::TestWithParam<std::string> {
52  public:
SetUp()53   virtual void SetUp() override {
54     thermal_ = IThermal::getService(GetParam());
55     ASSERT_NE(thermal_, nullptr);
56     baseSize_ = 0;
57     names_.clear();
58   }
59 
TearDown()60   virtual void TearDown() override {}
61 
62  protected:
63   // Check validity of temperatures returned by Thremal HAL.
checkTemperatures(const hidl_vec<Temperature> temperatures)64   void checkTemperatures(const hidl_vec<Temperature> temperatures) {
65     size_t size = temperatures.size();
66     EXPECT_LE(baseSize_, size);
67 
68     for (size_t i = 0; i < size; ++i) {
69       checkDeviceTemperature(temperatures[i]);
70       if (i < baseSize_) {
71         EXPECT_EQ(names_[i], temperatures[i].name.c_str());
72       } else {
73           // Names must be unique only for known temperature types.
74           if (temperatures[i].type != TemperatureType::UNKNOWN) {
75               EXPECT_EQ(names_.end(), std::find(names_.begin(), names_.end(),
76                                                 temperatures[i].name.c_str()));
77           }
78           names_.push_back(temperatures[i].name);
79       }
80     }
81     baseSize_ = size;
82   }
83 
84   // Check validity of CPU usages returned by Thermal HAL.
checkCpuUsages(const hidl_vec<CpuUsage> & cpuUsages)85   void checkCpuUsages(const hidl_vec<CpuUsage>& cpuUsages) {
86     size_t size = cpuUsages.size();
87     // A number of CPU's does not change.
88     if (baseSize_ != 0) EXPECT_EQ(baseSize_, size);
89 
90     for (size_t i = 0; i < size; ++i) {
91       checkCpuUsage(cpuUsages[i]);
92       if (i < baseSize_) {
93         EXPECT_EQ(names_[i], cpuUsages[i].name.c_str());
94       } else {
95           // Names are not guaranteed to be unique because of the current
96           // default Thermal HAL implementation.
97           names_.push_back(cpuUsages[i].name);
98       }
99     }
100     baseSize_ = size;
101   }
102 
103   // Check validity of cooling devices information returned by Thermal HAL.
checkCoolingDevices(const hidl_vec<CoolingDevice> coolingDevices)104   void checkCoolingDevices(const hidl_vec<CoolingDevice> coolingDevices) {
105     size_t size = coolingDevices.size();
106     EXPECT_LE(baseSize_, size);
107 
108     for (size_t i = 0; i < size; ++i) {
109       checkCoolingDevice(coolingDevices[i]);
110       if (i < baseSize_) {
111         EXPECT_EQ(names_[i], coolingDevices[i].name.c_str());
112       } else {
113         // Names must be unique.
114         EXPECT_EQ(names_.end(), std::find(names_.begin(), names_.end(),
115                                           coolingDevices[i].name.c_str()));
116         names_.push_back(coolingDevices[i].name);
117       }
118     }
119     baseSize_ = size;
120   }
121 
122   sp<IThermal> thermal_;
123 
124  private:
125   // Check validity of temperature returned by Thermal HAL.
checkDeviceTemperature(const Temperature & temperature)126   void checkDeviceTemperature(const Temperature& temperature) {
127     // .currentValue of known type is in Celsius and must be reasonable.
128     EXPECT_TRUE(temperature.type == TemperatureType::UNKNOWN ||
129                 std::abs(temperature.currentValue) < MAX_DEVICE_TEMPERATURE ||
130                 isnan(temperature.currentValue));
131 
132     // .name must not be empty.
133     EXPECT_LT(0u, temperature.name.size());
134 
135     // .currentValue must not exceed .shutdwonThreshold if defined.
136     EXPECT_TRUE(temperature.currentValue < temperature.shutdownThreshold ||
137                 isnan(temperature.currentValue) || isnan(temperature.shutdownThreshold));
138 
139     // .throttlingThreshold must not exceed .shutdownThreshold if defined.
140     EXPECT_TRUE(temperature.throttlingThreshold < temperature.shutdownThreshold ||
141                 isnan(temperature.throttlingThreshold) || isnan(temperature.shutdownThreshold));
142   }
143 
144   // Check validity of CPU usage returned by Thermal HAL.
checkCpuUsage(const CpuUsage & cpuUsage)145   void checkCpuUsage(const CpuUsage& cpuUsage) {
146     // .active must be less than .total if CPU is online.
147     EXPECT_TRUE(!cpuUsage.isOnline ||
148                 (cpuUsage.active >= 0 && cpuUsage.total >= 0 &&
149                  cpuUsage.total >= cpuUsage.active));
150 
151     // .name must be not empty.
152     EXPECT_LT(0u, cpuUsage.name.size());
153   }
154 
155   // Check validity of a cooling device information returned by Thermal HAL.
checkCoolingDevice(const CoolingDevice & coolingDevice)156   void checkCoolingDevice(const CoolingDevice& coolingDevice) {
157     EXPECT_LE(0, coolingDevice.currentValue);
158     EXPECT_GT(MAX_FAN_SPEED, coolingDevice.currentValue);
159     EXPECT_LT(0u, coolingDevice.name.size());
160   }
161 
162   size_t baseSize_;
163   std::vector<hidl_string> names_;
164 };
165 
166 // Sanity test for Thermal::getTemperatures().
TEST_P(ThermalHidlTest,TemperatureTest)167 TEST_P(ThermalHidlTest, TemperatureTest) {
168   hidl_vec<Temperature> passed;
169   for (size_t i = 0; i < MONITORING_OPERATION_NUMBER; ++i) {
170     thermal_->getTemperatures(
171         [&passed](ThermalStatus status, hidl_vec<Temperature> temperatures) {
172           EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
173           passed = temperatures;
174         });
175 
176     checkTemperatures(passed);
177     sleep(1);
178   }
179 }
180 
181 // Sanity test for Thermal::getCpuUsages().
TEST_P(ThermalHidlTest,CpuUsageTest)182 TEST_P(ThermalHidlTest, CpuUsageTest) {
183   hidl_vec<CpuUsage> passed;
184   for (size_t i = 0; i < MONITORING_OPERATION_NUMBER; ++i) {
185     thermal_->getCpuUsages(
186         [&passed](ThermalStatus status, hidl_vec<CpuUsage> cpuUsages) {
187           EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
188           passed = cpuUsages;
189         });
190 
191     checkCpuUsages(passed);
192     sleep(1);
193   }
194 }
195 
196 // Sanity test for Thermal::getCoolingDevices().
TEST_P(ThermalHidlTest,CoolingDeviceTest)197 TEST_P(ThermalHidlTest, CoolingDeviceTest) {
198   hidl_vec<CoolingDevice> passed;
199   for (size_t i = 0; i < MONITORING_OPERATION_NUMBER; ++i) {
200     thermal_->getCoolingDevices([&passed](
201         ThermalStatus status, hidl_vec<CoolingDevice> coolingDevices) {
202       EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code);
203       passed = coolingDevices;
204     });
205 
206     checkCoolingDevices(passed);
207     sleep(1);
208   }
209 }
210 
211 GTEST_ALLOW_UNINSTANTIATED_PARAMETERIZED_TEST(ThermalHidlTest);
212 INSTANTIATE_TEST_SUITE_P(
213         PerInstance, ThermalHidlTest,
214         testing::ValuesIn(android::hardware::getAllHalInstanceNames(IThermal::descriptor)),
215         android::hardware::PrintInstanceNameToString);
216