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 <cJSON.h>
17 #include "power_cjson_utils.h"
18 #include "power_mode_policy.h"
19 #include "power_mgr_service.h"
20 #include "power_log.h"
21 #include "power_save_mode.h"
22 #include "singleton.h"
23 #include "setting_helper.h"
24 using namespace std;
25
26 namespace OHOS {
27 namespace PowerMgr {
28 constexpr int32_t KEY_BASE = 10;
29
GetPowerModeValuePolicy(uint32_t type)30 int32_t PowerModePolicy::GetPowerModeValuePolicy(uint32_t type)
31 {
32 int32_t ret = INIT_VALUE_FALSE;
33 if (IsValidType(type)) {
34 ret = GetPolicyFromMap(type);
35 }
36
37 return ret;
38 }
39
GetPolicyFromMap(uint32_t type)40 int32_t PowerModePolicy::GetPolicyFromMap(uint32_t type)
41 {
42 int32_t ret = INIT_VALUE_FALSE;
43 std::lock_guard<std::mutex> lock(policyMutex_);
44 auto iter = switchMap_.find(type);
45 if (iter != switchMap_.end()) {
46 ret = iter->second;
47 }
48 return ret;
49 }
50
UpdatePowerModePolicy(uint32_t mode)51 void PowerModePolicy::UpdatePowerModePolicy(uint32_t mode)
52 {
53 POWER_HILOGD(FEATURE_POWER_MODE, "update mode policy, mode=%{public}d", mode);
54 ReadPowerModePolicy(mode);
55 ComparePowerModePolicy();
56 }
57
ComparePowerModePolicy()58 void PowerModePolicy::ComparePowerModePolicy()
59 {
60 std::lock_guard<std::mutex> lock(policyMutex_);
61 for (auto [id, value] : recoverMap_) {
62 if (switchMap_.find(id) != switchMap_.end()) {
63 backupMap_[id] = value;
64 }
65 switchMap_.emplace(id, value);
66 }
67 recoverMap_ = backupMap_;
68 SavePowerModeRecoverMap();
69 }
70
InitRecoverMap()71 bool PowerModePolicy::InitRecoverMap()
72 {
73 std::string jsonStr = SettingHelper::ReadPowerModeRecoverMap();
74 if (!ParseRecoverJson(jsonStr)) {
75 POWER_HILOGI(FEATURE_POWER_MODE, "init recover map error");
76 return false;
77 }
78 POWER_HILOGI(FEATURE_POWER_MODE, "init recover map succeed");
79 return true;
80 }
81
ParseRecoverJson(std::string & jsonStr)82 bool PowerModePolicy::ParseRecoverJson(std::string& jsonStr)
83 {
84 cJSON* recoverJson = cJSON_Parse(jsonStr.c_str());
85 if (!recoverJson) {
86 POWER_HILOGW(FEATURE_POWER_MODE, "parse recover json str error");
87 return false;
88 }
89 if (!PowerMgrJsonUtils::IsValidJsonObjectOrJsonArray(recoverJson)) {
90 POWER_HILOGW(FEATURE_POWER_MODE, "recover json root is not object or array , string:%{public}s",
91 jsonStr.c_str());
92 cJSON_Delete(recoverJson);
93 return false;
94 }
95 cJSON* item = nullptr;
96 cJSON_ArrayForEach(item, recoverJson) {
97 const char* keyStr = item->string;
98 if (!keyStr || !PowerMgrJsonUtils::IsValidJsonNumber(item)) {
99 continue;
100 }
101 errno = 0;
102 char* endptr = nullptr;
103 int32_t key = static_cast<int32_t>(strtol(keyStr, &endptr, KEY_BASE));
104 if (endptr == keyStr) {
105 POWER_HILOGW(FEATURE_POWER_MODE, "String have no numbers, string:%{public}s", keyStr);
106 continue;
107 }
108 if (errno == ERANGE && (key == INT_MAX || key == INT_MIN)) {
109 POWER_HILOGW(FEATURE_POWER_MODE, "Transit result out of range, string:%{public}s", keyStr);
110 continue;
111 }
112 if (endptr == nullptr || *endptr != '\0') {
113 POWER_HILOGW(FEATURE_POWER_MODE, "String contain non-numeric characters, string:%{public}s", keyStr);
114 continue;
115 }
116 int32_t value = static_cast<int32_t>(item->valueint);
117 recoverMap_[key] = value;
118 }
119
120 cJSON_Delete(recoverJson);
121 return true;
122 }
123
ReadPowerModePolicy(uint32_t mode)124 void PowerModePolicy::ReadPowerModePolicy(uint32_t mode)
125 {
126 auto policyCache = DelayedSpSingleton<PowerSaveMode>::GetInstance()->GetPolicyCache();
127 if (policyCache.empty()) {
128 POWER_HILOGD(FEATURE_POWER_MODE, "config policy cache is empty");
129 return;
130 }
131
132 switchMap_.clear();
133 backupMap_.clear();
134 for (auto [id, value, flag] : policyCache[mode]) {
135 switchMap_[id] = value;
136 POWER_HILOGD(FEATURE_POWER_MODE, "read switch id: %{public}d, value: %{public}d", id, value);
137 if (flag == ValueProp::recover) {
138 GetSettingSwitchState(id, backupMap_[id]);
139 }
140 }
141 }
142
GetSettingDisplayOffTime(int64_t defaultVal)143 int64_t PowerModePolicy::GetSettingDisplayOffTime(int64_t defaultVal)
144 {
145 auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
146 if (pms == nullptr) {
147 POWER_HILOGE(FEATURE_POWER_MODE, "get PowerMgrService fail");
148 return defaultVal;
149 }
150 return pms->GetSettingDisplayOffTime(defaultVal);
151 }
152
GetSettingSwitchState(uint32_t & switchId,int32_t & value)153 void PowerModePolicy::GetSettingSwitchState(uint32_t& switchId, int32_t& value)
154 {
155 int32_t defaultVal = INIT_VALUE_FALSE;
156 switch (switchId) {
157 case PowerModePolicy::ServiceType::AUTO_ADJUST_BRIGHTNESS:
158 defaultVal = SettingHelper::GetSettingAutoAdjustBrightness(defaultVal);
159 break;
160 case PowerModePolicy::ServiceType::AUTO_WINDOWN_RORATION:
161 defaultVal = SettingHelper::GetSettingWindowRotation(defaultVal);
162 break;
163 case PowerModePolicy::ServiceType::VIBRATORS_STATE:
164 defaultVal = SettingHelper::GetSettingVibration(defaultVal);
165 break;
166 case PowerModePolicy::ServiceType::INTELL_VOICE:
167 defaultVal = SettingHelper::GetSettingIntellVoice(defaultVal);
168 break;
169 case PowerModePolicy::ServiceType::DISPLAY_OFFTIME: {
170 int64_t displayOfftime = GetSettingDisplayOffTime(static_cast<int64_t>(defaultVal));
171 defaultVal = static_cast<int32_t>(displayOfftime);
172 break;
173 }
174 default:
175 break;
176 }
177
178 if (defaultVal == INIT_VALUE_FALSE) {
179 POWER_HILOGW(FEATURE_POWER_MODE, "get setting state invalid, switch id: %{public}d", switchId);
180 return;
181 }
182 value = defaultVal;
183 POWER_HILOGD(FEATURE_POWER_MODE, "read switch id: %{public}d, switch value: %{public}d", switchId, value);
184 }
185
AddAction(uint32_t type,ModeAction & action)186 void PowerModePolicy::AddAction(uint32_t type, ModeAction& action)
187 {
188 POWER_HILOGD(FEATURE_POWER_MODE, "add action, type=%{public}d", type);
189 std::lock_guard<std::mutex> lock(actionMapMutex_);
190 actionMap_.emplace(type, action);
191 }
192
TriggerAllActions(bool isBoot)193 void PowerModePolicy::TriggerAllActions(bool isBoot)
194 {
195 std::vector<ModeAction> allActions;
196 {
197 std::lock_guard<std::mutex> lock(actionMapMutex_);
198 for (auto iterator = actionMap_.begin(); iterator != actionMap_.end(); iterator++) {
199 POWER_HILOGD(FEATURE_POWER_MODE, "trigger action, type=%{public}d", iterator->first);
200 allActions.emplace_back(iterator->second);
201 }
202 }
203 for (const auto &actions : allActions) {
204 actions(isBoot);
205 }
206 }
207
IsValidType(uint32_t type)208 bool PowerModePolicy::IsValidType(uint32_t type)
209 {
210 std::lock_guard<std::mutex> lock(actionMapMutex_);
211 auto iterator = actionMap_.find(type);
212 if (iterator == actionMap_.end()) {
213 POWER_HILOGW(FEATURE_POWER_MODE, "Invalid type: %{public}d", type);
214 return false;
215 }
216 return true;
217 }
218
RemoveBackupMapSettingSwitch(uint32_t switchId)219 void PowerModePolicy::RemoveBackupMapSettingSwitch(uint32_t switchId)
220 {
221 auto iter = recoverMap_.find(switchId);
222 if (iter != recoverMap_.end()) {
223 recoverMap_.erase(iter);
224 SavePowerModeRecoverMap();
225 POWER_HILOGW(FEATURE_POWER_MODE, "remove backup switch: %{public}d", switchId);
226 }
227 }
228
SavePowerModeRecoverMap()229 void PowerModePolicy::SavePowerModeRecoverMap()
230 {
231 cJSON* recoverJson = cJSON_CreateObject();
232 if (!recoverJson) {
233 POWER_HILOGE(FEATURE_POWER_MODE, "Failed to create cJSON object");
234 return;
235 }
236
237 for (const auto& pair : recoverMap_) {
238 std::string keyStr = std::to_string(pair.first);
239 if (cJSON_AddNumberToObject(recoverJson, keyStr.c_str(), pair.second) == nullptr) {
240 POWER_HILOGE(FEATURE_POWER_MODE, "Failed to add %{public}s to recoverJson object", keyStr.c_str());
241 }
242 }
243
244 char* jsonStr = cJSON_Print(recoverJson);
245 if (!jsonStr) {
246 POWER_HILOGE(FEATURE_POWER_MODE, "Failed to print cJSON to string");
247 cJSON_Delete(recoverJson);
248 return;
249 }
250 std::string jsonConfig = std::string(jsonStr);
251 SettingHelper::SavePowerModeRecoverMap(jsonConfig);
252 cJSON_free(jsonStr);
253 cJSON_Delete(recoverJson);
254 }
255 } // namespace PowerMgr
256 } // namespace OHOS
257