1 /*
2  * Copyright (c) 2022-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 #ifndef HIVIEWDFX_NAPI_HISYSEVENT_ADAPTER_H
17 #define HIVIEWDFX_NAPI_HISYSEVENT_ADAPTER_H
18 
19 #include <cinttypes>
20 #include <functional>
21 #include <string>
22 #include <unordered_map>
23 #include <vector>
24 
25 #include "hisysevent.h"
26 #include "napi/native_api.h"
27 #include "napi/native_node_api.h"
28 #include "stringfilter.h"
29 #include "write_controller.h"
30 
31 namespace OHOS {
32 namespace HiviewDFX {
33 using namespace Encoded;
34 using JsCallerInfo = std::pair<std::string, int64_t>;
35 enum ParamType { BL = 0, DOU, I64, U64, STR, BOOL_ARR, DOUBLE_ARR, I64_ARR, U64_ARR, STR_ARR };
36 using Param = std::variant<bool, double, int64_t, uint64_t, std::string,
37     std::vector<bool>, std::vector<double>, std::vector<int64_t>, std::vector<uint64_t>,
38     std::vector<std::string>>;
39 
40 using HiSysEventInfo = struct HiSysEventInfo {
41     std::string domain;
42     std::string name;
43     HiSysEvent::EventType eventType;
44     std::unordered_map<std::string, Param> params;
45 };
46 
47 using HiSysEventAsyncContext = struct HiSysEventAsyncContext {
48     napi_env env;
49     napi_async_work asyncWork;
50     napi_deferred deferred;
51     napi_ref callback;
52     HiSysEventInfo eventInfo;
53     int eventWroteResult;
54     JsCallerInfo jsCallerInfo;
55     uint64_t timeStamp;
56 };
57 
58 class NapiHiSysEventAdapter {
59 public:
60     static void Write(const napi_env env, HiSysEventAsyncContext* eventAsyncContext);
61     static void ParseJsCallerInfo(const napi_env env, JsCallerInfo& callerInfo);
62 
63 private:
64     static void CheckThenWriteSysEvent(HiSysEventAsyncContext* eventAsyncContext);
65     static void InnerWrite(HiSysEvent::EventBase& eventBase, const HiSysEventInfo& eventInfo);
66     static int Write(const HiSysEventInfo& eventInfo, uint64_t timeStamp);
67 
68 private:
AppendParams(HiSysEvent::EventBase & eventBase,const std::unordered_map<std::string,Param> & params)69     static void AppendParams(HiSysEvent::EventBase& eventBase,
70         const std::unordered_map<std::string, Param>& params)
71     {
72         const std::vector<std::function<void(const std::string&, const Param&)>> allParamsHandlers = {
73             [&] (const std::string& key, const Param& param) {
74                 (void)HiSysEvent::InnerWrite(eventBase, key, std::get<BL>(param));
75             },
76             [&] (const std::string& key, const Param& param) {
77                 (void)HiSysEvent::InnerWrite(eventBase, key, std::get<DOU>(param));
78             },
79             [&] (const std::string& key, const Param& param) {
80                 (void)HiSysEvent::InnerWrite(eventBase, key, std::get<I64>(param));
81             },
82             [&] (const std::string& key, const Param& param) {
83                 (void)HiSysEvent::InnerWrite(eventBase, key, std::get<U64>(param));
84             },
85             [&] (const std::string& key, const Param& param) {
86                 (void)HiSysEvent::InnerWrite(eventBase, key, std::get<STR>(param));
87             },
88             [&] (const std::string& key, const Param& param) {
89                 (void)HiSysEvent::InnerWrite(eventBase, key, std::get<BOOL_ARR>(param));
90             },
91             [&] (const std::string& key, const Param& param) {
92                 (void)HiSysEvent::InnerWrite(eventBase, key, std::get<DOUBLE_ARR>(param));
93             },
94             [&] (const std::string& key, const Param& param) {
95                 (void)HiSysEvent::InnerWrite(eventBase, key, std::get<I64_ARR>(param));
96             },
97             [&] (const std::string& key, const Param& param) {
98                 (void)HiSysEvent::InnerWrite(eventBase, key, std::get<U64_ARR>(param));
99             },
100             [&] (const std::string& key, const Param& param) {
101                 (void)HiSysEvent::InnerWrite(eventBase, key, std::get<STR_ARR>(param));
102             },
103         };
104         for (auto iter = params.cbegin(); iter != params.cend(); ++iter) {
105             Param param = iter->second;
106             size_t paramIndex = static_cast<size_t>(param.index());
107             if (paramIndex >= allParamsHandlers.size()) {
108                 continue;
109             }
110             auto paramHandler = allParamsHandlers.at(paramIndex);
111             if (paramHandler != nullptr) {
112                 paramHandler(iter->first, param);
113             }
114         }
115     }
116 };
117 } // namespace HiviewDFX
118 } // namespace OHOS
119 
120 #endif // HIVIEWDFX_NAPI_HISYSEVENT_ADAPTER_H