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 "plugin_factory.h"
16#include "app_event_publisher_factory.h"
17#include "XperfPlugin.h"
18#include "EvtParser.h"
19#include "JlogId.h"
20#include "EventObserverConverter.h"
21#include "NormalContext.h"
22#include "hiview_logger.h"
23
24namespace OHOS {
25    namespace HiviewDFX {
26        const std::string EvtParser::separator = ":";
27
28        const std::map<std::string, unsigned int> EvtParser::logIdMap = {
29            {"GRAPHIC:JANK_FRAME_SKIP",                         JLID_JANK_FRAME_SKIP},
30            {"AAFWK:START_ABILITY",                             JLID_START_ABILITY},
31            {"AAFWK:ABILITY_ONFOREGROUND",                      JLID_ABILITY_ONFOREGROUND},
32            {"AAFWK:APP_FOREGROUND",                            JLID_APP_FOREGROUND},
33            {"AAFWK:ABILITY_ONACTIVE",                          JLID_ABILITY_ONACTIVE},
34            {"KERNEL_WAKEUP:LID_WAKEUP_END",                    JLID_LID_WAKEUP_END},
35            {"LCD:LCD_POWER_OFF",                               JLID_LCD_POWER_OFF},
36            {"AAFWK:TERMINATE_ABILITY",                         JLID_AAFWK_TERMINATE_ABILITY},
37            {"AAFWK:APP_BACKGROUND",                            JLID_APP_BACKGROUND},
38            {"AAFWK:ABILITY_ONBACKGROUND",                      JLID_ABILITY_ONBACKGROUND},
39            {"AAFWK:APP_TERMINATE",                             JLID_APP_TERMINATE},
40            {"AAFWK:APP_ATTACH",                                JLID_APP_ATTACH},
41            {"GRAPHIC:RS_COMPOSITION_TIMEOUT",                  JLID_RS_COMPOSITION_TIMEOUT},
42            {"KERNEL_WAKEUP:LID_WAKEUP_START",                  JLID_LID_WAKEUP_START},
43            {"SCREENLOCK_APP:SCREENON_EVENT",                   JLID_SCREENON_EVENT},
44            {"LCD:LCD_POWER_ON",                                JLID_LCD_POWER_ON},
45            {"LCD:LCD_BACKLIGHT_ON",                            JLID_LCD_BACKLIGHT_ON},
46            {"MULTIMODALINPUT:INPUT_POWER_DOWN",                JLID_INPUT_POWER_DOWN},
47            {"LCD:LCD_BACKLIGHT_OFF",                           JLID_LCD_BACKLIGHT_OFF},
48            {"POWER:STATE",                                     JLID_POWER_STATE},
49            {"GRAPHIC:INTERACTION_RESPONSE_LATENCY",            JLID_GRAPHIC_INTERACTION_RESPONSE_LATENCY},
50            {"GRAPHIC:INTERACTION_COMPLETED_LATENCY",           JLID_GRAPHIC_INTERACTION_COMPLETED_LATENCY},
51            {"AAFWK:DRAWN_COMPLETED",                           JLID_AAFWK_DRAWN_COMPLETED},
52            {"INIT:STARTUP_TIME",                               JLID_INIT_STARTUP_TIME},
53            {"AAFWK:APP_STARTUP_TYPE",                          JLID_AAFWK_APP_STARTUP_TYPE},
54            {"AAFWK:PROCESS_START",                             JLID_AAFWK_PROCESS_START},
55            {"WINDOWMANAGER:START_WINDOW",                      JLID_WINDOWMANAGER_START_WINDOW},
56            {"GRAPHIC:FIRST_FRAME_DRAWN",                       JLID_GRAPHIC_FIRST_FRAME_DRAWN},
57            {"ACE:INTERACTION_COMPLETED_LATENCY",               JLID_ACE_INTERACTION_COMPLETED_LATENCY},
58            {"ACE:INTERACTION_APP_JANK",                        JLID_ACE_INTERACTION_APP_JANK},
59            {"GRAPHIC:INTERACTION_RENDER_JANK",                 JLID_GRAPHIC_INTERACTION_RENDER_JANK},
60            {"AAFWK:CLOSE_ABILITY",                             JLID_AAFWK_CLOSE_ABILITY},
61            {"AAFWK:PROCESS_EXIT",                              JLID_AAFWK_PROCESS_EXIT},
62            {"SCENE_BOARD_APP:SCENE_PANEL_ROTATION_END",        JLID_SCENE_BOARD_APP_CONTAINER_ANIMATION_END},
63            {"SCENE_BOARD_APP:SCREENUNLOCK_EVENT",              JLID_BOARD_SCREENUNLOCK_EVENT},
64            {"SCENE_BOARD_APP:CLICK_BUTTON_EVENT",              JLID_BOARD_CLICK_BUTTON_EVENT},
65            {"SCENE_BOARD_APP:START_UNLOCK",                    JLID_BOARD_START_UNLOCK},
66            {"SCENE_BOARD_APP:UNLOCK_TO_GRID_ANIMATION_END",    JLID_BOARD_UNLOCK_TO_GRID_ANIMATION_END},
67            {"SCENE_BOARD_APP:UNLOCK_TO_DOCK_ANIMATION_END",    JLID_BOARD_UNLOCK_TO_DOCK_ANIMATION_END},
68            {"SCREEN_RECORDER:RECORDER_STOP",                   JLID_SCREEN_RECORDER_STOP},
69            {"ACE:JANK_FRAME_APP",                              JLID_JANK_FRAME_APP},
70            {"WINDOWMANAGER:FOCUS_WINDOW",                      JLID_WINDOWMANAGER_FOCUS_WINDOW},
71            {"RSS:APP_ASSOCIATED_START",                        JLID_APP_ASSOCIATED_START},
72            {"SCENE_BOARD_APP:SCREEN_ON_ANIMATION",             JLID_SCENE_BOARD_APP_SCREEN_ON_ANIMATION},
73            {"XGATE:XGATE_WIFI_CONNECT_START",                  JLID_XGATE_WIFI_CONNECT_START},
74            {"XGATE:XGATE_WIFI_CONNECT_END",                    JLID_XGATE_WIFI_CONNECT_END},
75            {"XGATE:XGATE_SPES_LOGIN_START",                    JLID_XGATE_SPES_LOGIN_START},
76            {"XGATE:XGATE_SPES_LOGIN_END",                      JLID_XGATE_SPES_LOGIN_END},
77            {"XGATE:XGATE_IACCESS_LOGIN_START",                 JLID_XGATE_IACCESS_LOGIN_START},
78            {"XGATE:XGATE_IACCESS_LOGIN_END",                   JLID_XGATE_IACCESS_LOGIN_END},
79            {"WINDOWMANAGER:FOLD_STATE_CHANGE_BEGIN",           JLID_FOLD_STATE_CHANGE_BEGIN},
80            {"PERFORMANCE:PERF_FACTORY_TEST_START",             JLID_PERF_FACTORY_TEST_START},
81            {"PERFORMANCE:PERF_FACTORY_TEST_STOP",              JLID_PERF_FACTORY_TEST_STOP},
82            {"PERFORMANCE:PERF_FACTORY_TEST_CLEAR",             JLID_PERF_FACTORY_TEST_CLEAR},
83            {"RSS:LIMIT_BOOST",                                 JLID_LIMIT_BOOST},
84            {"RSS:LIMIT_REQUEST",                               JLID_LIMIT_FREQUENCY},
85            {"GRAPHIC:HGM_VOTER_INFO",                          JLID_LTPO_DYNAMICS_FRAME},
86            {"GRAPHIC:SHADER_MALFUNCTION",                      JLID_SHADER_MALFUNCTION},
87            {"GRAPHIC:SHADER_STATS",                            JLID_SHADER_STATS},
88            {"WEBVIEW:PAGE_LOAD_TIME",                          JLID_WEBVIEW_PAGE_LOAD},
89            {"WEBVIEW:DYNAMIC_FRAME_DROP_STATISTICS",           JLID_WEBVIEW_DYNAMIC_FRAME_DROP},
90            {"WEBVIEW:AUDIO_FRAME_DROP_STATISTICS",             JLID_WEBVIEW_AUDIO_FRAME_DROP},
91            {"WEBVIEW:VIDEO_FRAME_DROP_STATISTICS",             JLID_WEBVIEW_VIDEO_FRAME_DROP},
92            {"GRAPHIC:INTERACTION_HITCH_TIME_RATIO",            JLID_GRAPHIC_INTERACTION_HITCH_TIME_RATIO}
93        };
94
95        REGISTER(XperfPlugin);
96        REGISTER_PUBLISHER(XperfPlugin);
97        DEFINE_LOG_LABEL(0xD002D66, "Hiview-XPerformance");
98
99        void XperfPlugin::OnLoad()
100        {
101            HIVIEW_LOGI("XperfPlugin::OnLoad");
102            SetName(PLUGIN_NAME);
103            SetVersion(PLUGIN_VERSION);
104            NormalInit();
105            HIVIEW_LOGI("Xperf Plugin Load Finish");
106        }
107
108        void XperfPlugin::OnUnload()
109        {
110            HIVIEW_LOGI("Xperf Plugin OnUnload.");
111        }
112
113        void XperfPlugin::OnEventListeningCallback(const Event &event)
114        {
115            HIVIEW_LOGD("Xperf Listening Event is %{public}s", (event.eventName_).c_str());
116            if (event.messageType_ != Event::MessageType::SYS_EVENT) {
117                HIVIEW_LOGW("Event is not Sys event type");
118                return;
119            }
120            Event& eventRef = const_cast<Event&>(event);
121            SysEvent& sysEvent = static_cast<SysEvent&>(eventRef);
122            XperfDispatch(sysEvent);
123        }
124
125        void XperfPlugin::AddAppEventHandler(std::shared_ptr<AppEventHandler> handler)
126        {
127            this->appEventHandler = handler;
128        }
129
130        void XperfPlugin::NormalInit()
131        {
132            /* create context */
133            perfContext = std::make_shared<NormalContext>();
134            /* create monitors here */
135            perfContext->CreateContext();
136            /* register Observer */
137            IEventObservable* eventObservable = perfContext->GetEventObservable();
138            if (eventObservable != nullptr) {
139                eventObservable->RegObserver(this);
140            } else {
141                HIVIEW_LOGW("[XperfPlugin::OnLoad] eventObservable is null");
142            }
143        }
144
145        void XperfPlugin::XperfDispatch(const SysEvent& sysEvent)
146        {
147            try {
148                std::shared_ptr<XperfEvt> evt = EvtParser::FromHivewEvt(sysEvent);
149                DispatchToMonitor(evt->logId, evt);
150            }
151            catch (std::out_of_range& outEx) {
152                std::string logIdStr = std::string(sysEvent.domain_ + EvtParser::separator + sysEvent.eventName_);
153                HIVIEW_LOGW("event %{public}s not exist in logIdMap", logIdStr.c_str());
154            }
155            catch (std::invalid_argument& logIdEx) {
156                HIVIEW_LOGW("dispatch exception: %{public}s", logIdEx.what());
157            }
158        }
159
160        void XperfPlugin::DispatchToMonitor(unsigned int logId, std::shared_ptr<XperfEvt> xperfEvt)
161        {
162            std::vector<IMonitor*> monitorVec;
163            try {
164                monitorVec = perfContext->GetMonitorsByLogID(logId);
165            } catch (const std::invalid_argument& ex) {
166                HIVIEW_LOGW("[XperfPlugin::DispatchToMonitor] no monitor register for %{public}d", logId);
167                return;
168            }
169            for (IMonitor* monitor : monitorVec) {
170                monitor->HandleEvt(xperfEvt);
171            }
172        }
173
174        void XperfPlugin::PostAppStartEvent(const AppStartInfo& ase)
175        {
176            if (appEventHandler != nullptr) {
177                AppEventHandler::AppLaunchInfo appLaunchInfo = EventObserverConverter::ConvertToAppStartInfo(ase);
178                HIVIEW_LOGD("[XperfPlugin::PostAppStartEvent] PostEvent begin");
179                appEventHandler->PostEvent(appLaunchInfo);
180                HIVIEW_LOGD("[XperfPlugin::PostAppStartEvent] PostEvent end");
181            } else {
182                HIVIEW_LOGW("[XperfPlugin::PostAppStartEvent] appEventHandler is null");
183            }
184        }
185
186        void XperfPlugin::PostScrollJankEvent(const ScrollJankInfo& sji)
187        {
188            if (appEventHandler != nullptr) {
189                ScrollJankEvtInfo scrollJankEvtInfo = EventObserverConverter::ConvertToScrollJankEvtInfo(sji);
190                HIVIEW_LOGD("[XperfPlugin::PostScrollJankEvent] PostEvent begin");
191                appEventHandler->PostEvent(scrollJankEvtInfo);
192                HIVIEW_LOGD("[XperfPlugin::PostScrollJankEvent] PostEvent end");
193            } else {
194                HIVIEW_LOGW("[XperfPlugin::PostScrollJankEvent] appEventHandler is null");
195            }
196        }
197
198    } // HiviewDFX
199} // OHOS