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