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