• 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         tms->GetObserver()->SetDecisionValue(actionName_, std::to_string(value));
95         THERMAL_HILOGD(COMP_SVC, "action execute: {%{public}s = %{public}u}", actionName_.c_str(), lastValue_);
96     }
97     valueList_.clear();
98 }
99 
ResetActionValue()100 void ActionThermalLevel::ResetActionValue()
101 {
102     lastValue_ = INT_MIN;
103 }
104 
GetActionValue()105 int32_t ActionThermalLevel::GetActionValue()
106 {
107     uint32_t value = MIN_THERMAL_LEVEL;
108     if (!valueList_.empty()) {
109         if (isStrict_) {
110             value = *min_element(valueList_.begin(), valueList_.end());
111         } else {
112             value = *max_element(valueList_.begin(), valueList_.end());
113         }
114     }
115     return value;
116 }
117 
GetThermalLevel()118 int32_t ActionThermalLevel::GetThermalLevel()
119 {
120     return lastValue_;
121 }
122 
LevelRequest(int32_t level)123 void ActionThermalLevel::LevelRequest(int32_t level)
124 {
125     if (level > MAX_THERMAL_LEVEL) {
126         level = MAX_THERMAL_LEVEL;
127     }
128     if (level < MIN_THERMAL_LEVEL) {
129         level = MIN_THERMAL_LEVEL;
130     }
131     NotifyThermalLevelChanged(level);
132 }
133 
SubscribeThermalLevelCallback(const sptr<IThermalLevelCallback> & callback)134 void ActionThermalLevel::SubscribeThermalLevelCallback(const sptr<IThermalLevelCallback>& callback)
135 {
136     std::lock_guard lock(mutex_);
137     THERMAL_RETURN_IF(callback == nullptr);
138     auto object = callback->AsObject();
139     THERMAL_RETURN_IF(object == nullptr);
140     auto retIt = thermalLevelListeners_.insert(callback);
141     if (retIt.second) {
142         object->AddDeathRecipient(thermalLevelCBDeathRecipient_);
143         callback->OnThermalLevelChanged(static_cast<ThermalLevel>(lastValue_));
144     }
145     THERMAL_HILOGI(COMP_SVC, "listeners.size=%{public}zu, insertOk=%{public}d",
146         thermalLevelListeners_.size(), retIt.second);
147 }
148 
UnSubscribeThermalLevelCallback(const sptr<IThermalLevelCallback> & callback)149 void ActionThermalLevel::UnSubscribeThermalLevelCallback(const sptr<IThermalLevelCallback>& callback)
150 {
151     std::lock_guard lock(mutex_);
152     THERMAL_RETURN_IF(callback == nullptr);
153     auto object = callback->AsObject();
154     THERMAL_RETURN_IF(object == nullptr);
155     size_t eraseNum = thermalLevelListeners_.erase(callback);
156     if (eraseNum != 0) {
157         object->RemoveDeathRecipient(thermalLevelCBDeathRecipient_);
158     }
159     THERMAL_HILOGI(COMP_SVC, "listeners.size=%{public}zu, eraseNum=%{public}zu",
160         thermalLevelListeners_.size(), eraseNum);
161 }
162 
OnRemoteDied(const wptr<IRemoteObject> & remote)163 void ActionThermalLevel::ThermalLevelCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
164 {
165     if (remote == nullptr || remote.promote() == nullptr) {
166         return;
167     }
168     auto tms = ThermalService::GetInstance();
169     if (tms == nullptr) {
170         return;
171     }
172     sptr<IThermalLevelCallback> callback = iface_cast<IThermalLevelCallback>(remote.promote());
173     FFRTTask task = [tms, callback] { tms->UnSubscribeThermalLevelCallback(callback); };
174     FFRTUtils::SubmitTask(task);
175 }
176 
NotifyThermalLevelChanged(int32_t level)177 void ActionThermalLevel::NotifyThermalLevelChanged(int32_t level)
178 {
179     // Send Notification event
180     PublishLevelChangedEvents(ThermalCommonEventCode::CODE_THERMAL_LEVEL_CHANGED, level);
181 
182     // Call back all level listeners
183     std::lock_guard lock(mutex_);
184     for (auto& listener : thermalLevelListeners_) {
185         listener->OnThermalLevelChanged(static_cast<ThermalLevel>(level));
186     }
187 }
188 
PublishLevelChangedEvents(ThermalCommonEventCode code,int32_t level)189 bool ActionThermalLevel::PublishLevelChangedEvents(ThermalCommonEventCode code, int32_t level)
190 {
191     Want want;
192     want.SetParam(ToString(static_cast<int32_t>(code)), level);
193     want.SetAction(CommonEventSupport::COMMON_EVENT_THERMAL_LEVEL_CHANGED);
194     CommonEventData commonData;
195     commonData.SetWant(want);
196     CommonEventPublishInfo publishInfo;
197     publishInfo.SetOrdered(false);
198     if (!CommonEventManager::PublishCommonEvent(commonData, publishInfo)) {
199         THERMAL_HILOGE(COMP_SVC, "failed to publish thermal level change event");
200         return false;
201     }
202     return true;
203 }
204 } // namespace PowerMgr
205 } // namespace OHOS
206