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 #include "hisysevent_adapter.h"
16 #include "securec.h"
17 #include "hisysevent.h"
18 #include "appspawn_utils.h"
19
20 using namespace OHOS::HiviewDFX;
21 namespace {
22 // fail event
23 constexpr const char* SPAWN_CHILD_PROCESS_FAIL = "SPAWN_CHILD_PROCESS_FAIL";
24
25 // behavior event
26 constexpr const char* SPAWN_KEY_EVENT = "SPAWN_KEY_EVENT";
27 constexpr const char* SPAWN_ABNORMAL_DURATION = "SPAWN_ABNORMAL_DURATION";
28
29 // statistic event
30 constexpr const char* SPAWN_PROCESS_DURATION = "SPAWN_PROCESS_DURATION";
31
32 // param
33 constexpr const char* PROCESS_NAME = "PROCESS_NAME";
34 constexpr const char* ERROR_CODE = "ERROR_CODE";
35 constexpr const char* SPAWN_RESULT = "SPAWN_RESULT";
36 constexpr const char* SRC_PATH = "SRC_PATH";
37 constexpr const char* TARGET_PATH = "TARGET_PATH";
38
39 constexpr const char* EVENT_NAME = "EVENT_NAME";
40
41 constexpr const char* SCENE_NAME = "SCENE_NAME";
42 constexpr const char* DURATION = "DURATION";
43
44 constexpr const char* MAXDURATION = "MAXDURATION";
45 constexpr const char* MINDURATION = "MINDURATION";
46 constexpr const char* TOTALDURATION = "TOTALDURATION";
47 constexpr const char* EVENTCOUNT = "EVENTCOUNT";
48 constexpr const char* STAGE = "STAGE";
49 constexpr const char* BOOTSTAGE = "BOOTSTAGE";
50 constexpr const char* BOOTFINISHEDSTAGE = "BOOTFINISHEDSTAGE";
51 }
52
AddStatisticEvent(AppSpawnHisysevent * event,uint32_t duration)53 static void AddStatisticEvent(AppSpawnHisysevent *event, uint32_t duration)
54 {
55 event->eventCount++;
56 event->totalDuration += duration;
57 if (duration > event->maxDuration) {
58 event->maxDuration = duration;
59 }
60 if (duration < event->minDuration) {
61 event->minDuration = duration;
62 }
63 APPSPAWN_LOGV("event->maxDuration is: %{public}d, event->minDuration is: %{public}d",
64 event->maxDuration, event->minDuration);
65 }
66
AddStatisticEventInfo(AppSpawnHisyseventInfo * hisyseventInfo,uint32_t duration,bool stage)67 void AddStatisticEventInfo(AppSpawnHisyseventInfo *hisyseventInfo, uint32_t duration, bool stage)
68 {
69 APPSPAWN_CHECK(hisyseventInfo != NULL, return, "fail to get AppSpawnHisyseventInfo");
70 if (stage) {
71 AddStatisticEvent(&hisyseventInfo->bootEvent, duration);
72 } else {
73 AddStatisticEvent(&hisyseventInfo->manualEvent, duration);
74 }
75 }
76
InitStatisticEvent(AppSpawnHisysevent * event)77 static void InitStatisticEvent(AppSpawnHisysevent *event)
78 {
79 event->eventCount = 0;
80 event->maxDuration = 0;
81 event->minDuration = UINT32_MAX;
82 event->totalDuration = 0;
83 }
84
InitStatisticEventInfo(AppSpawnHisyseventInfo * appSpawnHisysInfo)85 static void InitStatisticEventInfo(AppSpawnHisyseventInfo *appSpawnHisysInfo)
86 {
87 InitStatisticEvent(&appSpawnHisysInfo->bootEvent);
88 InitStatisticEvent(&appSpawnHisysInfo->manualEvent);
89 }
90
CreateHisysTimerLoop(AppSpawnHisyseventInfo * hisyseventInfo)91 static int CreateHisysTimerLoop(AppSpawnHisyseventInfo *hisyseventInfo)
92 {
93 LoopHandle loop = LE_GetDefaultLoop();
94 TimerHandle timer = NULL;
95 int ret = LE_CreateTimer(loop, &timer, ReportSpawnStatisticDuration, (void *)hisyseventInfo);
96 APPSPAWN_CHECK(ret == 0, return -1, "fail to create HisysTimer, ret is: %{public}d", ret);
97 // start a timer to report event every 24h
98 ret = LE_StartTimer(loop, timer, APPSPAWN_HISYSEVENT_REPORT_TIME, INT64_MAX);
99 APPSPAWN_CHECK(ret == 0, return -1, "fail to start HisysTimer, ret is: %{public}d", ret);
100 return ret;
101 }
102
GetAppSpawnHisyseventInfo(void)103 AppSpawnHisyseventInfo *GetAppSpawnHisyseventInfo(void)
104 {
105 AppSpawnHisyseventInfo *hisyseventInfo =
106 static_cast<AppSpawnHisyseventInfo *>(malloc(sizeof(AppSpawnHisyseventInfo)));
107 APPSPAWN_CHECK(hisyseventInfo != NULL, return NULL, "fail to alloc memory for hisyseventInfo");
108 int ret = memset_s(hisyseventInfo, sizeof(AppSpawnHisyseventInfo), 0, sizeof(AppSpawnHisyseventInfo));
109 if (ret != 0) {
110 free(hisyseventInfo);
111 hisyseventInfo = NULL;
112 APPSPAWN_LOGE("Failed to memset hisyseventInfo");
113 return NULL;
114 }
115 InitStatisticEventInfo(hisyseventInfo);
116 return hisyseventInfo;
117 }
118
DeleteHisyseventInfo(AppSpawnHisyseventInfo * hisyseventInfo)119 void DeleteHisyseventInfo(AppSpawnHisyseventInfo *hisyseventInfo)
120 {
121 APPSPAWN_CHECK_ONLY_EXPER(hisyseventInfo != NULL, return);
122 free(hisyseventInfo);
123 hisyseventInfo = NULL;
124 }
125
InitHisyseventTimer(void)126 AppSpawnHisyseventInfo *InitHisyseventTimer(void)
127 {
128 AppSpawnHisyseventInfo *hisyseventInfo = GetAppSpawnHisyseventInfo();
129 APPSPAWN_CHECK(hisyseventInfo != NULL, return NULL, "fail to init hisyseventInfo");
130 int ret = CreateHisysTimerLoop(hisyseventInfo);
131 if (ret != 0) {
132 DeleteHisyseventInfo(hisyseventInfo);
133 hisyseventInfo = NULL;
134 APPSPAWN_LOGE("fail to create hisys timer loop, ret: %{public}d", ret);
135 }
136 return hisyseventInfo;
137 }
138
ReportSpawnChildProcessFail(const char * processName,int32_t errorCode,int32_t spawnResult)139 void ReportSpawnChildProcessFail(const char* processName, int32_t errorCode, int32_t spawnResult)
140 {
141 if (spawnResult == APPSPAWN_SANDBOX_MOUNT_FAIL) {
142 return;
143 }
144 int ret = HiSysEventWrite(HiSysEvent::Domain::APPSPAWN, SPAWN_CHILD_PROCESS_FAIL,
145 HiSysEvent::EventType::FAULT,
146 PROCESS_NAME, processName,
147 ERROR_CODE, errorCode,
148 SPAWN_RESULT, spawnResult);
149 if (ret != 0) {
150 APPSPAWN_LOGE("ReportSpawnChildProcessFail error, ret: %{public}d", ret);
151 }
152 }
153
ReportMountFail(const char * bundleName,const char * srcPath,const char * targetPath,int32_t spawnResult)154 void ReportMountFail(const char* bundleName, const char* srcPath, const char* targetPath,
155 int32_t spawnResult)
156 {
157 if (srcPath == nullptr || (strstr(srcPath, "data/app/el1/") == nullptr &&
158 strstr(srcPath, "data/app/el2/") == nullptr)) {
159 return;
160 }
161 int ret = HiSysEventWrite(HiSysEvent::Domain::APPSPAWN, SPAWN_CHILD_PROCESS_FAIL,
162 HiSysEvent::EventType::FAULT,
163 PROCESS_NAME, bundleName,
164 ERROR_CODE, ERR_APPSPAWN_CHILD_MOUNT_FAILED,
165 SRC_PATH, srcPath,
166 TARGET_PATH, targetPath,
167 SPAWN_RESULT, spawnResult);
168 if (ret != 0) {
169 APPSPAWN_LOGE("ReportMountFail error, ret: %{public}d", ret);
170 }
171 }
172
ReportKeyEvent(const char * eventName)173 void ReportKeyEvent(const char *eventName)
174 {
175 int ret = HiSysEventWrite(HiSysEvent::Domain::APPSPAWN, SPAWN_KEY_EVENT,
176 HiSysEvent::EventType::BEHAVIOR,
177 EVENT_NAME, eventName);
178 if (ret != 0) {
179 APPSPAWN_LOGE("ReportKeyEvent error, ret: %{public}d", ret);
180 }
181 }
182
ReportAbnormalDuration(const char * scene,uint64_t duration)183 void ReportAbnormalDuration(const char* scene, uint64_t duration)
184 {
185 APPSPAWN_LOGI("ReportAbnormalDuration %{public}d with %{public}s %{public}" PRId64 " us",
186 getpid(), scene, duration);
187 int ret = HiSysEventWrite(HiSysEvent::Domain::APPSPAWN, SPAWN_ABNORMAL_DURATION,
188 HiSysEvent::EventType::BEHAVIOR,
189 SCENE_NAME, scene,
190 DURATION, duration);
191 if (ret != 0) {
192 APPSPAWN_LOGE("ReportAbnormalDuration error, ret: %{public}d", ret);
193 }
194 }
195
ReportSpawnProcessDuration(AppSpawnHisysevent * hisysevent,const char * stage)196 void ReportSpawnProcessDuration(AppSpawnHisysevent *hisysevent, const char* stage)
197 {
198 int ret = HiSysEventWrite(HiSysEvent::Domain::APPSPAWN, SPAWN_PROCESS_DURATION,
199 HiSysEvent::EventType::STATISTIC,
200 MAXDURATION, hisysevent->maxDuration,
201 MINDURATION, hisysevent->minDuration,
202 TOTALDURATION, hisysevent->totalDuration,
203 EVENTCOUNT, hisysevent->eventCount,
204 STAGE, stage);
205 if (ret != 0) {
206 APPSPAWN_LOGE("ReportSpawnProcessDuration error, ret: %{public}d", ret);
207 }
208 }
209
ReportSpawnStatisticDuration(const TimerHandle taskHandle,void * content)210 void ReportSpawnStatisticDuration(const TimerHandle taskHandle, void *content)
211 {
212 AppSpawnHisyseventInfo *hisyseventInfo = static_cast<AppSpawnHisyseventInfo *>(content);
213 ReportSpawnProcessDuration(&hisyseventInfo->bootEvent, BOOTSTAGE);
214 ReportSpawnProcessDuration(&hisyseventInfo->manualEvent, BOOTFINISHEDSTAGE);
215
216 InitStatisticEventInfo(hisyseventInfo);
217 }