1 /* 2 * Copyright (C) 2018 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 <android/hardware/thermal/2.0/IThermal.h> 18 #include <android/hardware/thermal/2.0/IThermalChangedCallback.h> 19 #include <android/hardware/thermal/2.0/types.h> 20 21 #include <VtsHalHidlTargetCallbackBase.h> 22 #include <VtsHalHidlTargetTestBase.h> 23 #include <VtsHalHidlTargetTestEnvBase.h> 24 25 using ::android::sp; 26 using ::android::hardware::hidl_enum_range; 27 using ::android::hardware::hidl_vec; 28 using ::android::hardware::Return; 29 using ::android::hardware::Void; 30 using ::android::hardware::thermal::V1_0::ThermalStatus; 31 using ::android::hardware::thermal::V1_0::ThermalStatusCode; 32 using ::android::hardware::thermal::V2_0::CoolingDevice; 33 using ::android::hardware::thermal::V2_0::CoolingType; 34 using ::android::hardware::thermal::V2_0::IThermal; 35 using ::android::hardware::thermal::V2_0::IThermalChangedCallback; 36 using ::android::hardware::thermal::V2_0::Temperature; 37 using ::android::hardware::thermal::V2_0::TemperatureThreshold; 38 using ::android::hardware::thermal::V2_0::TemperatureType; 39 using ::android::hardware::thermal::V2_0::ThrottlingSeverity; 40 41 constexpr char kCallbackNameNotifyThrottling[] = "notifyThrottling"; 42 static const Temperature kThrottleTemp = { 43 .type = TemperatureType::SKIN, 44 .name = "test temperature sensor", 45 .value = 98.6, 46 .throttlingStatus = ThrottlingSeverity::CRITICAL, 47 }; 48 49 class ThermalCallbackArgs { 50 public: 51 Temperature temperature; 52 }; 53 54 // Callback class for receiving thermal event notifications from main class 55 class ThermalCallback : public ::testing::VtsHalHidlTargetCallbackBase<ThermalCallbackArgs>, 56 public IThermalChangedCallback { 57 public: 58 Return<void> notifyThrottling(const Temperature& temperature) override { 59 ThermalCallbackArgs args; 60 args.temperature = temperature; 61 NotifyFromCallback(kCallbackNameNotifyThrottling, args); 62 return Void(); 63 } 64 }; 65 66 // Test environment for Thermal HIDL HAL. 67 class ThermalHidlEnvironment : public ::testing::VtsHalHidlTargetTestEnvBase { 68 public: 69 // get the test environment singleton 70 static ThermalHidlEnvironment* Instance() { 71 static ThermalHidlEnvironment* instance = new ThermalHidlEnvironment; 72 return instance; 73 } 74 75 void registerTestServices() override { registerTestService<IThermal>(); } 76 77 private: 78 ThermalHidlEnvironment() {} 79 }; 80 81 // The main test class for THERMAL HIDL HAL 2.0. 82 class ThermalHidlTest : public ::testing::VtsHalHidlTargetTestBase { 83 public: 84 virtual void SetUp() override { 85 mThermal = ::testing::VtsHalHidlTargetTestBase::getService<IThermal>( 86 ThermalHidlEnvironment::Instance()->getServiceName<IThermal>()); 87 ASSERT_NE(mThermal, nullptr); 88 mThermalCallback = new (std::nothrow) ThermalCallback(); 89 ASSERT_NE(mThermalCallback, nullptr); 90 auto ret = mThermal->registerThermalChangedCallback( 91 mThermalCallback, false, TemperatureType::SKIN, 92 [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); }); 93 ASSERT_TRUE(ret.isOk()); 94 // Expect to fail if register again 95 ret = mThermal->registerThermalChangedCallback( 96 mThermalCallback, false, TemperatureType::SKIN, 97 [](ThermalStatus status) { EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); }); 98 ASSERT_TRUE(ret.isOk()); 99 } 100 101 virtual void TearDown() override { 102 auto ret = mThermal->unregisterThermalChangedCallback( 103 mThermalCallback, 104 [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); }); 105 ASSERT_TRUE(ret.isOk()); 106 // Expect to fail if unregister again 107 ret = mThermal->unregisterThermalChangedCallback( 108 mThermalCallback, 109 [](ThermalStatus status) { EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); }); 110 ASSERT_TRUE(ret.isOk()); 111 } 112 113 protected: 114 sp<IThermal> mThermal; 115 sp<ThermalCallback> mThermalCallback; 116 }; // class ThermalHidlTest 117 118 // Test ThermalChangedCallback::notifyThrottling(). 119 // This just calls into and back from our local ThermalChangedCallback impl. 120 // Note: a real thermal throttling event from the Thermal HAL could be 121 // inadvertently received here. 122 TEST_F(ThermalHidlTest, NotifyThrottlingTest) { 123 auto ret = mThermalCallback->notifyThrottling(kThrottleTemp); 124 ASSERT_TRUE(ret.isOk()); 125 auto res = mThermalCallback->WaitForCallback(kCallbackNameNotifyThrottling); 126 EXPECT_TRUE(res.no_timeout); 127 ASSERT_TRUE(res.args); 128 EXPECT_EQ(kThrottleTemp, res.args->temperature); 129 } 130 131 // Test Thermal->registerThermalChangedCallback. 132 TEST_F(ThermalHidlTest, RegisterThermalChangedCallbackTest) { 133 // Expect to fail with same callback 134 auto ret = mThermal->registerThermalChangedCallback( 135 mThermalCallback, false, TemperatureType::SKIN, 136 [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::FAILURE, status.code); }); 137 ASSERT_TRUE(ret.isOk()); 138 // Expect to fail with null callback 139 ret = mThermal->registerThermalChangedCallback( 140 nullptr, false, TemperatureType::SKIN, 141 [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::FAILURE, status.code); }); 142 ASSERT_TRUE(ret.isOk()); 143 sp<ThermalCallback> localThermalCallback = new (std::nothrow) ThermalCallback(); 144 // Expect to succeed with different callback 145 ret = mThermal->registerThermalChangedCallback( 146 localThermalCallback, false, TemperatureType::SKIN, 147 [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); }); 148 ASSERT_TRUE(ret.isOk()); 149 // Remove the local callback 150 ret = mThermal->unregisterThermalChangedCallback( 151 localThermalCallback, 152 [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); }); 153 ASSERT_TRUE(ret.isOk()); 154 // Expect to fail with null callback 155 ret = mThermal->unregisterThermalChangedCallback(nullptr, [](ThermalStatus status) { 156 EXPECT_EQ(ThermalStatusCode::FAILURE, status.code); 157 }); 158 ASSERT_TRUE(ret.isOk()); 159 } 160 161 // Test Thermal->unregisterThermalChangedCallback. 162 TEST_F(ThermalHidlTest, UnregisterThermalChangedCallbackTest) { 163 sp<ThermalCallback> localThermalCallback = new (std::nothrow) ThermalCallback(); 164 // Expect to fail as the callback was not registered before 165 auto ret = mThermal->unregisterThermalChangedCallback( 166 localThermalCallback, 167 [](ThermalStatus status) { EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); }); 168 ASSERT_TRUE(ret.isOk()); 169 // Register a local callback 170 ret = mThermal->registerThermalChangedCallback( 171 localThermalCallback, false, TemperatureType::SKIN, 172 [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); }); 173 ASSERT_TRUE(ret.isOk()); 174 // Expect to succeed with callback removed 175 ret = mThermal->unregisterThermalChangedCallback( 176 localThermalCallback, 177 [](ThermalStatus status) { EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); }); 178 ASSERT_TRUE(ret.isOk()); 179 // Expect to fail as the callback has been unregistered already 180 ret = mThermal->unregisterThermalChangedCallback( 181 localThermalCallback, 182 [](ThermalStatus status) { EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); }); 183 ASSERT_TRUE(ret.isOk()); 184 } 185 186 // Sanity test for Thermal::getCurrentTemperatures(). 187 TEST_F(ThermalHidlTest, TemperatureTest) { 188 mThermal->getCurrentTemperatures(false, TemperatureType::SKIN, 189 [](ThermalStatus status, hidl_vec<Temperature> temperatures) { 190 if (temperatures.size()) { 191 EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); 192 } else { 193 EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); 194 } 195 for (int i = 0; i < temperatures.size(); ++i) { 196 EXPECT_LT(0u, temperatures[i].name.size()); 197 } 198 }); 199 auto types = hidl_enum_range<TemperatureType>(); 200 for (const auto& type : types) { 201 mThermal->getCurrentTemperatures( 202 true, type, [&type](ThermalStatus status, hidl_vec<Temperature> temperatures) { 203 if (temperatures.size()) { 204 EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); 205 } else { 206 EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); 207 } 208 for (int i = 0; i < temperatures.size(); ++i) { 209 EXPECT_EQ(type, temperatures[i].type); 210 EXPECT_LT(0u, temperatures[i].name.size()); 211 } 212 }); 213 } 214 } 215 216 // Sanity test for Thermal::getTemperatureThresholds(). 217 TEST_F(ThermalHidlTest, TemperatureThresholdTest) { 218 mThermal->getTemperatureThresholds( 219 false, TemperatureType::SKIN, 220 [](ThermalStatus status, hidl_vec<TemperatureThreshold> temperatures) { 221 if (temperatures.size()) { 222 EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); 223 } else { 224 EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); 225 } 226 }); 227 for (int i = static_cast<int>(TemperatureType::UNKNOWN); 228 i <= static_cast<int>(TemperatureType::POWER_AMPLIFIER); ++i) { 229 auto type = static_cast<TemperatureType>(i); 230 mThermal->getTemperatureThresholds( 231 true, type, [&type](ThermalStatus status, hidl_vec<TemperatureThreshold> temperatures) { 232 if (temperatures.size()) { 233 EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); 234 } else { 235 EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); 236 } 237 for (int i = 0; i < temperatures.size(); ++i) { 238 EXPECT_EQ(type, temperatures[i].type); 239 } 240 }); 241 } 242 } 243 244 // Sanity test for Thermal::getCurrentCoolingDevices(). 245 TEST_F(ThermalHidlTest, CoolingDeviceTest) { 246 mThermal->getCurrentCoolingDevices( 247 false, CoolingType::CPU, [](ThermalStatus status, hidl_vec<CoolingDevice> cooling_devices) { 248 if (cooling_devices.size()) { 249 EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); 250 } else { 251 EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); 252 } 253 for (int i = 0; i < cooling_devices.size(); ++i) { 254 EXPECT_LT(0u, cooling_devices[i].name.size()); 255 } 256 }); 257 for (int i = 0; i <= static_cast<int>(CoolingType::COMPONENT); ++i) { 258 auto type = static_cast<CoolingType>(i); 259 mThermal->getCurrentCoolingDevices( 260 true, type, [&type](ThermalStatus status, hidl_vec<CoolingDevice> cooling_devices) { 261 if (cooling_devices.size()) { 262 EXPECT_EQ(ThermalStatusCode::SUCCESS, status.code); 263 } else { 264 EXPECT_NE(ThermalStatusCode::SUCCESS, status.code); 265 } 266 for (int i = 0; i < cooling_devices.size(); ++i) { 267 EXPECT_EQ(type, cooling_devices[i].type); 268 EXPECT_LT(0u, cooling_devices[i].name.size()); 269 } 270 }); 271 } 272 } 273 274 int main(int argc, char** argv) { 275 ::testing::AddGlobalTestEnvironment(ThermalHidlEnvironment::Instance()); 276 ::testing::InitGoogleTest(&argc, argv); 277 ThermalHidlEnvironment::Instance()->init(&argc, argv); 278 int status = RUN_ALL_TESTS(); 279 cout << "Test result = " << status << std::endl; 280 return status; 281 } 282