• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2021-2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "action_thermal_level.h"
17 
18 #include <common_event_data.h>
19 #include <common_event_manager.h>
20 #include <common_event_support.h>
21 #include <map>
22 
23 #include "constants.h"
24 #include "thermal_hisysevent.h"
25 #include "thermal_service.h"
26 #include "thermal_common.h"
27 #include "ffrt_utils.h"
28 
29 using namespace OHOS::AAFwk;
30 using namespace OHOS::EventFwk;
31 using namespace OHOS::HiviewDFX;
32 
33 namespace OHOS {
34 namespace PowerMgr {
35 namespace {
36 constexpr int32_t MIN_THERMAL_LEVEL = static_cast<int32_t>(ThermalLevel::COOL);
37 constexpr int32_t MAX_THERMAL_LEVEL = static_cast<int32_t>(ThermalLevel::ESCAPE);
38 }
39 int32_t ActionThermalLevel::lastValue_ = INT_MIN;
40 
ActionThermalLevel(const std::string & actionName)41 ActionThermalLevel::ActionThermalLevel(const std::string& actionName)
42 {
43     actionName_ = actionName;
44 }
45 
InitParams(const std::string & params)46 void ActionThermalLevel::InitParams(const std::string& params)
47 {
48     if (thermalLevelCBDeathRecipient_ == nullptr) {
49         thermalLevelCBDeathRecipient_ = new ThermalLevelCallbackDeathRecipient();
50     }
51 }
52 
SetStrict(bool enable)53 void ActionThermalLevel::SetStrict(bool enable)
54 {
55     isStrict_ = enable;
56 }
57 
SetEnableEvent(bool enable)58 void ActionThermalLevel::SetEnableEvent(bool enable)
59 {
60     enableEvent_ = enable;
61 }
62 
AddActionValue(uint32_t actionId,std::string value)63 void ActionThermalLevel::AddActionValue(uint32_t actionId, std::string value)
64 {
65     if (value.empty()) {
66         return;
67     }
68     if (actionId > 0) {
69         auto iter = policyActionMap_.find(actionId);
70         if (iter != policyActionMap_.end()) {
71             iter->second.uintDelayValue = static_cast<uint32_t>(static_cast<uint32_t>(strtol(value.c_str(),
72                 nullptr, STRTOL_FORMART_DEC)));
73         }
74     } else {
75         valueList_.push_back(static_cast<uint32_t>(strtol(value.c_str(), nullptr, STRTOL_FORMART_DEC)));
76     }
77 }
78 
ExecuteInner()79 void ActionThermalLevel::ExecuteInner()
80 {
81     auto tms = ThermalService::GetInstance();
82     THERMAL_RETURN_IF (tms == nullptr);
83     for (auto &policyAction : policyActionMap_) {
84         if (policyAction.second.isCompleted) {
85             valueList_.push_back(policyAction.second.uintDelayValue);
86         }
87     }
88 
89     int32_t value = GetActionValue();
90     if (value != lastValue_) {
91         THERMAL_HILOGI(COMP_SVC, "thermal level changed, new lev: %{public}d, old lev: %{public}d", value, lastValue_);
92         lastValue_ = value;
93         LevelRequest(value);
94         WriteActionTriggeredHiSysEvent(enableEvent_, actionName_, value);
95         tms->GetObserver()->SetDecisionValue(actionName_, std::to_string(value));
96         THERMAL_HILOGD(COMP_SVC, "action execute: {%{public}s = %{public}u}", actionName_.c_str(), lastValue_);
97     }
98     valueList_.clear();
99 }
100 
ResetActionValue()101 void ActionThermalLevel::ResetActionValue()
102 {
103     lastValue_ = INT_MIN;
104 }
105 
GetActionValue()106 int32_t ActionThermalLevel::GetActionValue()
107 {
108     uint32_t value = MIN_THERMAL_LEVEL;
109     if (!valueList_.empty()) {
110         if (isStrict_) {
111             value = *min_element(valueList_.begin(), valueList_.end());
112         } else {
113             value = *max_element(valueList_.begin(), valueList_.end());
114         }
115     }
116     return value;
117 }
118 
GetThermalLevel()119 int32_t ActionThermalLevel::GetThermalLevel()
120 {
121     return lastValue_;
122 }
123 
LevelRequest(int32_t level)124 void ActionThermalLevel::LevelRequest(int32_t level)
125 {
126     if (level > MAX_THERMAL_LEVEL) {
127         level = MAX_THERMAL_LEVEL;
128     }
129     if (level < MIN_THERMAL_LEVEL) {
130         level = MIN_THERMAL_LEVEL;
131     }
132     NotifyThermalLevelChanged(level);
133 }
134 
SubscribeThermalLevelCallback(const sptr<IThermalLevelCallback> & callback)135 void ActionThermalLevel::SubscribeThermalLevelCallback(const sptr<IThermalLevelCallback>& callback)
136 {
137     std::lock_guard lock(mutex_);
138     THERMAL_RETURN_IF(callback == nullptr);
139     auto object = callback->AsObject();
140     THERMAL_RETURN_IF(object == nullptr);
141     auto retIt = thermalLevelListeners_.insert(callback);
142     if (retIt.second) {
143         object->AddDeathRecipient(thermalLevelCBDeathRecipient_);
144         callback->OnThermalLevelChanged(static_cast<ThermalLevel>(lastValue_));
145     }
146     THERMAL_HILOGI(COMP_SVC, "listeners.size=%{public}zu, insertOk=%{public}d",
147         thermalLevelListeners_.size(), retIt.second);
148 }
149 
UnSubscribeThermalLevelCallback(const sptr<IThermalLevelCallback> & callback)150 void ActionThermalLevel::UnSubscribeThermalLevelCallback(const sptr<IThermalLevelCallback>& callback)
151 {
152     std::lock_guard lock(mutex_);
153     THERMAL_RETURN_IF(callback == nullptr);
154     auto object = callback->AsObject();
155     THERMAL_RETURN_IF(object == nullptr);
156     size_t eraseNum = thermalLevelListeners_.erase(callback);
157     if (eraseNum != 0) {
158         object->RemoveDeathRecipient(thermalLevelCBDeathRecipient_);
159     }
160     THERMAL_HILOGI(COMP_SVC, "listeners.size=%{public}zu, eraseNum=%{public}zu",
161         thermalLevelListeners_.size(), eraseNum);
162 }
163 
OnRemoteDied(const wptr<IRemoteObject> & remote)164 void ActionThermalLevel::ThermalLevelCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
165 {
166     if (remote == nullptr || remote.promote() == nullptr) {
167         return;
168     }
169     auto tms = ThermalService::GetInstance();
170     if (tms == nullptr) {
171         return;
172     }
173     sptr<IThermalLevelCallback> callback = iface_cast<IThermalLevelCallback>(remote.promote());
174     FFRTTask task = [tms, callback] { tms->UnSubscribeThermalLevelCallback(callback); };
175     FFRTUtils::SubmitTask(task);
176 }
177 
NotifyThermalLevelChanged(int32_t level)178 void ActionThermalLevel::NotifyThermalLevelChanged(int32_t level)
179 {
180     // Send Notification event
181     PublishLevelChangedEvents(ThermalCommonEventCode::CODE_THERMAL_LEVEL_CHANGED, level);
182 
183     // Call back all level listeners
184     std::lock_guard lock(mutex_);
185     for (auto& listener : thermalLevelListeners_) {
186         listener->OnThermalLevelChanged(static_cast<ThermalLevel>(level));
187     }
188 
189     // Notify thermal level change event to battery statistics
190     WriteLevelChangedHiSysEvent(enableEvent_, level);
191 }
192 
PublishLevelChangedEvents(ThermalCommonEventCode code,int32_t level)193 bool ActionThermalLevel::PublishLevelChangedEvents(ThermalCommonEventCode code, int32_t level)
194 {
195     Want want;
196     want.SetParam(ToString(static_cast<int32_t>(code)), level);
197     want.SetAction(CommonEventSupport::COMMON_EVENT_THERMAL_LEVEL_CHANGED);
198     CommonEventData commonData;
199     commonData.SetWant(want);
200     CommonEventPublishInfo publishInfo;
201     publishInfo.SetOrdered(false);
202     if (!CommonEventManager::PublishCommonEvent(commonData, publishInfo)) {
203         THERMAL_HILOGE(COMP_SVC, "failed to publish thermal level change event");
204         return false;
205     }
206     return true;
207 }
208 } // namespace PowerMgr
209 } // namespace OHOS
210