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 "config_policy_utils.h"
20 #include "power_log.h"
21 #include "setting_helper.h"
22 #include "wakeup_source_parser.h"
23 #include "json/reader.h"
24 #include "json/value.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         configJsonStr = SettingHelper::GetSettingWakeupSources();
45     } else {
46         configJsonStr = GetWakeupSourcesByConfig();
47     }
48     g_isFirstSettingUpdated = true;
49     std::shared_ptr<WakeupSources> parseSources = ParseSources(configJsonStr);
50     if (parseSources->GetParseErrorFlag()) {
51         POWER_HILOGI(FEATURE_WAKEUP, "call GetWakeupSourcesByConfig again");
52         configJsonStr = GetWakeupSourcesByConfig();
53         parseSources = ParseSources(configJsonStr);
54     }
55     if (parseSources != nullptr) {
56         SettingHelper::SetSettingWakeupSources(configJsonStr);
57     }
58     g_isFirstSettingUpdated = false;
59     return parseSources;
60 }
61 
GetWakeupSourcesByConfig()62 const std::string WakeupSourceParser::GetWakeupSourcesByConfig()
63 {
64     std::string targetPath;
65     bool ret = GetTargetPath(targetPath);
66     if (ret == false) {
67         return "";
68     }
69 
70     POWER_HILOGI(FEATURE_WAKEUP, "use targetPath=%{public}s", targetPath.c_str());
71     std::ifstream inputStream(targetPath.c_str(), std::ios::in | std::ios::binary);
72     return std::string(std::istreambuf_iterator<char> {inputStream}, std::istreambuf_iterator<char> {});
73 }
74 
GetTargetPath(std::string & targetPath)75 bool WakeupSourceParser::GetTargetPath(std::string& targetPath)
76 {
77     targetPath.clear();
78     char buf[MAX_PATH_LEN];
79     char* path = GetOneCfgFile(POWER_WAKEUP_CONFIG_FILE.c_str(), buf, MAX_PATH_LEN);
80     if (path != nullptr && *path != '\0') {
81         POWER_HILOGI(FEATURE_WAKEUP, "use policy path=%{public}s", path);
82         targetPath = path;
83         return true;
84     }
85 
86     if (access(VENDOR_POWER_WAKEUP_CONFIG_FILE.c_str(), F_OK | R_OK) == -1) {
87         POWER_HILOGE(FEATURE_WAKEUP, "vendor wakeup config is not exist or permission denied");
88         if (access(SYSTEM_POWER_WAKEUP_CONFIG_FILE.c_str(), F_OK | R_OK) == -1) {
89             POWER_HILOGE(FEATURE_WAKEUP, "system wakeup config is not exist or permission denied");
90             return false;
91         } else {
92             targetPath = SYSTEM_POWER_WAKEUP_CONFIG_FILE;
93         }
94     } else {
95         targetPath = VENDOR_POWER_WAKEUP_CONFIG_FILE;
96     }
97 
98     return true;
99 }
100 
ParseSources(const std::string & jsonStr)101 std::shared_ptr<WakeupSources> WakeupSourceParser::ParseSources(const std::string& jsonStr)
102 {
103     std::shared_ptr<WakeupSources> parseSources = std::make_shared<WakeupSources>();
104     Json::Reader reader;
105     Json::Value root;
106     std::string errors;
107     if (!reader.parse(jsonStr.data(), jsonStr.data() + jsonStr.size(), root)) {
108         POWER_HILOGE(FEATURE_WAKEUP, "json parse error");
109         parseSources->SetParseErrorFlag(true);
110         return parseSources;
111     }
112 
113     if (root.isNull() || !root.isObject()) {
114         POWER_HILOGE(FEATURE_WAKEUP, "json root invalid[%{public}s]", jsonStr.c_str());
115         parseSources->SetParseErrorFlag(true);
116         return parseSources;
117     }
118 
119     Json::Value::Members members = root.getMemberNames();
120     for (auto iter = members.begin(); iter != members.end(); iter++) {
121         std::string key = *iter;
122         Json::Value valueObj = root[key];
123 
124         bool ret = ParseSourcesProc(parseSources, valueObj, key);
125         if (ret == false) {
126             POWER_HILOGI(FEATURE_WAKEUP, "lost map config key");
127             continue;
128         }
129     }
130 
131     return parseSources;
132 }
133 
ParseSourcesProc(std::shared_ptr<WakeupSources> & parseSources,Json::Value & valueObj,std::string & key)134 bool WakeupSourceParser::ParseSourcesProc(
135     std::shared_ptr<WakeupSources>& parseSources, Json::Value& valueObj, std::string& key)
136 {
137     bool enable = true;
138     uint32_t click = DOUBLE_CLICK;
139     WakeupDeviceType wakeupDeviceType = WakeupDeviceType::WAKEUP_DEVICE_UNKNOWN;
140     if (!valueObj.isNull() && valueObj.isObject()) {
141         Json::Value enableValue = valueObj[WakeupSource::ENABLE_KEY];
142         Json::Value clickValue = valueObj[WakeupSource::KEYS_KEY];
143         if (!clickValue.isNull() && clickValue.isUInt()) {
144             click = (clickValue.asUInt() == SINGLE_CLICK || clickValue.asUInt() == DOUBLE_CLICK) ? clickValue.asUInt() :
145                                                                                                    DOUBLE_CLICK;
146         }
147         if (enableValue.isBool()) {
148             enable = enableValue.asBool();
149         }
150     }
151 
152     wakeupDeviceType = WakeupSources::mapWakeupDeviceType(key, click);
153     POWER_HILOGI(FEATURE_WAKEUP, "key=%{public}s, type=%{public}u, click=%{public}u, enable=%{public}d",
154         key.c_str(), wakeupDeviceType, click, enable);
155 
156     if (wakeupDeviceType == WakeupDeviceType::WAKEUP_DEVICE_UNKNOWN) {
157         return false;
158     }
159 
160     if (!enable && g_isFirstSettingUpdated) {
161         if (wakeupDeviceType == WakeupDeviceType::WAKEUP_DEVICE_DOUBLE_CLICK
162             && (!SettingHelper::IsWakeupDoubleSettingValid())) {
163             SettingHelper::SetSettingWakeupDouble(enable);
164             POWER_HILOGI(FEATURE_WAKEUP, "the setting wakeupDoubleClick enable=%{public}d", enable);
165         }
166 
167         if (wakeupDeviceType == WakeupDeviceType::WAKEUP_DEVICE_PICKUP
168             && (!SettingHelper::IsWakeupPickupSettingValid())) {
169             SettingHelper::SetSettingWakeupPickup(enable);
170             POWER_HILOGI(FEATURE_WAKEUP, "the setting pickup enable=%{public}d", enable);
171         }
172     }
173 
174     if (enable == true) {
175         WakeupSource wakeupSource = WakeupSource(wakeupDeviceType, enable, click);
176         parseSources->PutSource(wakeupSource);
177     }
178 
179     return true;
180 }
181 
182 } // namespace PowerMgr
183 } // namespace OHOS