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 #include "log_print.h"
24 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
25 #include <thread>
26 
27 #include "accesstoken_kit.h"
28 #include "hisysevent_c.h"
29 #include "ipc_skeleton.h"
30 #endif
31 
32 namespace OHOS {
33 namespace NativePreferences {
34 #if !defined(WINDOWS_PLATFORM) && !defined(MAC_PLATFORM) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM)
GetCurrentTime()35 std::string GetCurrentTime()
36 {
37     auto now = std::chrono::system_clock::now();
38     auto now_ms = std::chrono::time_point_cast<std::chrono::microseconds>(now);
39     auto epoch = now_ms.time_since_epoch();
40     auto value = std::chrono::duration_cast<std::chrono::microseconds>(epoch);
41     auto timestamp = value.count();
42 
43     std::time_t tt = std::chrono::system_clock::to_time_t(now);
44     std::tm *tm = std::localtime(&tt);
45     if (tm == nullptr) {
46         return "";
47     }
48 
49     const int offset = 1000;
50     const int width = 3;
51     std::stringstream oss;
52     oss << std::put_time(tm, "%Y-%m-%d %H:%M:%S.") << std::setfill('0') << std::setw(width)
53         << ((timestamp / offset) % offset) << "." << std::setfill('0') << std::setw(width) << (timestamp % offset);
54     return oss.str();
55 }
56 
GetModuleName()57 std::string PreferencesDfxManager::GetModuleName()
58 {
59     std::string moduleName = "";
60     auto tokenId = IPCSkeleton::GetCallingTokenID();
61     auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(tokenId);
62     if ((tokenType == Security::AccessToken::TOKEN_NATIVE) || (tokenType == Security::AccessToken::TOKEN_SHELL)) {
63         Security::AccessToken::NativeTokenInfo tokenInfo;
64         if (Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(tokenId, tokenInfo) == 0) {
65             moduleName = tokenInfo.processName;
66         }
67     }
68     return moduleName;
69 }
70 
ReportDbFault(const ReportParam & reportParam)71 void PreferencesDfxManager::ReportDbFault(const ReportParam &reportParam)
72 {
73     std::thread thread([reportParam]() {
74         std::string nowTime = GetCurrentTime();
75         std::string moudleName = GetModuleName();
76         HiSysEventParam params[] = {
77             { .name = "BUNDLE_NAME",
78                 .t = HISYSEVENT_STRING,
79                 .v = { .s = const_cast<char *>(reportParam.bundleName.c_str()) },
80                 .arraySize = 0 },
81             { .name = "MODULE_NAME",
82                 .t = HISYSEVENT_STRING,
83                 .v = { .s = const_cast<char *>(moudleName.c_str()) },
84                 .arraySize = 0 },
85             { .name = "STORE_TYPE",
86                 .t = HISYSEVENT_STRING,
87                 .v = { .s = const_cast<char *>(reportParam.dbType.c_str()) },
88                 .arraySize = 0 },
89             { .name = "STORE_NAME",
90                 .t = HISYSEVENT_STRING,
91                 .v = { .s = const_cast<char *>(reportParam.storeName.c_str()) },
92                 .arraySize = 0 },
93             { .name = "SECURITY_LEVEL", .t = HISYSEVENT_UINT32, .v = { .ui32 = 0u }, .arraySize = 0 },
94             { .name = "PATH_AREA", .t = HISYSEVENT_UINT32, .v = { .ui32 = 0u }, .arraySize = 0 },
95             { .name = "ENCRYPT_STATUS", .t = HISYSEVENT_UINT32, .v = { .ui32 = 0u }, .arraySize = 0 },
96             { .name = "INTERGITY_CHECK", .t = HISYSEVENT_UINT32, .v = { .ui32 = 0u }, .arraySize = 0 },
97             { .name = "ERROR_CODE", .t = HISYSEVENT_UINT32, .v = { .ui32 = reportParam.errCode }, .arraySize = 0 },
98             { .name = "ERRNO", .t = HISYSEVENT_INT32, .v = { .i32 = reportParam.errnoCode }, .arraySize = 0 },
99             { .name = "APPENDIX",
100                 .t = HISYSEVENT_STRING,
101                 .v = { .s = const_cast<char *>(reportParam.appendix.c_str()) },
102                 .arraySize = 0 },
103             { .name = "ERROR_TIME",
104                 .t = HISYSEVENT_STRING,
105                 .v = { .s = const_cast<char *>(nowTime.c_str()) },
106                 .arraySize = 0 },
107         };
108         size_t len = sizeof(params) / sizeof(params[0]);
109         OH_HiSysEvent_Write(DISTRIBUTED_DATAMGR, EVENT_NAME_DB_CORRUPTED, HISYSEVENT_FAULT, params, len);
110     });
111     thread.detach();
112 }
113 #else
114 std::string GetCurrentTime()
115 {
116     return "";
117 }
118 
119 std::string PreferencesDfxManager::GetModuleName()
120 {
121     return "";
122 }
123 
124 void PreferencesDfxManager::ReportDbFault(const ReportParam &reportParam)
125 {
126 }
127 #endif
128 } // End of namespace NativePreferences
129 } // End of namespace OHOS
130