* Copyright (c) 2023 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "vibrator_source_parser.h"
#include <fstream>
#include <securec.h>
#include <unistd.h>
#include <cJSON.h>
#include "config_policy_utils.h"
#include "power_cjson_utils.h"
#include "power_log.h"
namespace OHOS {
namespace PowerMgr {
std::vector<VibratorSource> VibratorSourceParser::ParseSources(
const std::string& etcPath, const std::string& vendorPath, const std::string& systemPath)
{
std::vector<VibratorSource> sources;
std::string targetPath;
GetTargetPath(targetPath, etcPath, vendorPath, systemPath);
if (targetPath.empty()) {
POWER_HILOGE(COMP_UTILS, "targetPath is null");
return sources;
}
POWER_HILOGI(COMP_UTILS, "use targetPath=%{public}s", targetPath.c_str());
std::ifstream inputStream(targetPath.c_str(), std::ios::in | std::ios::binary);
std::string fileStringStr(std::istreambuf_iterator<char> {inputStream}, std::istreambuf_iterator<char> {});
targetPath = fileStringStr;
sources = ParseSources(targetPath);
return sources;
}
void VibratorSourceParser::GetTargetPath(
std::string& targetPath, const std::string& etcPath, const std::string& vendorPath, const std::string& systemPath)
{
targetPath.clear();
char buf[MAX_PATH_LEN];
char* path = GetOneCfgFile(etcPath.c_str(), buf, MAX_PATH_LEN);
if (path != nullptr && *path != '\0') {
POWER_HILOGI(COMP_UTILS, "use policy path=%{public}s", path);
targetPath = path;
return;
}
if (access(vendorPath.c_str(), F_OK | R_OK) == -1) {
POWER_HILOGE(COMP_UTILS, "vendor vibrator config is not exist or permission denied");
if (access(systemPath.c_str(), F_OK | R_OK) == -1) {
POWER_HILOGE(COMP_UTILS, "system vibrator config is not exist or permission denied");
return;
} else {
targetPath = systemPath;
}
} else {
targetPath = vendorPath;
}
}
std::vector<VibratorSource> VibratorSourceParser::ParseSources(const std::string& jsonStr)
{
std::vector<VibratorSource> sources;
if (jsonStr.empty()) {
POWER_HILOGE(COMP_UTILS, "Input JSON string is empty");
return sources;
}
cJSON* root = cJSON_Parse(jsonStr.c_str());
if (!root) {
POWER_HILOGE(COMP_UTILS, "JSON parse error");
return sources;
}
if (!PowerMgrJsonUtils::IsValidJsonObjectOrJsonArray(root)) {
POWER_HILOGE(COMP_UTILS, "JSON root is not object");
cJSON_Delete(root);
return sources;
}
cJSON* item = nullptr;
cJSON_ArrayForEach(item, root) {
const char* key = item->string;
if (!key) {
POWER_HILOGE(COMP_UTILS, "invalid key in json object");
continue;
}
std::string keyStr = std::string(key);
POWER_HILOGI(COMP_UTILS, "key=%{public}s", keyStr.c_str());
ParseSourcesProc(sources, item, keyStr);
}
cJSON_Delete(root);
return sources;
}
void VibratorSourceParser::ParseSourcesProc(
std::vector<VibratorSource>& sources, cJSON* valueObj, std::string& key)
{
if (!PowerMgrJsonUtils::IsValidJsonObject(valueObj)) {
POWER_HILOGE(COMP_UTILS, "ValueObj is not a json object.");
return;
}
bool enable = false;
std::string type;
cJSON* enableItem = cJSON_GetObjectItemCaseSensitive(valueObj, VibratorSource::ENABLE_KEY);
if (!PowerMgrJsonUtils::IsValidJsonBool(enableItem)) {
POWER_HILOGE(COMP_UTILS, "Parse enable error.");
return;
}
enable = cJSON_IsTrue(enableItem);
cJSON* typeItem = cJSON_GetObjectItemCaseSensitive(valueObj, VibratorSource::TYPE_KEY);
if (!PowerMgrJsonUtils::IsValidJsonString(typeItem)) {
POWER_HILOGE(COMP_UTILS, "Parse type error.");
return;
}
type = typeItem->valuestring;
if (!enable || type.empty()) {
return;
}
VibratorSource vibratorSource = VibratorSource(key, enable, type);
sources.emplace_back(vibratorSource);
}
}
}