• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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