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