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