1 /*
2 * Copyright (c) 2021-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 #include "hiappevent_config.h"
16
17 #include <algorithm>
18 #include <mutex>
19 #include <regex>
20 #include <sstream>
21 #include <string>
22
23 #include "app_event_observer_mgr.h"
24 #include "application_context.h"
25 #include "context.h"
26 #include "hiappevent_base.h"
27 #include "hiappevent_read.h"
28 #include "hilog/log.h"
29 #include "module_loader.h"
30
31 #undef LOG_DOMAIN
32 #define LOG_DOMAIN 0xD002D07
33
34 #undef LOG_TAG
35 #define LOG_TAG "HiAppEventConfig"
36
37 namespace OHOS {
38 namespace HiviewDFX {
39 namespace {
40 const std::string DISABLE = "disable";
41 const std::string MAX_STORAGE = "max_storage";
42 const std::string DEFAULT_STORAGE_DIR = "";
43 const std::string APP_EVENT_DIR = "/hiappevent/";
44 constexpr uint64_t STORAGE_UNIT_KB = 1024;
45 constexpr uint64_t STORAGE_UNIT_MB = STORAGE_UNIT_KB * 1024;
46 constexpr uint64_t STORAGE_UNIT_GB = STORAGE_UNIT_MB * 1024;
47 constexpr uint64_t STORAGE_UNIT_TB = STORAGE_UNIT_GB * 1024;
48 constexpr int DECIMAL_UNIT = 10;
49
50 std::mutex g_mutex;
51
TransUpperToUnderscoreAndLower(const std::string & str)52 std::string TransUpperToUnderscoreAndLower(const std::string& str)
53 {
54 if (str.empty()) {
55 return "";
56 }
57
58 std::stringstream ss;
59 for (size_t i = 0; i < str.size(); i++) {
60 char tmp = str[i];
61 if (tmp < 'A' || tmp > 'Z') {
62 ss << tmp;
63 continue;
64 }
65 if (i != 0) { // prevent string from starting with an underscore
66 ss << "_";
67 }
68 tmp += 32; // 32 means upper case to lower case
69 ss << tmp;
70 }
71
72 return ss.str();
73 }
74 }
75
GetInstance()76 HiAppEventConfig& HiAppEventConfig::GetInstance()
77 {
78 static HiAppEventConfig instance;
79 return instance;
80 }
81
SetConfigurationItem(std::string name,std::string value)82 bool HiAppEventConfig::SetConfigurationItem(std::string name, std::string value)
83 {
84 // trans uppercase to underscore and lowercase
85 name = TransUpperToUnderscoreAndLower(name);
86 HILOG_DEBUG(LOG_CORE, "start to configure, name=%{public}s, value=%{public}s.", name.c_str(), value.c_str());
87
88 if (name == "") {
89 HILOG_ERROR(LOG_CORE, "item name can not be empty.");
90 return false;
91 }
92 std::transform(name.begin(), name.end(), name.begin(), ::tolower);
93
94 if (value == "") {
95 HILOG_ERROR(LOG_CORE, "item value can not be empty.");
96 return false;
97 }
98 std::transform(value.begin(), value.end(), value.begin(), ::tolower);
99
100 if (name == DISABLE) {
101 return SetDisableItem(value);
102 } else if (name == MAX_STORAGE) {
103 return SetMaxStorageSizeItem(value);
104 } else {
105 HILOG_ERROR(LOG_CORE, "unrecognized configuration item name.");
106 return false;
107 }
108 }
109
SetDisableItem(const std::string & value)110 bool HiAppEventConfig::SetDisableItem(const std::string& value)
111 {
112 if (value == "true") {
113 SetDisable(true);
114 } else if (value == "false") {
115 SetDisable(false);
116 } else {
117 HILOG_ERROR(LOG_CORE, "invalid bool value=%{public}s of the application dotting switch.", value.c_str());
118 return false;
119 }
120 return true;
121 }
122
SetMaxStorageSizeItem(const std::string & value)123 bool HiAppEventConfig::SetMaxStorageSizeItem(const std::string& value)
124 {
125 if (!std::regex_match(value, std::regex("[0-9]+[k|m|g|t]?[b]?"))) {
126 HILOG_ERROR(LOG_CORE, "invalid value=%{public}s of the event file dir storage quota size.", value.c_str());
127 return false;
128 }
129
130 auto len = value.length();
131 std::string::size_type numEndIndex = 0;
132 uint64_t numValue = std::stoull(value, &numEndIndex, DECIMAL_UNIT);
133 if (numEndIndex == len) {
134 SetMaxStorageSize(numValue);
135 return true;
136 }
137
138 uint32_t unitLen = (numEndIndex == (len - 1)) ? 1 : 2; // 1 2, means the length of the storage unit
139 char unitChr = value[len - unitLen];
140 uint64_t maxStoSize = 0;
141 switch (unitChr) {
142 case 'b':
143 maxStoSize = numValue;
144 break;
145 case 'k':
146 maxStoSize = numValue * STORAGE_UNIT_KB;
147 break;
148 case 'm':
149 maxStoSize = numValue * STORAGE_UNIT_MB;
150 break;
151 case 'g':
152 maxStoSize = numValue * STORAGE_UNIT_GB;
153 break;
154 case 't':
155 maxStoSize = numValue * STORAGE_UNIT_TB;
156 break;
157 default:
158 HILOG_ERROR(LOG_CORE, "invalid storage unit value=%{public}c.", unitChr);
159 return false;
160 }
161
162 SetMaxStorageSize(maxStoSize);
163 return true;
164 }
165
SetDisable(bool disable)166 void HiAppEventConfig::SetDisable(bool disable)
167 {
168 {
169 std::lock_guard<std::mutex> lockGuard(g_mutex);
170 this->disable = disable;
171 }
172 }
173
SetMaxStorageSize(uint64_t size)174 void HiAppEventConfig::SetMaxStorageSize(uint64_t size)
175 {
176 {
177 std::lock_guard<std::mutex> lockGuard(g_mutex);
178 this->maxStorageSize = size;
179 }
180 }
181
SetStorageDir(const std::string & dir)182 void HiAppEventConfig::SetStorageDir(const std::string& dir)
183 {
184 this->storageDir = dir;
185 LogAssistant::Instance().UpdateHiAppEventLogDir(dir);
186 }
187
GetDisable()188 bool HiAppEventConfig::GetDisable()
189 {
190 std::lock_guard<std::mutex> lockGuard(g_mutex);
191 return this->disable;
192 }
193
GetMaxStorageSize()194 uint64_t HiAppEventConfig::GetMaxStorageSize()
195 {
196 std::lock_guard<std::mutex> lockGuard(g_mutex);
197 return this->maxStorageSize;
198 }
199
GetStorageDir()200 std::string HiAppEventConfig::GetStorageDir()
201 {
202 std::lock_guard<std::mutex> lockGuard(g_mutex);
203 if (!this->storageDir.empty()) {
204 return this->storageDir;
205 }
206 std::shared_ptr<OHOS::AbilityRuntime::ApplicationContext> context =
207 OHOS::AbilityRuntime::Context::GetApplicationContext();
208 if (context == nullptr) {
209 HILOG_ERROR(LOG_CORE, "Context is null.");
210 return DEFAULT_STORAGE_DIR;
211 }
212 if (context->GetFilesDir().empty()) {
213 HILOG_ERROR(LOG_CORE, "The files dir obtained from context is empty.");
214 return DEFAULT_STORAGE_DIR;
215 }
216 std::string dir = context->GetFilesDir() + APP_EVENT_DIR;
217 SetStorageDir(dir);
218 return this->storageDir;
219 }
220 } // namespace HiviewDFX
221 } // namespace OHOS
222