• 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 const char* TASK_UNREG_THERMAL_LEVEL_CALLBACK = "ThermalLevel_UnRegThermalLevelpCB";
37 constexpr int32_t MAX_THERMAL_LEVEL = static_cast<int32_t>(ThermalLevel::ESCAPE);
38 auto g_service = DelayedSpSingleton<ThermalService>::GetInstance();
39 }
40 int32_t ActionThermalLevel::level_ = static_cast<int32_t>(ThermalLevel::COOL);
41 std::set<const sptr<IThermalLevelCallback>, ActionThermalLevel::classcomp> ActionThermalLevel::thermalLevelListeners_;
42 
ActionThermalLevel(const wptr<ThermalService> & tms)43 ActionThermalLevel::ActionThermalLevel(const wptr<ThermalService>& tms) : tms_(tms), lastValue_(0) {}
~ActionThermalLevel()44 ActionThermalLevel::~ActionThermalLevel() {}
45 
ActionThermalLevel(const std::string & actionName)46 ActionThermalLevel::ActionThermalLevel(const std::string& actionName)
47 {
48     actionName_ = actionName;
49 }
50 
InitParams(const std::string & params)51 void ActionThermalLevel::InitParams(const std::string& params)
52 {
53     if (thermalLevelCBDeathRecipient_ == nullptr) {
54         thermalLevelCBDeathRecipient_ = new ThermalLevelCallbackDeathRecipient();
55     }
56 }
57 
SetStrict(bool enable)58 void ActionThermalLevel::SetStrict(bool enable)
59 {
60     isStrict_ = enable;
61 }
62 
SetEnableEvent(bool enable)63 void ActionThermalLevel::SetEnableEvent(bool enable)
64 {
65     enableEvent_ = enable;
66 }
67 
AddActionValue(std::string value)68 void ActionThermalLevel::AddActionValue(std::string value)
69 {
70     if (value.empty()) {
71         return;
72     }
73     valueList_.push_back(static_cast<uint32_t>(strtol(value.c_str(), nullptr, STRTOL_FORMART_DEC)));
74 }
75 
Execute()76 void ActionThermalLevel::Execute()
77 {
78     THERMAL_RETURN_IF (g_service == nullptr);
79     uint32_t value = GetActionValue();
80     if (value != lastValue_) {
81         LevelRequest(value);
82         WriteActionTriggeredHiSysEvent(enableEvent_, actionName_, value);
83         g_service->GetObserver()->SetDecisionValue(actionName_, std::to_string(value));
84         lastValue_ = value;
85         THERMAL_HILOGD(COMP_SVC, "action execute: {%{public}s = %{public}u}", actionName_.c_str(), lastValue_);
86     }
87     valueList_.clear();
88 }
89 
GetActionValue()90 uint32_t ActionThermalLevel::GetActionValue()
91 {
92     std::string scene = g_service->GetScene();
93     auto iter = g_sceneMap.find(scene);
94     if (iter != g_sceneMap.end()) {
95         return static_cast<uint32_t>(strtol(iter->second.c_str(), nullptr, STRTOL_FORMART_DEC));
96     }
97     uint32_t value = FALLBACK_VALUE_UINT_ZERO;
98     if (!valueList_.empty()) {
99         if (isStrict_) {
100             value = *min_element(valueList_.begin(), valueList_.end());
101         } else {
102             value = *max_element(valueList_.begin(), valueList_.end());
103         }
104     }
105     return value;
106 }
107 
GetThermalLevel()108 int32_t ActionThermalLevel::GetThermalLevel()
109 {
110     return level_;
111 }
112 
LevelRequest(int32_t level)113 uint32_t ActionThermalLevel::LevelRequest(int32_t level)
114 {
115     if (level > MAX_THERMAL_LEVEL) {
116         level = MAX_THERMAL_LEVEL;
117     }
118     if (level_ != level) {
119         NotifyThermalLevelChanged(level);
120     }
121     return ERR_OK;
122 }
123 
124 /**
125  * @brief Callback of subscription temp level
126  *
127  * @param callback Thermal level callback object
128  */
SubscribeThermalLevelCallback(const sptr<IThermalLevelCallback> & callback)129 void ActionThermalLevel::SubscribeThermalLevelCallback(const sptr<IThermalLevelCallback>& callback)
130 {
131     std::lock_guard lock(mutex_);
132     THERMAL_RETURN_IF(callback == nullptr);
133     auto object = callback->AsObject();
134     THERMAL_RETURN_IF(object == nullptr);
135     auto retIt = thermalLevelListeners_.insert(callback);
136     if (retIt.second) {
137         object->AddDeathRecipient(thermalLevelCBDeathRecipient_);
138         callback->OnThermalLevelChanged(static_cast<ThermalLevel>(level_));
139     }
140     THERMAL_HILOGI(COMP_SVC, "listeners.size=%{public}d, insertOk=%{public}d",
141         static_cast<unsigned int>(thermalLevelListeners_.size()), retIt.second);
142 }
143 
UnSubscribeThermalLevelCallback(const sptr<IThermalLevelCallback> & callback)144 void ActionThermalLevel::UnSubscribeThermalLevelCallback(const sptr<IThermalLevelCallback>& callback)
145 {
146     std::lock_guard lock(mutex_);
147     THERMAL_RETURN_IF(callback == nullptr);
148     auto object = callback->AsObject();
149     THERMAL_RETURN_IF(object == nullptr);
150     size_t eraseNum = thermalLevelListeners_.erase(callback);
151     if (eraseNum != 0) {
152         object->RemoveDeathRecipient(thermalLevelCBDeathRecipient_);
153     }
154     THERMAL_HILOGI(COMP_SVC, "listeners.size=%{public}d, eraseNum=%{public}zu",
155         static_cast<unsigned int>(thermalLevelListeners_.size()), eraseNum);
156 }
157 
OnRemoteDied(const wptr<IRemoteObject> & remote)158 void ActionThermalLevel::ThermalLevelCallbackDeathRecipient::OnRemoteDied(const wptr<IRemoteObject>& remote)
159 {
160     if (remote == nullptr || remote.promote() == nullptr) {
161         return;
162     }
163     auto tms = DelayedSpSingleton<ThermalService>::GetInstance();
164     if (tms == nullptr) {
165         return;
166     }
167     sptr<IThermalLevelCallback> callback = iface_cast<IThermalLevelCallback>(remote.promote());
168     FFRTTask task = std::bind(&ThermalService::UnSubscribeThermalLevelCallback, tms, callback);
169     FFRTUtils::SubmitTask(task);
170 }
171 /**
172  * @brief notify level
173  *
174  * @param level
175  */
NotifyThermalLevelChanged(int32_t level)176 void ActionThermalLevel::NotifyThermalLevelChanged(int32_t level)
177 {
178     THERMAL_HILOGD(COMP_SVC, "level = %{public}d, listeners.size = %{public}d",
179         level, static_cast<unsigned int>(thermalLevelListeners_.size()));
180     THERMAL_HILOGI(COMP_SVC, "thermal level changed, new lev: %{public}d, old lev: %{public}d", level, level_);
181     level_ = level;
182 
183     // Send Notification event
184     PublishLevelChangedEvents(ThermalCommonEventCode::CODE_THERMAL_LEVEL_CHANGED, level_);
185 
186     // Call back all level listeners
187     std::lock_guard lock(mutex_);
188     for (auto& listener : thermalLevelListeners_) {
189         listener->OnThermalLevelChanged(static_cast<ThermalLevel>(level_));
190     }
191 
192     // Notify thermal level change event to battery statistics
193     WriteLevelChangedHiSysEvent(enableEvent_, level);
194 }
195 
PublishLevelChangedEvents(ThermalCommonEventCode code,int32_t level)196 bool ActionThermalLevel::PublishLevelChangedEvents(ThermalCommonEventCode code, int32_t level)
197 {
198     Want want;
199     want.SetParam(ToString(static_cast<int32_t>(code)), level);
200     want.SetAction(CommonEventSupport::COMMON_EVENT_THERMAL_LEVEL_CHANGED);
201     CommonEventData commonData;
202     commonData.SetWant(want);
203     CommonEventPublishInfo publishInfo;
204     publishInfo.SetOrdered(false);
205     if (!CommonEventManager::PublishCommonEvent(commonData, publishInfo)) {
206         THERMAL_HILOGE(COMP_SVC, "failed to publish thermal level change event");
207         return false;
208     }
209     return true;
210 }
211 } // namespace PowerMgr
212 } // namespace OHOS
213