1 /*
2 * Copyright (C) 2023 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 <aidl/android/hardware/thermal/BnThermalChangedCallback.h>
18 #include <log/log.h>
19
20 #include "Thermal.h"
21 #include "mock_thermal_helper.h"
22
23 namespace aidl::android::hardware::thermal::implementation {
24
25 class ThermalLooperTest : public testing::Test {
26 protected:
SetUp()27 void SetUp() override {
28 ON_CALL(*helper, isInitializedOk).WillByDefault(testing::Return(true));
29 }
30
31 std::shared_ptr<testing::NiceMock<MockThermalHelper>> helper =
32 std::make_shared<testing::NiceMock<MockThermalHelper>>();
33 std::shared_ptr<Thermal> thermal = ndk::SharedRefBase::make<Thermal>(helper);
34 };
35
36 class TestCallback : public BnThermalChangedCallback {
37 public:
notifyThrottling(const Temperature & t)38 ndk::ScopedAStatus notifyThrottling(const Temperature &t) override {
39 std::lock_guard<std::mutex> lock_guard(mMutex);
40 mTemperatures.emplace_back(t);
41 return ndk::ScopedAStatus::ok();
42 }
43
notifyThresholdChanged(const TemperatureThreshold &)44 ndk::ScopedAStatus notifyThresholdChanged(const TemperatureThreshold &) override {
45 // no impl for threshold change
46 return ndk::ScopedAStatus::ok();
47 }
48
getTemperatures()49 std::vector<Temperature> getTemperatures() {
50 std::lock_guard<std::mutex> lock_guard(mMutex);
51 return mTemperatures;
52 }
53
clear()54 void clear() {
55 std::lock_guard<std::mutex> lock_guard(mMutex);
56 mTemperatures.clear();
57 }
58
59 private:
60 std::vector<Temperature> mTemperatures;
61 std::mutex mMutex;
62 };
63
TEST_F(ThermalLooperTest,AsyncCallbackTest)64 TEST_F(ThermalLooperTest, AsyncCallbackTest) {
65 Temperature t1;
66 t1.type = TemperatureType::SKIN;
67 Temperature t2;
68 t2.type = TemperatureType::UNKNOWN;
69 ON_CALL(*helper, fillCurrentTemperatures)
70 .WillByDefault([this, t1, t2](bool, bool, TemperatureType,
71 std::vector<Temperature> *temperatures) {
72 std::vector<Temperature> ret = {t1, t2};
73 *temperatures = ret;
74 sleep(1);
75 return true;
76 });
77 std::shared_ptr<TestCallback> callback = ndk::SharedRefBase::make<TestCallback>();
78 std::shared_ptr<TestCallback> callbackWithType = ndk::SharedRefBase::make<TestCallback>();
79
80 // if callback immediately unregistered, no async callback should be scheduled
81 ASSERT_TRUE(thermal->registerThermalChangedCallback(callback).isOk());
82 ASSERT_TRUE(
83 thermal->registerThermalChangedCallbackWithType(callbackWithType, TemperatureType::SKIN)
84 .isOk());
85 ASSERT_TRUE(thermal->unregisterThermalChangedCallback(callback).isOk());
86 ASSERT_TRUE(thermal->unregisterThermalChangedCallback(callbackWithType).isOk());
87 sleep(3);
88 ASSERT_TRUE(callback->getTemperatures().empty());
89 ASSERT_TRUE(callbackWithType->getTemperatures().empty());
90
91 // otherwise, async callback should be scheduled if registered
92 ASSERT_TRUE(thermal->registerThermalChangedCallback(callback).isOk());
93 ASSERT_TRUE(
94 thermal->registerThermalChangedCallbackWithType(callbackWithType, TemperatureType::SKIN)
95 .isOk());
96 sleep(3);
97 ASSERT_THAT(callback->getTemperatures(), testing::UnorderedElementsAreArray({t1, t2}));
98 ASSERT_THAT(callbackWithType->getTemperatures(), testing::UnorderedElementsAreArray({t1}));
99 }
100
101 } // namespace aidl::android::hardware::thermal::implementation
102