• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "suspend_source_parser.h"
16 
17 #include <fstream>
18 #include <securec.h>
19 #include <unistd.h>
20 
21 #include <cJSON.h>
22 
23 #include "config_policy_utils.h"
24 #include "power_cjson_utils.h"
25 #include "power_log.h"
26 #include "setting_helper.h"
27 #ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING
28 #include "power_mgr_service.h"
29 #endif
30 
31 namespace OHOS {
32 namespace PowerMgr {
33 
34 namespace {
35 static const std::string POWER_SUSPEND_CONFIG_FILE = "etc/power_config/power_suspend.json";
36 static const std::string VENDOR_POWER_SUSPEND_CONFIG_FILE = "/vendor/etc/power_config/power_suspend.json";
37 static const std::string SYSTEM_POWER_SUSPEND_CONFIG_FILE = "/system/etc/power_config/power_suspend.json";
38 static const uint32_t ILLEGAL_ACTION = static_cast<uint32_t>(SuspendAction::ACTION_INVALID);
39 } // namespace
40 
41 #ifdef POWER_MANAGER_ENABLE_CHARGING_TYPE_SETTING
ParseSources()42 std::shared_ptr<SuspendSources> SuspendSourceParser::ParseSources()
43 {
44     std::shared_ptr<SuspendSources> parseSources{nullptr};
45     auto pms = DelayedSpSingleton<PowerMgrService>::GetInstance();
46     if (pms == nullptr) {
47         POWER_HILOGE(FEATURE_SUSPEND, "get PowerMgrService fail");
48         return parseSources;
49     }
50     bool isPowerConnected = pms->IsPowerConnected();
51     bool isSettingAcValid = SettingHelper::IsSettingAcSuspendSourcesValid();
52     bool isSettingDcValid = SettingHelper::IsSettingDcSuspendSourcesValid();
53     std::string configJsonStr;
54 
55     if (!isSettingAcValid || !isSettingDcValid) {
56         std::string fileStringStr = GetSuspendSourcesByConfig();
57 
58         if (!isSettingAcValid) {
59             SettingHelper::SetSettingAcSuspendSources(fileStringStr);
60         }
61         if (!isSettingDcValid) {
62             SettingHelper::SetSettingDcSuspendSources(fileStringStr);
63         }
64         configJsonStr = fileStringStr;
65     }
66 
67     if (isPowerConnected && isSettingAcValid) {
68         configJsonStr = SettingHelper::GetSettingAcSuspendSources();
69     } else if (!isPowerConnected && isSettingDcValid) {
70         configJsonStr = SettingHelper::GetSettingDcSuspendSources();
71     }
72 
73     parseSources = ParseSources(configJsonStr);
74     if (parseSources->GetParseErrorFlag()) {
75         POWER_HILOGI(FEATURE_SUSPEND, "call GetSuspendSourcesByConfig again");
76         configJsonStr = GetSuspendSourcesByConfig();
77         parseSources = ParseSources(configJsonStr);
78     }
79     return parseSources;
80 }
81 #else
ParseSources()82 std::shared_ptr<SuspendSources> SuspendSourceParser::ParseSources()
83 {
84     std::shared_ptr<SuspendSources> parseSources{nullptr};
85     bool isSettingUpdated = SettingHelper::IsSuspendSourcesSettingValid();
86     POWER_HILOGI(FEATURE_SUSPEND, "ParseSources setting=%{public}d", isSettingUpdated);
87     std::string configJsonStr;
88     if (isSettingUpdated) {
89         std::string sourcesSettingStr = SettingHelper::GetSettingSuspendSources();
90         configJsonStr = sourcesSettingStr;
91 #ifdef POWER_MANAGER_ENABLE_WATCH_UPDATE_ADAPT
92         // this branch means use config file for update scene in watch
93         if (sourcesSettingStr.find(SuspendSources::TP_COVER_KEY) == std::string::npos) {
94             configJsonStr = GetSuspendSourcesByConfig();
95             POWER_HILOGW(FEATURE_SUSPEND, "update scene need use (config file)");
96         }
97 #endif
98     } else {
99         configJsonStr = GetSuspendSourcesByConfig();
100     }
101     parseSources = ParseSources(configJsonStr);
102     if (parseSources->GetParseErrorFlag()) {
103         POWER_HILOGI(FEATURE_SUSPEND, "call GetSuspendSourcesByConfig again");
104         configJsonStr = GetSuspendSourcesByConfig();
105         parseSources = ParseSources(configJsonStr);
106     }
107     if (parseSources != nullptr) {
108         SettingHelper::SetSettingSuspendSources(configJsonStr);
109     }
110     return parseSources;
111 }
112 #endif
113 
GetSuspendSourcesByConfig()114 const std::string SuspendSourceParser::GetSuspendSourcesByConfig()
115 {
116     std::string targetPath;
117     bool ret = GetTargetPath(targetPath);
118     if (ret == false) {
119         POWER_HILOGE(FEATURE_SUSPEND, "GetTargetPath fail");
120         return "";
121     }
122     POWER_HILOGI(FEATURE_SUSPEND, "use targetPath=%{public}s", targetPath.c_str());
123     std::ifstream inputStream(targetPath.c_str(), std::ios::in | std::ios::binary);
124     return std::string(std::istreambuf_iterator<char> {inputStream}, std::istreambuf_iterator<char> {});
125 }
126 
GetTargetPath(std::string & targetPath)127 bool SuspendSourceParser::GetTargetPath(std::string& targetPath)
128 {
129     targetPath.clear();
130     bool ret = true;
131     char buf[MAX_PATH_LEN];
132     char* path = GetOneCfgFile(POWER_SUSPEND_CONFIG_FILE.c_str(), buf, MAX_PATH_LEN);
133     if (path != nullptr && *path != '\0') {
134         POWER_HILOGI(FEATURE_SUSPEND, "use policy path=%{public}s", path);
135         targetPath = path;
136         return true;
137     }
138 
139     if (access(VENDOR_POWER_SUSPEND_CONFIG_FILE.c_str(), F_OK | R_OK) == -1) {
140         POWER_HILOGE(FEATURE_SUSPEND, "vendor suspend config is not exist or permission denied");
141         if (access(SYSTEM_POWER_SUSPEND_CONFIG_FILE.c_str(), F_OK | R_OK) == -1) {
142             POWER_HILOGE(FEATURE_SUSPEND, "system suspend config is not exist or permission denied");
143             ret = false;
144         } else {
145             targetPath = SYSTEM_POWER_SUSPEND_CONFIG_FILE;
146         }
147     } else {
148         targetPath = VENDOR_POWER_SUSPEND_CONFIG_FILE;
149     }
150     return ret;
151 }
152 
ParseSources(const std::string & jsonStr)153 std::shared_ptr<SuspendSources> SuspendSourceParser::ParseSources(const std::string& jsonStr)
154 {
155     std::shared_ptr<SuspendSources> parseSources = std::make_shared<SuspendSources>();
156     cJSON* root = cJSON_Parse(jsonStr.c_str());
157     if (!root) {
158         POWER_HILOGE(FEATURE_SUSPEND, "json parse error");
159         parseSources->SetParseErrorFlag(true);
160         return parseSources;
161     }
162     if (!PowerMgrJsonUtils::IsValidJsonObjectOrJsonArray(root)) {
163         POWER_HILOGE(FEATURE_SUSPEND, "json root invalid[%{public}s]", jsonStr.c_str());
164         parseSources->SetParseErrorFlag(true);
165         cJSON_Delete(root);
166         return parseSources;
167     }
168 
169     cJSON* item = nullptr;
170     cJSON_ArrayForEach(item, root) {
171         const char* key = item->string;
172         if (!key) {
173             POWER_HILOGI(FEATURE_SUSPEND, "invalid key in json object");
174             continue;
175         }
176         std::string keyStr = std::string(key);
177         bool ret = ParseSourcesProc(parseSources, item, keyStr);
178         if (ret == false) {
179             POWER_HILOGI(FEATURE_SUSPEND, "lost map config key");
180             continue;
181         }
182     }
183 
184     cJSON_Delete(root);
185     return parseSources;
186 }
187 
ParseSourcesProc(std::shared_ptr<SuspendSources> & parseSources,cJSON * valueObj,std::string & key)188 bool SuspendSourceParser::ParseSourcesProc(
189     std::shared_ptr<SuspendSources>& parseSources, cJSON* valueObj, std::string& key)
190 {
191     if (parseSources == nullptr) {
192         POWER_HILOGE(FEATURE_SUSPEND, "parseSources is nullptr");
193         return false;
194     }
195 
196     SuspendDeviceType suspendDeviceType = SuspendSources::mapSuspendDeviceType(key);
197     if (suspendDeviceType == SuspendDeviceType::SUSPEND_DEVICE_REASON_MIN) {
198         return false;
199     }
200 
201     uint32_t action = 0;
202     uint32_t delayMs = 0;
203     if (PowerMgrJsonUtils::IsValidJsonObject(valueObj)) {
204         cJSON* actionValue = cJSON_GetObjectItemCaseSensitive(valueObj, SuspendSource::ACTION_KEY);
205         cJSON* delayValue = cJSON_GetObjectItemCaseSensitive(valueObj, SuspendSource::DELAY_KEY);
206         if (PowerMgrJsonUtils::IsValidJsonNumber(actionValue) && PowerMgrJsonUtils::IsValidJsonNumber(delayValue)) {
207             action = static_cast<uint32_t>(actionValue->valueint);
208             delayMs = static_cast<uint32_t>(delayValue->valueint);
209             if (action >= ILLEGAL_ACTION) {
210                 action = 0;
211             }
212         }
213     }
214 
215     POWER_HILOGI(FEATURE_SUSPEND,
216         "ParseSourcesProc key=%{public}s, type=%{public}u, action=%{public}u, delayMs=%{public}u",
217         key.c_str(), suspendDeviceType, action, delayMs);
218     SuspendSource suspendSource = SuspendSource(suspendDeviceType, action, delayMs);
219     parseSources->PutSource(suspendSource);
220     return true;
221 }
222 
223 } // namespace PowerMgr
224 } // namespace OHOS