1 /*
2 * Copyright (c) 2024 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 <unistd.h>
17 #include <cJSON.h>
18
19 #include "notification_locale.h"
20 #include "config_policy_utils.h"
21 #include "locale_config.h"
22 #include "locale_matcher.h"
23 #include "battery_info.h"
24 #include "battery_log.h"
25 #include "battery_mgr_cjson_utils.h"
26 #include "power_common.h"
27
28 namespace {
29 constexpr const char* LOCALE_CONFIG_PATH = "/system/etc/battery/resources/locale_path.json";
30 constexpr const char* SYSTEM_BATTERY_RESOURCE_PATH = "/system/etc/battery/resources/";
31 constexpr const char* SYSTEM_BATTERY_RESOURCEEXT_PATH = "/system/etc/battery/resourcesExt/";
32 constexpr const char* ELEMENT_STRING_FILE = "/element/string.json";
33 constexpr const char* DEFAULT_LANGUAGE_EN = "base";
34 }
35
36 namespace OHOS {
37 namespace PowerMgr {
38 std::shared_ptr<NotificationLocale> NotificationLocale::instance_ = nullptr;
39 std::mutex NotificationLocale::mutex_;
GetInstance()40 NotificationLocale& NotificationLocale::GetInstance()
41 {
42 std::lock_guard<std::mutex> lock(mutex_);
43 if (instance_ == nullptr) {
44 instance_ = std::make_shared<NotificationLocale>();
45 }
46 return *(instance_.get());
47 }
48
ParseJsonfile(const std::string & targetPath,std::unordered_map<std::string,std::string> & container)49 bool NotificationLocale::ParseJsonfile(const std::string& targetPath,
50 std::unordered_map<std::string, std::string>& container)
51 {
52 if (access(targetPath.c_str(), F_OK) != 0) {
53 BATTERY_HILOGE(COMP_SVC, "targetPath %{public}s invalid", targetPath.c_str());
54 return false;
55 }
56 std::ifstream inputStream(targetPath.c_str(), std::ios::in | std::ios::binary);
57 std::string fileStr(std::istreambuf_iterator<char> {inputStream}, std::istreambuf_iterator<char> {});
58
59 return SaveJsonToMap(fileStr, targetPath, container);
60 }
61
SaveJsonToMap(const std::string & fileStr,const std::string & targetPath,std::unordered_map<std::string,std::string> & container)62 bool NotificationLocale::SaveJsonToMap(const std::string& fileStr, const std::string& targetPath,
63 std::unordered_map<std::string, std::string>& container)
64 {
65 cJSON* root = cJSON_Parse(fileStr.c_str());
66 if (!root) {
67 BATTERY_HILOGE(COMP_SVC, "%{public}s json parse error", targetPath.c_str());
68 return false;
69 }
70 if (cJSON_IsNull(root) || !cJSON_IsObject(root)) {
71 BATTERY_HILOGE(COMP_SVC, "%{public}s json root error", targetPath.c_str());
72 cJSON_Delete(root);
73 return false;
74 }
75 cJSON* stringConf = cJSON_GetObjectItemCaseSensitive(root, "string");
76 if (!BatteryMgrJsonUtils::IsValidJsonArray(stringConf)) {
77 BATTERY_HILOGE(COMP_SVC, "%{public}s stringConf invalid", targetPath.c_str());
78 cJSON_Delete(root);
79 return false;
80 }
81 cJSON* conf = nullptr;
82 cJSON_ArrayForEach(conf, stringConf) {
83 cJSON* nameObj = cJSON_GetObjectItemCaseSensitive(conf, "name");
84 cJSON* valueObj = cJSON_GetObjectItemCaseSensitive(conf, "value");
85 if (BatteryMgrJsonUtils::IsValidJsonStringAndNoEmpty(nameObj) &&
86 BatteryMgrJsonUtils::IsValidJsonStringAndNoEmpty(valueObj)) {
87 container.insert(std::make_pair(nameObj->valuestring, valueObj->valuestring));
88 }
89 }
90 cJSON_Delete(root);
91 BATTERY_HILOGI(COMP_SVC, "%{public}s stringConf end", targetPath.c_str());
92 return true;
93 }
94
ParseLocaleCfg()95 void NotificationLocale::ParseLocaleCfg()
96 {
97 if (islanguageMapInit_) {
98 return;
99 }
100 languageMap_.clear();
101 if (ParseJsonfile(LOCALE_CONFIG_PATH, languageMap_)) {
102 islanguageMapInit_ = true;
103 }
104 }
105
UpdateStringMap()106 void NotificationLocale::UpdateStringMap()
107 {
108 OHOS::Global::I18n::LocaleInfo locale(Global::I18n::LocaleConfig::GetSystemLocale());
109 std::string curBaseName = locale.GetBaseName();
110 if (localeBaseName_ == curBaseName) {
111 return;
112 }
113 BATTERY_HILOGI(COMP_SVC, "UpdateResourceMap: change from [%{public}s] to [%{public}s]",
114 localeBaseName_.c_str(), curBaseName.c_str());
115 localeBaseName_ = curBaseName;
116 std::string language = DEFAULT_LANGUAGE_EN;
117 if (languageMap_.find(localeBaseName_) != languageMap_.end()) {
118 language = languageMap_[localeBaseName_];
119 } else {
120 for (auto& iter : languageMap_) {
121 OHOS::Global::I18n::LocaleInfo eachLocale(iter.first);
122 if (OHOS::Global::I18n::LocaleMatcher::Match(&locale, &eachLocale)) {
123 language = iter.second;
124 break;
125 }
126 }
127 }
128 stringMap_.clear();
129 std::string resourcePath = SYSTEM_BATTERY_RESOURCE_PATH + language + ELEMENT_STRING_FILE;
130 ParseJsonfile(resourcePath, stringMap_);
131 resourcePath = SYSTEM_BATTERY_RESOURCEEXT_PATH + language + ELEMENT_STRING_FILE;
132 ParseJsonfile(resourcePath, stringMap_);
133 }
134
GetStringByKey(const std::string & key)135 std::string NotificationLocale::GetStringByKey(const std::string& key)
136 {
137 auto iter = stringMap_.find(key);
138 if (iter != stringMap_.end()) {
139 return iter->second;
140 }
141 return "";
142 }
143 }
144 }