1 /*
2 * Copyright (c) 2025 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
17 #include "product_name_definition_parser.h"
18
19 #include "devicestatus_define.h"
20
21 #include "util.h"
22
23 #include <cJSON.h>
24
25 #undef LOG_TAG
26 #define LOG_TAG "ProductNameDefinitionParser"
27
28 namespace OHOS {
29 namespace Msdp {
30 namespace DeviceStatus {
31 namespace {
32 constexpr std::string_view productNameDefinitionConfigDir {
33 "/etc/multimodalinput/product_name_definition_config.json" };
34 constexpr int32_t maxJsonArraySize { 100 };
35 } // namespace
36
GetInstance()37 ProductNameDefinitionParser& ProductNameDefinitionParser::GetInstance()
38 {
39 static ProductNameDefinitionParser instance;
40 return instance;
41 }
42
Init()43 int32_t ProductNameDefinitionParser::Init()
44 {
45 CALL_DEBUG_ENTER;
46 if (isInitialized_.load()) {
47 return RET_OK;
48 }
49 std::string jsonStr = ReadJsonFile(std::string(productNameDefinitionConfigDir));
50 if (jsonStr.empty()) {
51 FI_HILOGE("Read productName failed");
52 return RET_ERR;
53 }
54 JsonParser parser(jsonStr.c_str());
55 if (!cJSON_IsObject(parser.Get())) {
56 FI_HILOGE("Not valid object");
57 return RET_ERR;
58 }
59 if (ParseProductNameMap(parser) != RET_OK) {
60 FI_HILOGE("ParseProductNameMap failed");
61 return RET_ERR;
62 }
63 PrintProductNames();
64 isInitialized_.store(true);
65 return RET_OK;
66 }
67
GetProductName(const std::string & key)68 std::string ProductNameDefinitionParser::GetProductName(const std::string &key)
69 {
70 if (Init() != RET_OK) {
71 FI_HILOGE("Init failed");
72 return "";
73 }
74 std::shared_lock<std::shared_mutex> lock(lock_);
75 if (productNames_.find(key) != productNames_.end()) {
76 return productNames_[key];
77 }
78 FI_HILOGW("No %{public}s matched.", key.c_str());
79 return "";
80 }
81
ParseProductNameMap(const JsonParser & jsonParser)82 int32_t ProductNameDefinitionParser::ParseProductNameMap(const JsonParser &jsonParser)
83 {
84 cJSON *productNameMapJson = cJSON_GetObjectItemCaseSensitive(jsonParser.Get(), "product_name_definition");
85
86 if (!cJSON_IsArray(productNameMapJson)) {
87 FI_HILOGE("productNameMapJson is not array");
88 return RET_ERR;
89 }
90 int32_t arraySize = cJSON_GetArraySize(productNameMapJson);
91 if (arraySize > maxJsonArraySize) {
92 FI_HILOGW("arraySize is too much, truncate it");
93 }
94 for (int32_t i = 0; i < std::min(arraySize, maxJsonArraySize); i++) {
95 cJSON* productNameItemJson = cJSON_GetArrayItem(productNameMapJson, i);
96 CHKPC(productNameItemJson);
97 ProductNameDefinitionItem productNameItem;
98 if (ParserProductNameItem(productNameItemJson, productNameItem) != RET_OK) {
99 FI_HILOGE("ParserProductNameItem failed");
100 continue;
101 }
102 std::unique_lock<std::shared_mutex> lock(lock_);
103 productNames_.insert({ productNameItem.productAlias, productNameItem.productName });
104 }
105 return RET_OK;
106 }
107
ParserProductNameItem(const cJSON * json,ProductNameDefinitionItem & productNameItem)108 int32_t ProductNameDefinitionParser::ParserProductNameItem(const cJSON *json,
109 ProductNameDefinitionItem &productNameItem)
110 {
111 if (JsonParser::ParseString(json, "product_alias", productNameItem.productAlias) != RET_OK) {
112 FI_HILOGE("Parse product_alias failed");
113 return RET_ERR;
114 }
115 if (JsonParser::ParseString(json, "product_name", productNameItem.productName) != RET_OK) {
116 FI_HILOGE("Parse product_name failed");
117 return RET_ERR;
118 }
119 return RET_OK;
120 }
121
PrintProductNames()122 void ProductNameDefinitionParser::PrintProductNames()
123 {
124 CALL_INFO_TRACE;
125 std::shared_lock<std::shared_mutex> lock(lock_);
126 for (const auto &productName: productNames_) {
127 FI_HILOGI("key:%{public}s -> value:%{public}s", productName.first.c_str(), productName.second.c_str());
128 }
129 }
130 } // namespace DeviceStatus
131 } // namespace Msdp
132 } // namespace OHOS