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
16 #include <fstream>
17 #include <unistd.h>
18
19 #include <cJSON.h>
20 #include "config_policy_utils.h"
21 #include "power_cjson_utils.h"
22 #include "power_log.h"
23 #include "setting_helper.h"
24 #include "wakeup_source_parser.h"
25
26 namespace OHOS {
27 namespace PowerMgr {
28
29 namespace {
30 static const std::string POWER_WAKEUP_CONFIG_FILE = "etc/power_config/power_wakeup.json";
31 static const std::string VENDOR_POWER_WAKEUP_CONFIG_FILE = "/vendor/etc/power_config/power_wakeup.json";
32 static const std::string SYSTEM_POWER_WAKEUP_CONFIG_FILE = "/system/etc/power_config/power_wakeup.json";
33 static const uint32_t SINGLE_CLICK = static_cast<uint32_t>(WakeUpAction::CLICK_SINGLE);
34 static const uint32_t DOUBLE_CLICK = static_cast<uint32_t>(WakeUpAction::CLICK_DOUBLE);
35 } // namespace
36 bool g_isFirstSettingUpdated = true;
37
ParseSources()38 std::shared_ptr<WakeupSources> WakeupSourceParser::ParseSources()
39 {
40 bool isWakeupSourcesSettingValid = SettingHelper::IsWakeupSourcesSettingValid();
41 POWER_HILOGI(FEATURE_WAKEUP, "ParseSources setting=%{public}d", isWakeupSourcesSettingValid);
42 std::string configJsonStr;
43 if (isWakeupSourcesSettingValid) {
44 std::string sourcesSettingStr = SettingHelper::GetSettingWakeupSources();
45 configJsonStr = sourcesSettingStr;
46 #ifdef POWER_MANAGER_ENABLE_WATCH_UPDATE_ADAPT
47 // this branch means use config file for update scene in watch
48 if (sourcesSettingStr.find(WakeupSources::TP_TOUCH_KEY) == std::string::npos) {
49 configJsonStr = GetWakeupSourcesByConfig();
50 POWER_HILOGW(FEATURE_WAKEUP, "update scene need use (config file)");
51 }
52 #endif
53 } else {
54 configJsonStr = GetWakeupSourcesByConfig();
55 }
56 g_isFirstSettingUpdated = true;
57 std::shared_ptr<WakeupSources> parseSources = ParseSources(configJsonStr);
58 if (parseSources->GetParseErrorFlag()) {
59 POWER_HILOGI(FEATURE_WAKEUP, "call GetWakeupSourcesByConfig again");
60 configJsonStr = GetWakeupSourcesByConfig();
61 parseSources = ParseSources(configJsonStr);
62 }
63 if (parseSources != nullptr) {
64 SettingHelper::SetSettingWakeupSources(configJsonStr);
65 }
66 g_isFirstSettingUpdated = false;
67 return parseSources;
68 }
69
GetWakeupSourcesByConfig()70 const std::string WakeupSourceParser::GetWakeupSourcesByConfig()
71 {
72 std::string targetPath;
73 bool ret = GetTargetPath(targetPath);
74 if (ret == false) {
75 return "";
76 }
77
78 POWER_HILOGI(FEATURE_WAKEUP, "use targetPath=%{public}s", targetPath.c_str());
79 std::ifstream inputStream(targetPath.c_str(), std::ios::in | std::ios::binary);
80 return std::string(std::istreambuf_iterator<char> {inputStream}, std::istreambuf_iterator<char> {});
81 }
82
GetTargetPath(std::string & targetPath)83 bool WakeupSourceParser::GetTargetPath(std::string& targetPath)
84 {
85 targetPath.clear();
86 char buf[MAX_PATH_LEN];
87 char* path = GetOneCfgFile(POWER_WAKEUP_CONFIG_FILE.c_str(), buf, MAX_PATH_LEN);
88 if (path != nullptr && *path != '\0') {
89 POWER_HILOGI(FEATURE_WAKEUP, "use policy path=%{public}s", path);
90 targetPath = path;
91 return true;
92 }
93
94 if (access(VENDOR_POWER_WAKEUP_CONFIG_FILE.c_str(), F_OK | R_OK) == -1) {
95 POWER_HILOGE(FEATURE_WAKEUP, "vendor wakeup config is not exist or permission denied");
96 if (access(SYSTEM_POWER_WAKEUP_CONFIG_FILE.c_str(), F_OK | R_OK) == -1) {
97 POWER_HILOGE(FEATURE_WAKEUP, "system wakeup config is not exist or permission denied");
98 return false;
99 } else {
100 targetPath = SYSTEM_POWER_WAKEUP_CONFIG_FILE;
101 }
102 } else {
103 targetPath = VENDOR_POWER_WAKEUP_CONFIG_FILE;
104 }
105
106 return true;
107 }
108
ParseSources(const std::string & jsonStr)109 std::shared_ptr<WakeupSources> WakeupSourceParser::ParseSources(const std::string& jsonStr)
110 {
111 std::shared_ptr<WakeupSources> parseSources = std::make_shared<WakeupSources>();
112 cJSON* root = cJSON_Parse(jsonStr.c_str());
113 if (!root) {
114 POWER_HILOGE(FEATURE_WAKEUP, "json parse error");
115 parseSources->SetParseErrorFlag(true);
116 return parseSources;
117 }
118
119 if (!PowerMgrJsonUtils::IsValidJsonObjectOrJsonArray(root)) {
120 POWER_HILOGE(FEATURE_WAKEUP, "json root invalid[%{public}s]", jsonStr.c_str());
121 parseSources->SetParseErrorFlag(true);
122 cJSON_Delete(root);
123 return parseSources;
124 }
125
126 cJSON* item = nullptr;
127 cJSON_ArrayForEach(item, root) {
128 const char* key = item->string;
129 if (!key) {
130 POWER_HILOGI(FEATURE_WAKEUP, "invalid key in json object");
131 continue;
132 }
133 std::string keyStr = std::string(key);
134 bool ret = ParseSourcesProc(parseSources, item, keyStr);
135 if (ret == false) {
136 POWER_HILOGI(FEATURE_WAKEUP, "lost map config key");
137 continue;
138 }
139 }
140
141 cJSON_Delete(root);
142 return parseSources;
143 }
144
ParseSourcesProc(std::shared_ptr<WakeupSources> & parseSources,cJSON * valueObj,std::string & key)145 bool WakeupSourceParser::ParseSourcesProc(
146 std::shared_ptr<WakeupSources>& parseSources, cJSON* valueObj, std::string& key)
147 {
148 bool enable = true;
149 uint32_t click = DOUBLE_CLICK;
150 WakeupDeviceType wakeupDeviceType = WakeupDeviceType::WAKEUP_DEVICE_UNKNOWN;
151 if (PowerMgrJsonUtils::IsValidJsonObject(valueObj)) {
152 cJSON* enableValue = cJSON_GetObjectItemCaseSensitive(valueObj, WakeupSource::ENABLE_KEY);
153 if (PowerMgrJsonUtils::IsValidJsonBool(enableValue)) {
154 enable = cJSON_IsTrue(enableValue);
155 }
156 cJSON* clickValue = cJSON_GetObjectItemCaseSensitive(valueObj, WakeupSource::KEYS_KEY);
157 if (PowerMgrJsonUtils::IsValidJsonNumber(clickValue)) {
158 uint32_t clickInt = static_cast<uint32_t>(clickValue->valueint);
159 click = (clickInt == SINGLE_CLICK || clickInt == DOUBLE_CLICK) ? clickInt : DOUBLE_CLICK;
160 }
161 }
162
163 wakeupDeviceType = WakeupSources::mapWakeupDeviceType(key, click);
164 POWER_HILOGI(FEATURE_WAKEUP, "key=%{public}s, type=%{public}u, click=%{public}u, enable=%{public}d",
165 key.c_str(), wakeupDeviceType, click, enable);
166
167 if (wakeupDeviceType == WakeupDeviceType::WAKEUP_DEVICE_UNKNOWN) {
168 return false;
169 }
170
171 if (!enable && g_isFirstSettingUpdated) {
172 if (wakeupDeviceType == WakeupDeviceType::WAKEUP_DEVICE_DOUBLE_CLICK
173 && (!SettingHelper::IsWakeupDoubleSettingValid())) {
174 SettingHelper::SetSettingWakeupDouble(enable);
175 POWER_HILOGI(FEATURE_WAKEUP, "the setting wakeupDoubleClick enable=%{public}d", enable);
176 }
177
178 if (wakeupDeviceType == WakeupDeviceType::WAKEUP_DEVICE_PICKUP
179 && (!SettingHelper::IsWakeupPickupSettingValid())) {
180 SettingHelper::SetSettingWakeupPickup(enable);
181 POWER_HILOGI(FEATURE_WAKEUP, "the setting pickup enable=%{public}d", enable);
182 }
183 }
184
185 if (enable == true) {
186 WakeupSource wakeupSource = WakeupSource(wakeupDeviceType, enable, click);
187 parseSources->PutSource(wakeupSource);
188 }
189
190 SetSettingsToDatabase(wakeupDeviceType, enable);
191 return true;
192 }
193
SetSettingsToDatabase(WakeupDeviceType type,bool enable)194 void WakeupSourceParser::SetSettingsToDatabase(WakeupDeviceType type, bool enable)
195 {
196 if (type == WakeupDeviceType::WAKEUP_DEVICE_LID) {
197 if (!SettingHelper::IsWakeupLidSettingValid()) {
198 SettingHelper::SetSettingWakeupLid(enable);
199 POWER_HILOGI(FEATURE_WAKEUP, "the setting lidwakeup enable=%{public}d", enable);
200 }
201 }
202 }
203 } // namespace PowerMgr
204 } // namespace OHOS