• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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