• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 <dlfcn.h>
19 #include <mutex>
20 #include <regex>
21 #include <sstream>
22 #include <string>
23 
24 #include "application_context.h"
25 #include "context.h"
26 #include "file_util.h"
27 #include "hiappevent_base.h"
28 #include "hiappevent_read.h"
29 #include "hilog/log.h"
30 
31 namespace OHOS {
32 namespace HiviewDFX {
33 namespace {
34 const HiLogLabel LABEL = { LOG_CORE, HIAPPEVENT_DOMAIN, "HiAppEvent_config" };
35 const std::string DISABLE = "disable";
36 const std::string MAX_STORAGE = "max_storage";
37 const std::string DEFAULT_STORAGE_DIR = "";
38 const std::string APP_EVENT_DIR = "/hiappevent/";
39 constexpr uint64_t STORAGE_UNIT_KB = 1024;
40 constexpr uint64_t STORAGE_UNIT_MB = STORAGE_UNIT_KB * 1024;
41 constexpr uint64_t STORAGE_UNIT_GB = STORAGE_UNIT_MB * 1024;
42 constexpr uint64_t STORAGE_UNIT_TB = STORAGE_UNIT_GB * 1024;
43 constexpr int DECIMAL_UNIT = 10;
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 
LoadAnalyticsModule(const std::string & moduleName)70 void LoadAnalyticsModule(const std::string& moduleName)
71 {
72     const std::string searchDirs[] = {
73         "/system/lib/", "/system/lib64/", "/system/lib/ndk/", "/system/lib64/ndk/"
74     };
75     std::string modulePath;
76     for (auto& searchDir : searchDirs) {
77         if (FileUtil::IsFileExists(searchDir + moduleName)) {
78             modulePath = searchDir + moduleName;
79             break;
80         }
81     }
82     if (modulePath.empty()) {
83         HiLog::Info(LABEL, "the module=%{public}s does not exist.", moduleName.c_str());
84         return;
85     }
86 
87     if (dlopen(modulePath.c_str(), RTLD_GLOBAL) == nullptr) {
88         HiLog::Info(LABEL, "failed to load module=%{public}s, error=%{public}s.", modulePath.c_str(), dlerror());
89     } else {
90         HiLog::Info(LABEL, "success to load module=%{public}s.", modulePath.c_str());
91     }
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(LABEL, "start to configure, name=%{public}s, value=%{public}s.", name.c_str(), value.c_str());
106 
107     if (name == "") {
108         HiLog::Error(LABEL, "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(LABEL, "item value can not be empty.");
115         return false;
116     }
117     std::transform(value.begin(), value.end(), value.begin(), ::tolower);
118 
119     // temporay loading scheme
120     LoadAnalyticsModule("libanalyticskit_native.z.so");
121 
122     if (name == DISABLE) {
123         return SetDisableItem(value);
124     } else if (name == MAX_STORAGE) {
125         return SetMaxStorageSizeItem(value);
126     } else {
127         HiLog::Error(LABEL, "unrecognized configuration item name.");
128         return false;
129     }
130 }
131 
SetDisableItem(const std::string & value)132 bool HiAppEventConfig::SetDisableItem(const std::string& value)
133 {
134     if (value == "true") {
135         SetDisable(true);
136     } else if (value == "false") {
137         SetDisable(false);
138     } else {
139         HiLog::Error(LABEL, "invalid bool value=%{public}s of the application dotting switch.", value.c_str());
140         return false;
141     }
142     return true;
143 }
144 
SetMaxStorageSizeItem(const std::string & value)145 bool HiAppEventConfig::SetMaxStorageSizeItem(const std::string& value)
146 {
147     if (!std::regex_match(value, std::regex("[0-9]+[k|m|g|t]?[b]?"))) {
148         HiLog::Error(LABEL, "invalid value=%{public}s of the event file dir storage quota size.", value.c_str());
149         return false;
150     }
151 
152     auto len = value.length();
153     std::string::size_type numEndIndex = 0;
154     uint64_t numValue = std::stoull(value, &numEndIndex, DECIMAL_UNIT);
155     if (numEndIndex == len) {
156         SetMaxStorageSize(numValue);
157         return true;
158     }
159 
160     uint32_t unitLen = (numEndIndex == (len - 1)) ? 1 : 2; // 1 2, means the length of the storage unit
161     char unitChr = value[len - unitLen];
162     uint64_t maxStoSize = 0;
163     switch (unitChr) {
164         case 'b':
165             maxStoSize = numValue;
166             break;
167         case 'k':
168             maxStoSize = numValue * STORAGE_UNIT_KB;
169             break;
170         case 'm':
171             maxStoSize = numValue * STORAGE_UNIT_MB;
172             break;
173         case 'g':
174             maxStoSize = numValue * STORAGE_UNIT_GB;
175             break;
176         case 't':
177             maxStoSize = numValue * STORAGE_UNIT_TB;
178             break;
179         default:
180             HiLog::Error(LABEL, "invalid storage unit value=%{public}c.", unitChr);
181             return false;
182     }
183 
184     SetMaxStorageSize(maxStoSize);
185     return true;
186 }
187 
SetDisable(bool disable)188 void HiAppEventConfig::SetDisable(bool disable)
189 {
190     {
191         std::lock_guard<std::mutex> lockGuard(g_mutex);
192         this->disable = disable;
193     }
194 }
195 
SetMaxStorageSize(uint64_t size)196 void HiAppEventConfig::SetMaxStorageSize(uint64_t size)
197 {
198     {
199         std::lock_guard<std::mutex> lockGuard(g_mutex);
200         this->maxStorageSize = size;
201     }
202 }
203 
SetStorageDir(const std::string & dir)204 void HiAppEventConfig::SetStorageDir(const std::string& dir)
205 {
206     {
207         std::lock_guard<std::mutex> lockGuard(g_mutex);
208         this->storageDir = dir;
209         LogAssistant::Instance().UpdateHiAppEventLogDir(dir);
210     }
211 }
212 
GetDisable()213 bool HiAppEventConfig::GetDisable()
214 {
215     return this->disable;
216 }
217 
GetMaxStorageSize()218 uint64_t HiAppEventConfig::GetMaxStorageSize()
219 {
220     return this->maxStorageSize;
221 }
222 
GetStorageDir()223 std::string HiAppEventConfig::GetStorageDir()
224 {
225     if (!this->storageDir.empty()) {
226         return this->storageDir;
227     }
228     std::shared_ptr<OHOS::AbilityRuntime::ApplicationContext> context =
229         OHOS::AbilityRuntime::Context::GetApplicationContext();
230     if (context == nullptr) {
231         HiLog::Error(LABEL, "Context is null.");
232         return DEFAULT_STORAGE_DIR;
233     }
234     if (context->GetFilesDir().empty()) {
235         HiLog::Error(LABEL, "The files dir obtained from context is empty.");
236         return DEFAULT_STORAGE_DIR;
237     }
238     std::string dir = context->GetFilesDir() + APP_EVENT_DIR;
239     SetStorageDir(dir);
240     return this->storageDir;
241 }
242 } // namespace HiviewDFX
243 } // namespace OHOS
244