1 /*
2 * Copyright (c) 2025 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 #define LOG_TAG "HiViewFaultAdapter"
17 
18 #include "hiview_fault_adapter.h"
19 
20 #include <iomanip>
21 #include <sstream>
22 #include "log_print.h"
23 
24 namespace OHOS {
25 namespace DataShare {
26 namespace {
27     constexpr char DOMAIN[] = "DISTDATAMGR";
28     constexpr const char *EVENT_NAME = "DISTRIBUTED_DATA_SHARE_FAULT";
29     constexpr const char *FAULT_TIME = "FAULT_TIME";
30     constexpr const char *FAULT_TYPE = "FAULT_TYPE";
31     constexpr const char *BUNDLE_NAME = "BUNDLE_NAME";
32     constexpr const char *MODULE_NAME = "MODULE_NAME";
33     constexpr const char *STORE_NAME = "STORE_NAME";
34     constexpr const char *BUSINESS_TYPE = "BUSINESS_TYPE";
35     constexpr const char *ERROR_CODE = "ERROR_CODE";
36     constexpr const char *APPENDIX = "APPENDIX";
37     constexpr const size_t PARAMS_SIZE = 8;
38 }
39 
ReportDataFault(const DataShareFaultInfo & faultInfo)40 void HiViewFaultAdapter::ReportDataFault(const DataShareFaultInfo &faultInfo)
41 {
42     auto t = std::chrono::system_clock::to_time_t(std::chrono::system_clock::now());
43     std::stringstream ss;
44     ss << std::put_time(std::localtime(&t), "%F %T");
45     auto time = ss.str();
46     HiSysEventParam faultTime = { .name = { *FAULT_TIME }, .t = HISYSEVENT_STRING,
47         .v = { .s = const_cast<char*>(time.c_str()) }, .arraySize = 0 };
48     HiSysEventParam faultType = { .name = { *FAULT_TYPE }, .t = HISYSEVENT_STRING,
49         .v = { .s = const_cast<char*>(faultInfo.faultType.c_str()) }, .arraySize = 0 };
50     HiSysEventParam bundleName = { .name = { *BUNDLE_NAME }, .t = HISYSEVENT_STRING,
51         .v = { .s = const_cast<char*>(faultInfo.bundleName.c_str()) }, .arraySize = 0 };
52     HiSysEventParam moduleName = { .name = { *MODULE_NAME }, .t = HISYSEVENT_STRING,
53         .v = { .s = const_cast<char*>(faultInfo.moduleName.c_str()) }, .arraySize = 0 };
54     HiSysEventParam storeName = { .name = { *STORE_NAME }, .t = HISYSEVENT_STRING,
55         .v = { .s = const_cast<char*>(faultInfo.storeName.c_str()) }, .arraySize = 0 };
56     HiSysEventParam businessType = { .name = { *BUSINESS_TYPE }, .t = HISYSEVENT_STRING,
57         .v = { .s = const_cast<char*>(faultInfo.businessType.c_str()) }, .arraySize = 0 };
58     HiSysEventParam errorCode = { .name = { *ERROR_CODE }, .t = HISYSEVENT_INT32,
59         .v = { .i32 = faultInfo.errorCode }, .arraySize = 0 };
60     HiSysEventParam appendix = { .name = { *APPENDIX }, .t = HISYSEVENT_STRING,
61         .v = { .s = const_cast<char*>(faultInfo.appendix.c_str()) }, .arraySize = 0 };
62     HiSysEventParam params[] = { faultTime, faultType, bundleName, moduleName,
63         storeName, businessType, errorCode, appendix };
64     int res = OH_HiSysEvent_Write(DOMAIN, EVENT_NAME, HISYSEVENT_FAULT, params, PARAMS_SIZE);
65     ZLOGI("OH_HiSysEvent_Write, res = %{public}d", res);
66 }
67 
GetCallingName(uint32_t callingTokenid)68 std::pair<std::string, int> HiViewFaultAdapter::GetCallingName(uint32_t callingTokenid)
69 {
70     std::string callingName;
71     auto tokenType = Security::AccessToken::AccessTokenKit::GetTokenTypeFlag(callingTokenid);
72     int result = -1;
73     if (tokenType == Security::AccessToken::TOKEN_HAP) {
74         Security::AccessToken::HapTokenInfo tokenInfo;
75         result = Security::AccessToken::AccessTokenKit::GetHapTokenInfo(callingTokenid, tokenInfo);
76         if (result == Security::AccessToken::RET_SUCCESS) {
77             callingName = tokenInfo.bundleName;
78         }
79     } else if (tokenType == Security::AccessToken::TOKEN_NATIVE || tokenType == Security::AccessToken::TOKEN_SHELL) {
80         Security::AccessToken::NativeTokenInfo tokenInfo;
81         result = Security::AccessToken::AccessTokenKit::GetNativeTokenInfo(callingTokenid, tokenInfo);
82         if (result == Security::AccessToken::RET_SUCCESS) {
83             callingName = tokenInfo.processName;
84         }
85     } else {
86         ZLOGE("tokenType is invalid, tokenType:%{public}d, Tokenid:%{public}x", tokenType, callingTokenid);
87     }
88     return std::make_pair(callingName, result);
89 }
90 
~RdbTimeCostInfo()91 RdbTimeCostInfo::~RdbTimeCostInfo()
92 {
93     auto end = std::chrono::steady_clock::now();
94     auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
95     if (duration > TIME_OUT_MS) {
96         int64_t milliseconds = duration.count();
97         std::string appendix = "callingName:" + HiViewFaultAdapter::GetCallingName(callingTokenId).first;
98         appendix += ",cost:" + std::to_string(milliseconds) + "ms";
99         DataShareFaultInfo faultInfo{TIME_OUT, bundleName, moduleName, storeName, businessType, errorCode, appendix};
100         HiViewFaultAdapter::ReportDataFault(faultInfo);
101     }
102 }
103 }
104 }