1 /*
2 * Copyright (c) 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
16 #include "preferences_dfx_adapter.h"
17
18 #include <chrono>
19 #include <ctime>
20 #include <iomanip>
21 #include <sstream>
22
23 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
24 #include <thread>
25
26 #include "accesstoken_kit.h"
27 #include "hisysevent_c.h"
28 #include "ipc_skeleton.h"
29 #endif
30
31 namespace OHOS {
32 namespace NativePreferences {
33
34 ConcurrentMap<std::string, uint64_t> PreferencesDfxManager::reportedFaults_;
35
36 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
GetCurrentTime()37 std::string GetCurrentTime()
38 {
39 auto now = std::chrono::system_clock::now();
40 auto now_ms = std::chrono::time_point_cast<std::chrono::microseconds>(now);
41 auto epoch = now_ms.time_since_epoch();
42 auto value = std::chrono::duration_cast<std::chrono::microseconds>(epoch);
43 auto timestamp = value.count();
44
45 std::time_t tt = std::chrono::system_clock::to_time_t(now);
46 std::tm *tm = std::localtime(&tt);
47 if (tm == nullptr) {
48 return "";
49 }
50
51 const int offset = 1000;
52 const int width = 3;
53 std::stringstream oss;
54 oss << std::put_time(tm, "%Y-%m-%d %H:%M:%S.") << std::setfill('0') << std::setw(width)
55 << ((timestamp / offset) % offset) << "." << std::setfill('0') << std::setw(width) << (timestamp % offset);
56 return oss.str();
57 }
58
GetModuleName()59 std::string PreferencesDfxManager::GetModuleName()
60 {
61 std::string moduleName = "";
62 auto tokenId = IPCSkeleton::GetCallingTokenID();
63 auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
64 if ((tokenType == Security::AccessToken::TOKEN_NATIVE) || (tokenType == Security::AccessToken::TOKEN_SHELL)) {
65 Security::AccessToken::NativeTokenInfo tokenInfo;
66 if (Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) == 0) {
67 moduleName = tokenInfo.processName;
68 }
69 }
70 return moduleName;
71 }
72
ReportAbnormalOperation(const ReportFaultParam & reportParam,ReportedFaultBitMap faultOffset)73 void PreferencesDfxManager::ReportAbnormalOperation(
74 const ReportFaultParam &reportParam, ReportedFaultBitMap faultOffset)
75 {
76 uint64_t offset = static_cast<uint32_t>(faultOffset);
77 PreferencesDfxManager::reportedFaults_.Compute(
78 reportParam.storeName, [reportParam, offset](auto &, uint64_t &report) {
79 uint64_t mask = 0x01;
80 if ((report >> offset) & mask) {
81 return true;
82 }
83 PreferencesDfxManager::ReportFault(reportParam);
84 report |= (mask << offset);
85 return true;
86 });
87 }
88
Report(const ReportParam & reportParam,const char * eventName)89 void PreferencesDfxManager::Report(const ReportParam &reportParam, const char *eventName)
90 {
91 std::string nowTime = GetCurrentTime();
92 std::string moduleName = GetModuleName();
93 if (moduleName.empty()) {
94 moduleName = reportParam.storeName;
95 }
96 std::string bundleName = reportParam.bundleName.empty() ? moduleName : reportParam.bundleName;
97 HiSysEventParam params[] = {
98 { .name = "BUNDLE_NAME",
99 .t = HISYSEVENT_STRING,
100 .v = { .s = const_cast<char *>(bundleName.c_str()) },
101 .arraySize = 0 },
102 { .name = "MODULE_NAME",
103 .t = HISYSEVENT_STRING,
104 .v = { .s = const_cast<char *>(moduleName.c_str()) },
105 .arraySize = 0 },
106 { .name = "STORE_TYPE",
107 .t = HISYSEVENT_STRING,
108 .v = { .s = const_cast<char *>(reportParam.dbType.c_str()) },
109 .arraySize = 0 },
110 { .name = "STORE_NAME",
111 .t = HISYSEVENT_STRING,
112 .v = { .s = const_cast<char *>(reportParam.storeName.c_str()) },
113 .arraySize = 0 },
114 { .name = "SECURITY_LEVEL", .t = HISYSEVENT_UINT32, .v = { .ui32 = 0u }, .arraySize = 0 },
115 { .name = "PATH_AREA", .t = HISYSEVENT_UINT32, .v = { .ui32 = 0u }, .arraySize = 0 },
116 { .name = "ENCRYPT_STATUS", .t = HISYSEVENT_UINT32, .v = { .ui32 = 0u }, .arraySize = 0 },
117 { .name = "INTERGITY_CHECK", .t = HISYSEVENT_UINT32, .v = { .ui32 = 0u }, .arraySize = 0 },
118 { .name = "ERROR_CODE", .t = HISYSEVENT_UINT32, .v = { .ui32 = reportParam.errCode }, .arraySize = 0 },
119 { .name = "ERRNO", .t = HISYSEVENT_INT32, .v = { .i32 = reportParam.errnoCode }, .arraySize = 0 },
120 { .name = "APPENDIX",
121 .t = HISYSEVENT_STRING,
122 .v = { .s = const_cast<char *>(reportParam.appendix.c_str()) },
123 .arraySize = 0 },
124 { .name = "ERROR_TIME",
125 .t = HISYSEVENT_STRING,
126 .v = { .s = const_cast<char *>(nowTime.c_str()) },
127 .arraySize = 0 },
128 };
129 size_t len = sizeof(params) / sizeof(params[0]);
130 OH_HiSysEvent_Write(DISTRIBUTED_DATAMGR, eventName, HISYSEVENT_FAULT, params, len);
131 }
132
ReportFault(const ReportFaultParam & reportParam)133 void PreferencesDfxManager::ReportFault(const ReportFaultParam &reportParam)
134 {
135 std::string nowTime = GetCurrentTime();
136 std::string moduleName = GetModuleName();
137 if (moduleName.empty()) {
138 moduleName = reportParam.storeName;
139 }
140 std::string bundleName = reportParam.bundleName.empty() ? moduleName : reportParam.bundleName;
141 HiSysEventParam params[] = {
142 { .name = "FAULT_TIME",
143 .t = HISYSEVENT_STRING,
144 .v = { .s = const_cast<char *>(nowTime.c_str()) },
145 .arraySize = 0 },
146 { .name = "FAULT_TYPE",
147 .t = HISYSEVENT_STRING,
148 .v = { .s = const_cast<char *>(reportParam.faultType.c_str()) },
149 .arraySize = 0 },
150 { .name = "BUNDLE_NAME",
151 .t = HISYSEVENT_STRING,
152 .v = { .s = const_cast<char *>(bundleName.c_str()) },
153 .arraySize = 0 },
154 { .name = "MODULE_NAME",
155 .t = HISYSEVENT_STRING,
156 .v = { .s = const_cast<char *>(moduleName.c_str()) },
157 .arraySize = 0 },
158 { .name = "STORE_NAME",
159 .t = HISYSEVENT_STRING,
160 .v = { .s = const_cast<char *>(reportParam.storeName.c_str()) },
161 .arraySize = 0 },
162 { .name = "BUSINESE_TYPE",
163 .t = HISYSEVENT_STRING,
164 .v = { .s = const_cast<char *>(reportParam.dbType.c_str()) },
165 .arraySize = 0 },
166 { .name = "ERROR_CODE", .t = HISYSEVENT_INT32, .v = { .i32 = reportParam.errCode }, .arraySize = 0 },
167 { .name = "APPENDIX",
168 .t = HISYSEVENT_STRING,
169 .v = { .s = const_cast<char *>(reportParam.appendix.c_str()) },
170 .arraySize = 0 },
171 };
172 size_t len = sizeof(params) / sizeof(params[0]);
173 OH_HiSysEvent_Write(DISTRIBUTED_DATAMGR, EVENT_NAME_ARKDATA_PREFERENCES_FAULT, HISYSEVENT_FAULT, params, len);
174 }
175
176 #else
177
GetCurrentTime()178 std::string GetCurrentTime()
179 {
180 return "";
181 }
182
GetModuleName()183 std::string PreferencesDfxManager::GetModuleName()
184 {
185 return "";
186 }
187
Report(const ReportParam & reportParam,const char * eventName)188 void PreferencesDfxManager::Report(const ReportParam &reportParam, const char *eventName)
189 {
190 }
191
ReportFault(const ReportFaultParam & reportParam)192 void PreferencesDfxManager::ReportFault(const ReportFaultParam &reportParam)
193 {
194 }
195
ReportAbnormalOperation(const ReportFaultParam & reportParam,ReportedFaultBitMap faultOffset)196 void PreferencesDfxManager::ReportAbnormalOperation(
197 const ReportFaultParam &reportParam, ReportedFaultBitMap faultOffset)
198 {
199 }
200
201 #endif
202 } // End of namespace NativePreferences
203 } // End of namespace OHOS
204