• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "sys_event.h"
17 
18 #include <inttypes.h>
19 #include <time.h>
20 #include <sys/time.h>
21 
22 #include "bootevent.h"
23 #include "init_module_engine.h"
24 #include "init_param.h"
25 #include "plugin_adapter.h"
26 #include "securec.h"
27 
28 typedef struct {
29     char *buffer;
30     uint32_t bufferLen;
31     uint32_t currLen;
32 } EventArgs;
33 
GetServiceName(const char * paramName,char * buffer,size_t buffSize)34 static int GetServiceName(const char *paramName, char *buffer, size_t buffSize)
35 {
36     size_t len = strlen(paramName);
37     size_t i = 0;
38     for (size_t index = strlen("bootevent."); index < len; index++) {
39         PLUGIN_CHECK(i <= buffSize, return -1);
40         if (*(paramName + index) == '.') {
41             break;
42         }
43         buffer[i++] = *(paramName + index);
44     }
45     return (int)i;
46 }
47 
TraversalEvent(ListNode * node,void * root)48 static int TraversalEvent(ListNode *node, void *root)
49 {
50     BOOT_EVENT_PARAM_ITEM *item = (BOOT_EVENT_PARAM_ITEM *)node;
51     if (item->flags != BOOTEVENT_TYPE_SERVICE) {
52         return 0;
53     }
54     EventArgs *args = (EventArgs *)root;
55     int len = GetServiceName(item->paramName, args->buffer + args->currLen, args->bufferLen - args->currLen);
56     PLUGIN_CHECK(len > 0 && (((uint32_t)len + args->currLen) < args->bufferLen), return -1,
57         "Failed to format service name %s", item->paramName);
58     args->currLen += (uint32_t)len;
59 
60     len = sprintf_s(args->buffer + args->currLen, args->bufferLen - args->currLen, ",%u:%u,%u:%u;",
61         (uint32_t)item->timestamp[BOOTEVENT_FORK].tv_sec,
62         (uint32_t)(item->timestamp[BOOTEVENT_FORK].tv_nsec / USTONSEC),
63         (uint32_t)item->timestamp[BOOTEVENT_READY].tv_sec,
64         (uint32_t)(item->timestamp[BOOTEVENT_READY].tv_nsec / USTONSEC));
65     PLUGIN_CHECK(len > 0 && (((uint32_t)len + args->currLen) < args->bufferLen), return -1,
66         "Failed to format service time %s", item->paramName);
67     args->currLen += (uint32_t)len;
68     return 0;
69 }
70 
ReportBootEventComplete(ListNode * events)71 PLUGIN_STATIC void ReportBootEventComplete(ListNode *events)
72 {
73     PLUGIN_CHECK(events != NULL, return, "Invalid events");
74     struct timespec curr = {0};
75     int ret = clock_gettime(CLOCK_MONOTONIC, &curr);
76     PLUGIN_CHECK(ret == 0, return);
77 
78     char *buffer = (char *)calloc(MAX_BUFFER_FOR_EVENT + PARAM_VALUE_LEN_MAX, 1);
79     PLUGIN_CHECK(buffer != NULL, return, "Failed to get memory for sys event ");
80     EventArgs args = { buffer, MAX_BUFFER_FOR_EVENT, 0 };
81     OH_ListTraversal(events, (void *)&args, TraversalEvent, 0);
82     if ((args.currLen > 1) && (args.currLen < MAX_BUFFER_FOR_EVENT)) {
83         buffer[args.currLen - 1] = '\0';
84     }
85 
86     StartupTimeEvent startupTime = {};
87     startupTime.event.type = STARTUP_TIME;
88     startupTime.totalTime = curr.tv_sec;
89     startupTime.totalTime = startupTime.totalTime * MSECTONSEC;
90     startupTime.totalTime += curr.tv_nsec / USTONSEC;
91     startupTime.detailTime = buffer;
92     char *reason = buffer + MAX_BUFFER_FOR_EVENT;
93     uint32_t size = PARAM_VALUE_LEN_MAX;
94     ret = SystemReadParam("ohos.boot.bootreason", reason, &size);
95     if (ret == 0) {
96         startupTime.reason = reason;
97         startupTime.firstStart = 1;
98     } else {
99         startupTime.reason = "";
100         startupTime.firstStart = 0;
101     }
102     PLUGIN_LOGI("SysEventInit %u.%u detailTime len %u '%s'",
103         (uint32_t)curr.tv_sec, (uint32_t)(curr.tv_nsec / USTONSEC), args.currLen, startupTime.detailTime);
104     ReportSysEvent(&startupTime.event);
105     free(buffer);
106 }
107 
108 #ifndef STARTUP_INIT_TEST // do not install
MODULE_CONSTRUCTOR(void)109 MODULE_CONSTRUCTOR(void)
110 {
111     ReportBootEventComplete(GetBootEventList());
112 }
113 #endif
114