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