1/*
2 * Copyright (c) 2022 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 "base/log/frame_report.h"
17
18#include <dlfcn.h>
19#include <frame_collector.h>
20
21#include "base/utils/utils.h"
22
23namespace OHOS::Ace {
24namespace {
25const std::string FRAME_AWARE_SO_PATH = "libframe_ui_intf.z.so";
26} // namespace
27FrameReport& FrameReport::GetInstance()
28{
29    static FrameReport instance;
30    return instance;
31}
32
33FrameReport::FrameReport() {}
34
35FrameReport::~FrameReport()
36{
37    CloseLibrary();
38}
39
40bool FrameReport::LoadLibrary()
41{
42    if (!frameSchedSoLoaded_) {
43        frameSchedHandle_ = dlopen(FRAME_AWARE_SO_PATH.c_str(), RTLD_LAZY);
44        CHECK_NULL_RETURN(frameSchedHandle_, false);
45        frameInitFunc_ = (FrameInitFunc)LoadSymbol("Init");
46        CHECK_NULL_RETURN(frameInitFunc_, false);
47        frameGetEnableFunc_ = (FrameGetEnableFunc)LoadSymbol("GetSenseSchedEnable");
48        CHECK_NULL_RETURN(frameGetEnableFunc_, false);
49        beginFlushAnimationFunc_ = (BeginFlushAnimationFunc)LoadSymbol("BeginFlushAnimation");
50        CHECK_NULL_RETURN(beginFlushAnimationFunc_, false);
51        endFlushAnimationFunc_ = (EndFlushAnimationFunc)LoadSymbol("EndFlushAnimation");
52        CHECK_NULL_RETURN(endFlushAnimationFunc_, false);
53        beginFlushBuildFunc_ = (BeginFlushBuildFunc)LoadSymbol("BeginFlushBuild");
54        CHECK_NULL_RETURN(beginFlushBuildFunc_, false);
55        endFlushBuildFunc_ = (EndFlushBuildFunc)LoadSymbol("EndFlushBuild");
56        CHECK_NULL_RETURN(endFlushBuildFunc_, false);
57        beginFlushLayoutFunc_ = (BeginFlushLayoutFunc)LoadSymbol("BeginFlushLayout");
58        CHECK_NULL_RETURN(beginFlushLayoutFunc_, false);
59        endFlushLayoutFunc_ = (EndFlushLayoutFunc)LoadSymbol("EndFlushLayout");
60        CHECK_NULL_RETURN(endFlushLayoutFunc_, false);
61        beginFlushRenderFunc_ = (BeginFlushRenderFunc)LoadSymbol("BeginFlushRender");
62        CHECK_NULL_RETURN(beginFlushRenderFunc_, false);
63        endFlushRenderFunc_ = (EndFlushRenderFunc)LoadSymbol("EndFlushRender");
64        CHECK_NULL_RETURN(endFlushRenderFunc_, false);
65        beginFlushRenderFinishFunc_ = (BeginFlushRenderFinishFunc)LoadSymbol("BeginFlushRenderFinish");
66        CHECK_NULL_RETURN(beginFlushRenderFinishFunc_, false);
67        endFlushRenderFinishFunc_ = (EndFlushRenderFinishFunc)LoadSymbol("EndFlushRenderFinish");
68        CHECK_NULL_RETURN(endFlushRenderFinishFunc_, false);
69        beginProcessPostFunc_ = (BeginProcessPostFlushFunc)LoadSymbol("BeginProcessPostFlush");
70        CHECK_NULL_RETURN(beginProcessPostFunc_, false);
71        beginListFlingFunc_ = (BeginListFlingFunc)LoadSymbol("BeginListFling");
72        CHECK_NULL_RETURN(beginListFlingFunc_, false);
73        endListFlingFunc_ = (EndListFlingFunc)LoadSymbol("EndListFling");
74        CHECK_NULL_RETURN(endListFlingFunc_, false);
75        flushBeginFunc_ = (FlushBeginFunc)LoadSymbol("FlushBegin");
76        CHECK_NULL_RETURN(flushBeginFunc_, false);
77        flushEndFunc_ = (FlushEndFunc)LoadSymbol("FlushEnd");
78        CHECK_NULL_RETURN(flushEndFunc_, false);
79        setFrameParamFunc_ = (SetFrameParamFunc)LoadSymbol("SetFrameParam");
80        CHECK_NULL_RETURN(setFrameParamFunc_, false);
81        enableSelfRenderFunc_ = (EnableSelfRenderFunc)LoadSymbol("EnableSelfRender");
82        CHECK_NULL_RETURN(enableSelfRenderFunc_, false);
83        disableSelfRenderFunc_ = (DisableSelfRenderFunc)LoadSymbol("DisableSelfRender");
84        CHECK_NULL_RETURN(disableSelfRenderFunc_, false);
85        frameSchedSoLoaded_ = true;
86    }
87    return true;
88}
89
90void FrameReport::CloseLibrary()
91{
92    if (dlclose(frameSchedHandle_) != 0) {
93        LOGE("frame-ace:[CloseLibrary]libframe_ui_intf.so failed!\n");
94        return;
95    }
96    frameSchedHandle_ = nullptr;
97    frameSchedSoLoaded_ = false;
98}
99
100void* FrameReport::LoadSymbol(const char* symName)
101{
102    CHECK_NULL_RETURN(frameSchedHandle_, nullptr);
103    return dlsym(frameSchedHandle_, symName);
104}
105
106void FrameReport::Init()
107{
108    if (LoadLibrary()) {
109        frameInitFunc_();
110        enable_ = frameGetEnableFunc_() != 0;
111    }
112}
113
114int FrameReport::GetEnable()
115{
116    return true;
117}
118
119int FrameReport::GetFrameReportEnable()
120{
121    if (!frameSchedSoLoaded_) {
122        return 0;
123    }
124    return frameGetEnableFunc_();
125}
126
127void FrameReport::BeginFlushAnimation()
128{
129    Rosen::FrameCollector::GetInstance().MarkFrameEvent(Rosen::FrameEventType::AnimateStart);
130    if (!enable_) {
131        return;
132    }
133    beginFlushAnimationFunc_();
134}
135
136void FrameReport::EndFlushAnimation()
137{
138    Rosen::FrameCollector::GetInstance().MarkFrameEvent(Rosen::FrameEventType::AnimateEnd);
139    if (!enable_) {
140        return;
141    }
142    endFlushAnimationFunc_();
143}
144
145void FrameReport::BeginFlushBuild()
146{
147    Rosen::FrameCollector::GetInstance().MarkFrameEvent(Rosen::FrameEventType::BuildStart);
148    if (!enable_) {
149        return;
150    }
151    beginFlushBuildFunc_();
152}
153
154void FrameReport::EndFlushBuild()
155{
156    Rosen::FrameCollector::GetInstance().MarkFrameEvent(Rosen::FrameEventType::BuildEnd);
157    if (!enable_) {
158        return;
159    }
160    endFlushBuildFunc_();
161}
162
163void FrameReport::BeginFlushLayout()
164{
165    Rosen::FrameCollector::GetInstance().MarkFrameEvent(Rosen::FrameEventType::LayoutStart);
166    if (!enable_) {
167        return;
168    }
169    beginFlushLayoutFunc_();
170}
171
172void FrameReport::EndFlushLayout()
173{
174    Rosen::FrameCollector::GetInstance().MarkFrameEvent(Rosen::FrameEventType::LayoutEnd);
175    if (!enable_) {
176        return;
177    }
178    endFlushLayoutFunc_();
179}
180
181void FrameReport::BeginFlushRender()
182{
183    Rosen::FrameCollector::GetInstance().MarkFrameEvent(Rosen::FrameEventType::DrawStart);
184    if (!enable_) {
185        return;
186    }
187    beginFlushRenderFunc_();
188}
189
190void FrameReport::EndFlushRender()
191{
192    if (!enable_) {
193        return;
194    }
195    endFlushRenderFunc_();
196}
197
198void FrameReport::BeginFlushRenderFinish()
199{
200    if (!enable_) {
201        return;
202    }
203    beginFlushRenderFinishFunc_();
204}
205
206void FrameReport::EndFlushRenderFinish()
207{
208    Rosen::FrameCollector::GetInstance().MarkFrameEvent(Rosen::FrameEventType::DrawEnd);
209    if (!enable_) {
210        return;
211    }
212    endFlushRenderFinishFunc_();
213}
214
215void FrameReport::BeginProcessPostFlush()
216{
217    if (!enable_) {
218        return;
219    }
220    beginProcessPostFunc_();
221}
222
223void FrameReport::BeginListFling()
224{
225    if (!enable_) {
226        return;
227    }
228    beginListFlingFunc_();
229}
230
231void FrameReport::EndListFling()
232{
233    if (!enable_) {
234        return;
235    }
236    endListFlingFunc_();
237}
238
239void FrameReport::FlushBegin()
240{
241    if (!enable_) {
242        return;
243    }
244    flushBeginFunc_();
245}
246
247void FrameReport::FlushEnd()
248{
249    if (!enable_) {
250        return;
251    }
252    flushEndFunc_();
253}
254
255void FrameReport::SetFrameParam(int requestId, int load, int schedFrameNum, int value)
256{
257    if (!enable_) {
258        return;
259    }
260    setFrameParamFunc_(requestId, load, schedFrameNum, value);
261}
262
263void FrameReport::EnableSelfRender()
264{
265    if (!enable_) {
266        return;
267    }
268    enableSelfRenderFunc_();
269}
270
271void FrameReport::DisableSelfRender()
272{
273    if (!enable_) {
274        return;
275    }
276    disableSelfRenderFunc_();
277}
278} // namespace OHOS::Ace
279