1 /*
2 * Copyright (c) 2021-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 #include "hiappevent_config.h"
16
17 #include <algorithm>
18 #include <cinttypes>
19 #include <cstdlib>
20 #include <mutex>
21 #include <regex>
22 #include <sstream>
23 #include <string>
24
25 #include "app_event_observer_mgr.h"
26 #include "application_context.h"
27 #include "context.h"
28 #include "hiappevent_base.h"
29 #include "hilog/log.h"
30 #include "iservice_registry.h"
31 #include "storage_manager_proxy.h"
32 #include "system_ability_definition.h"
33
34 #undef LOG_DOMAIN
35 #define LOG_DOMAIN 0xD002D07
36
37 #undef LOG_TAG
38 #define LOG_TAG "Config"
39
40 namespace OHOS {
41 namespace HiviewDFX {
42 namespace {
43 const std::string DISABLE = "disable";
44 const std::string MAX_STORAGE = "max_storage";
45 const std::string DEFAULT_STORAGE_DIR = "";
46 const std::string APP_EVENT_DIR = "/hiappevent/";
47 constexpr uint64_t STORAGE_UNIT_KB = 1024;
48 constexpr uint64_t STORAGE_UNIT_MB = STORAGE_UNIT_KB * 1024;
49 constexpr uint64_t STORAGE_UNIT_GB = STORAGE_UNIT_MB * 1024;
50 constexpr uint64_t STORAGE_UNIT_TB = STORAGE_UNIT_GB * 1024;
51 constexpr int DECIMAL_UNIT = 10;
52 constexpr int64_t FREE_SIZE_LIMIT = STORAGE_UNIT_MB * 300;
53
54 std::mutex g_mutex;
55
TransUpperToUnderscoreAndLower(const std::string & str)56 std::string TransUpperToUnderscoreAndLower(const std::string& str)
57 {
58 if (str.empty()) {
59 return "";
60 }
61
62 std::stringstream ss;
63 for (size_t i = 0; i < str.size(); i++) {
64 char tmp = str[i];
65 if (tmp < 'A' || tmp > 'Z') {
66 ss << tmp;
67 continue;
68 }
69 if (i != 0) { // prevent string from starting with an underscore
70 ss << "_";
71 }
72 tmp += 32; // 32 means upper case to lower case
73 ss << tmp;
74 }
75
76 return ss.str();
77 }
78
GetStorageMgr()79 sptr<OHOS::StorageManager::IStorageManager> GetStorageMgr()
80 {
81 auto systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager();
82 if (systemAbilityManager == nullptr) {
83 HILOG_WARN(LOG_CORE, "systemAbilityManager is null.");
84 return nullptr;
85 }
86 sptr<IRemoteObject> storageMgrSa = systemAbilityManager->GetSystemAbility(STORAGE_MANAGER_MANAGER_ID);
87 if (storageMgrSa == nullptr) {
88 HILOG_WARN(LOG_CORE, "storageMgrSa is null.");
89 return nullptr;
90 }
91 return iface_cast<OHOS::StorageManager::IStorageManager>(storageMgrSa);
92 }
93 }
94
GetInstance()95 HiAppEventConfig& HiAppEventConfig::GetInstance()
96 {
97 static HiAppEventConfig instance;
98 return instance;
99 }
100
SetConfigurationItem(std::string name,std::string value)101 bool HiAppEventConfig::SetConfigurationItem(std::string name, std::string value)
102 {
103 // trans uppercase to underscore and lowercase
104 name = TransUpperToUnderscoreAndLower(name);
105 HILOG_DEBUG(LOG_CORE, "start to configure.");
106
107 if (name == "") {
108 HILOG_ERROR(LOG_CORE, "item name can not be empty.");
109 return false;
110 }
111 std::transform(name.begin(), name.end(), name.begin(), ::tolower);
112
113 if (value == "") {
114 HILOG_ERROR(LOG_CORE, "item value can not be empty.");
115 return false;
116 }
117 std::transform(value.begin(), value.end(), value.begin(), ::tolower);
118
119 if (name == DISABLE) {
120 return SetDisableItem(value);
121 } else if (name == MAX_STORAGE) {
122 return SetMaxStorageSizeItem(value);
123 } else {
124 HILOG_ERROR(LOG_CORE, "unrecognized configuration item name.");
125 return false;
126 }
127 }
128
SetDisableItem(const std::string & value)129 bool HiAppEventConfig::SetDisableItem(const std::string& value)
130 {
131 if (value == "true") {
132 SetDisable(true);
133 } else if (value == "false") {
134 SetDisable(false);
135 } else {
136 HILOG_ERROR(LOG_CORE, "invalid bool value=%{public}s of the application dotting switch.", value.c_str());
137 return false;
138 }
139 return true;
140 }
141
SetMaxStorageSizeItem(const std::string & value)142 bool HiAppEventConfig::SetMaxStorageSizeItem(const std::string& value)
143 {
144 if (!std::regex_match(value, std::regex("[0-9]+[k|m|g|t]?[b]?"))) {
145 HILOG_ERROR(LOG_CORE, "invalid value=%{public}s of the event file dir storage quota size.", value.c_str());
146 return false;
147 }
148
149 char* numEndIndex = nullptr;
150 uint64_t numValue = std::strtoull(value.c_str(), &numEndIndex, DECIMAL_UNIT);
151 if (*numEndIndex == '\0') {
152 SetMaxStorageSize(numValue);
153 return true;
154 }
155
156 uint32_t unitLen = std::strlen(numEndIndex);
157 auto len = value.length();
158 char unitChr = value[len - unitLen];
159 uint64_t maxStoSize = 0;
160 switch (unitChr) {
161 case 'b':
162 maxStoSize = numValue;
163 break;
164 case 'k':
165 maxStoSize = numValue * STORAGE_UNIT_KB;
166 break;
167 case 'm':
168 maxStoSize = numValue * STORAGE_UNIT_MB;
169 break;
170 case 'g':
171 maxStoSize = numValue * STORAGE_UNIT_GB;
172 break;
173 case 't':
174 maxStoSize = numValue * STORAGE_UNIT_TB;
175 break;
176 default:
177 HILOG_ERROR(LOG_CORE, "invalid storage unit value=%{public}c.", unitChr);
178 return false;
179 }
180
181 SetMaxStorageSize(maxStoSize);
182 return true;
183 }
184
SetDisable(bool disable)185 void HiAppEventConfig::SetDisable(bool disable)
186 {
187 std::lock_guard<std::mutex> lockGuard(g_mutex);
188 disable_ = disable;
189 }
190
SetMaxStorageSize(uint64_t size)191 void HiAppEventConfig::SetMaxStorageSize(uint64_t size)
192 {
193 std::lock_guard<std::mutex> lockGuard(g_mutex);
194 maxStorageSize_ = size;
195 }
196
SetStorageDir(const std::string & dir)197 void HiAppEventConfig::SetStorageDir(const std::string& dir)
198 {
199 storageDir_ = dir;
200 }
201
GetDisable()202 bool HiAppEventConfig::GetDisable()
203 {
204 std::lock_guard<std::mutex> lockGuard(g_mutex);
205 return disable_;
206 }
207
GetMaxStorageSize()208 uint64_t HiAppEventConfig::GetMaxStorageSize()
209 {
210 std::lock_guard<std::mutex> lockGuard(g_mutex);
211 return maxStorageSize_;
212 }
213
GetStorageDir()214 std::string HiAppEventConfig::GetStorageDir()
215 {
216 std::lock_guard<std::mutex> lockGuard(g_mutex);
217 if (!storageDir_.empty()) {
218 return storageDir_;
219 }
220 std::shared_ptr<OHOS::AbilityRuntime::ApplicationContext> context =
221 OHOS::AbilityRuntime::Context::GetApplicationContext();
222 if (context == nullptr) {
223 HILOG_ERROR(LOG_CORE, "Context is null.");
224 return DEFAULT_STORAGE_DIR;
225 }
226 if (context->GetFilesDir().empty()) {
227 HILOG_ERROR(LOG_CORE, "The files dir obtained from context is empty.");
228 return DEFAULT_STORAGE_DIR;
229 }
230 std::string dir = context->GetFilesDir() + APP_EVENT_DIR;
231 SetStorageDir(dir);
232 return storageDir_;
233 }
234
GetRunningId()235 std::string HiAppEventConfig::GetRunningId()
236 {
237 std::lock_guard<std::mutex> lockGuard(g_mutex);
238 if (!runningId_.empty()) {
239 return runningId_;
240 }
241 std::shared_ptr<OHOS::AbilityRuntime::ApplicationContext> context =
242 OHOS::AbilityRuntime::Context::GetApplicationContext();
243 if (context == nullptr) {
244 HILOG_ERROR(LOG_CORE, "Context is null.");
245 return "";
246 }
247 runningId_ = context->GetAppRunningUniqueId();
248 if (runningId_.empty()) {
249 HILOG_ERROR(LOG_CORE, "The running id from context is empty.");
250 }
251 return runningId_;
252 }
253
IsFreeSizeOverLimit()254 bool HiAppEventConfig::IsFreeSizeOverLimit()
255 {
256 std::lock_guard<std::mutex> lockGuard(g_mutex);
257 if (!isInitFreeSize_) {
258 isInitFreeSize_ = true;
259 auto storageMgr = GetStorageMgr();
260 int64_t freeSize = -1;
261 if (storageMgr == nullptr || storageMgr->GetFreeSize(freeSize) != 0) {
262 HILOG_WARN(LOG_CORE, "Failed to get free size.");
263 return false;
264 }
265 HILOG_INFO(LOG_CORE, "get free size=%{public}" PRId64, freeSize);
266 freeSize_ = freeSize;
267 }
268 return freeSize_ >= 0 && freeSize_ < FREE_SIZE_LIMIT;
269 }
270
RefreshFreeSize()271 void HiAppEventConfig::RefreshFreeSize()
272 {
273 auto storageMgr = GetStorageMgr();
274 int64_t freeSize = -1;
275 if (storageMgr == nullptr || storageMgr->GetFreeSize(freeSize) != 0) {
276 HILOG_WARN(LOG_CORE, "Failed to refresh free size.");
277 return;
278 }
279 HILOG_INFO(LOG_CORE, "refresh free size=%{public}" PRId64, freeSize);
280 std::lock_guard<std::mutex> lockGuard(g_mutex);
281 freeSize_ = freeSize;
282 }
283 } // namespace HiviewDFX
284 } // namespace OHOS
285