• 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 <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