• 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 #include "core/common/recorder/event_recorder.h"
16 
17 #include "base/json/json_util.h"
18 #include "base/log/log_wrapper.h"
19 #include "base/utils/string_utils.h"
20 #include "base/utils/time_util.h"
21 #include "core/common/container.h"
22 #include "core/common/recorder/event_controller.h"
23 #include "core/common/recorder/node_data_cache.h"
24 
25 namespace OHOS::Ace::Recorder {
26 constexpr char IGNORE_WINDOW_NAME[] = "$HA_FLOAT_WINDOW$";
27 
EventParamsBuilder()28 EventParamsBuilder::EventParamsBuilder()
29 {
30     params_ = std::make_shared<std::unordered_map<std::string, std::string>>();
31 }
32 
SetEventType(EventType eventType)33 EventParamsBuilder& EventParamsBuilder::SetEventType(EventType eventType)
34 {
35     eventType_ = eventType;
36     return *this;
37 }
38 
SetId(const std::string & id)39 EventParamsBuilder& EventParamsBuilder::SetId(const std::string& id)
40 {
41     if (!id.empty()) {
42         params_->emplace(KEY_ID, id);
43     }
44     return *this;
45 }
46 
SetType(const std::string & type)47 EventParamsBuilder& EventParamsBuilder::SetType(const std::string& type)
48 {
49     params_->emplace(KEY_TYPE, type);
50     return *this;
51 }
52 
SetDescription(const std::string & desc)53 EventParamsBuilder& EventParamsBuilder::SetDescription(const std::string& desc)
54 {
55     if (!desc.empty()) {
56         params_->emplace(KEY_DESCRIPTION, desc);
57     }
58     return *this;
59 }
60 
SetNavDst(const std::string & dstName)61 EventParamsBuilder& EventParamsBuilder::SetNavDst(const std::string& dstName)
62 {
63     if (!dstName.empty()) {
64         params_->emplace(KEY_NAV_DST, dstName);
65     }
66     return *this;
67 }
68 
SetPageUrl(const std::string & pageUrl)69 EventParamsBuilder& EventParamsBuilder::SetPageUrl(const std::string& pageUrl)
70 {
71     if (!pageUrl.empty()) {
72         params_->emplace(KEY_PAGE, pageUrl);
73     }
74     return *this;
75 }
76 
SetText(const std::string & value)77 EventParamsBuilder& EventParamsBuilder::SetText(const std::string& value)
78 {
79     if (!value.empty()) {
80         params_->emplace(KEY_TEXT, value);
81     }
82     return *this;
83 }
84 
SetChecked(bool value)85 EventParamsBuilder& EventParamsBuilder::SetChecked(bool value)
86 {
87     std::string strVal = value ? "true" : "false";
88     params_->emplace(KEY_CHECKED, strVal);
89     return *this;
90 }
91 
SetIndex(int value)92 EventParamsBuilder& EventParamsBuilder::SetIndex(int value)
93 {
94     params_->emplace(KEY_INDEX, std::to_string(value));
95     return *this;
96 }
97 
SetTextArray(const std::vector<std::string> & value)98 EventParamsBuilder& EventParamsBuilder::SetTextArray(const std::vector<std::string>& value)
99 {
100     auto jsonArray = JsonUtil::CreateArray(true);
101     for (size_t i = 0; i < value.size(); i++) {
102         jsonArray->Put(std::to_string(i).c_str(), value.at(i).c_str());
103     }
104     params_->emplace(KEY_TEXT_ARRAY, jsonArray->ToString());
105     return *this;
106 }
107 
SetExtra(const std::string & key,const std::string & value)108 EventParamsBuilder& EventParamsBuilder::SetExtra(const std::string& key, const std::string& value)
109 {
110     if (!key.empty() && !value.empty()) {
111         params_->emplace(key, value);
112     }
113     return *this;
114 }
115 
build()116 std::shared_ptr<std::unordered_map<std::string, std::string>> EventParamsBuilder::build()
117 {
118     return params_;
119 }
120 
GetEventType() const121 EventType EventParamsBuilder::GetEventType() const
122 {
123     return eventType_;
124 }
125 
GetText() const126 std::string EventParamsBuilder::GetText() const
127 {
128     auto iter = params_->find(KEY_TEXT);
129     if (iter != params_->end()) {
130         return iter->second;
131     }
132     return "";
133 }
134 
ToString() const135 std::string EventParamsBuilder::ToString() const
136 {
137     std::stringstream ss;
138     ss << "{";
139     if (eventType_ != EventType::INVALID) {
140         ss << "eventType:" << eventType_ << ", ";
141     }
142     for (auto&& it : *params_) {
143         ss << it.first << ":" << it.second << ", ";
144     }
145     ss << "}";
146     return ss.str();
147 }
148 
MapToString(const std::shared_ptr<std::unordered_map<std::string,std::string>> & input)149 std::string MapToString(const std::shared_ptr<std::unordered_map<std::string, std::string>>& input)
150 {
151     if (!input) {
152         return "";
153     }
154     std::stringstream ss;
155     ss << "{";
156     for (auto it = input->begin(); it != input->end(); it++) {
157         ss << it->first << ":" << it->second << ", ";
158     }
159     ss << "}";
160     return ss.str();
161 }
162 
Get()163 EventRecorder& EventRecorder::Get()
164 {
165     static EventRecorder eventRecorder;
166     return eventRecorder;
167 }
168 
EventRecorder()169 EventRecorder::EventRecorder() {}
170 
UpdateEventSwitch(const EventSwitch & eventSwitch)171 void EventRecorder::UpdateEventSwitch(const EventSwitch& eventSwitch)
172 {
173     eventSwitch_ = eventSwitch;
174 }
175 
IsPageRecordEnable() const176 bool EventRecorder::IsPageRecordEnable() const
177 {
178     return pageEnable_ && eventSwitch_.pageEnable;
179 }
180 
IsExposureRecordEnable() const181 bool EventRecorder::IsExposureRecordEnable() const
182 {
183     return exposureEnable_ && eventSwitch_.exposureEnable;
184 }
185 
IsComponentRecordEnable() const186 bool EventRecorder::IsComponentRecordEnable() const
187 {
188     return componentEnable_ && eventSwitch_.componentEnable;
189 }
190 
SetContainerInfo(const std::string & windowName,int32_t id,bool foreground)191 void EventRecorder::SetContainerInfo(const std::string& windowName, int32_t id, bool foreground)
192 {
193     if (windowName == IGNORE_WINDOW_NAME) {
194         return;
195     }
196     if (foreground) {
197         containerId_ = id;
198         containerCount_++;
199     } else {
200         containerCount_--;
201     }
202     if (containerCount_ <= 0) {
203         containerCount_ = 0;
204         containerId_ = -1;
205     }
206 }
207 
SetFocusContainerInfo(const std::string & windowName,int32_t id)208 void EventRecorder::SetFocusContainerInfo(const std::string& windowName, int32_t id)
209 {
210     if (windowName == IGNORE_WINDOW_NAME) {
211         return;
212     }
213     focusContainerId_ = id;
214 }
215 
GetContainerId()216 int32_t EventRecorder::GetContainerId()
217 {
218     if (containerId_ == -1) {
219         return -1;
220     }
221     return focusContainerId_;
222 }
223 
GetPageUrl()224 const std::string& EventRecorder::GetPageUrl()
225 {
226     if (pageUrl_.empty()) {
227         pageUrl_ = GetCurrentPageUrl();
228     }
229     return pageUrl_;
230 }
231 
GetNavDstName() const232 const std::string& EventRecorder::GetNavDstName() const
233 {
234     return navDstName_;
235 }
236 
OnPageShow(const std::string & pageUrl,const std::string & param)237 void EventRecorder::OnPageShow(const std::string& pageUrl, const std::string& param)
238 {
239     pageUrl_ = pageUrl;
240     NodeDataCache::Get().OnPageShow(pageUrl);
241     Recorder::EventParamsBuilder builder;
242     builder.SetType(std::to_string(PageEventType::ROUTER_PAGE))
243         .SetText(pageUrl)
244         .SetExtra(Recorder::KEY_PAGE_PARAM, param);
245     EventController::Get().NotifyEvent(
246         EventCategory::CATEGORY_PAGE, static_cast<int32_t>(EventType::PAGE_SHOW), std::move(builder.build()));
247 }
248 
OnPageHide(const std::string & pageUrl,const int64_t duration)249 void EventRecorder::OnPageHide(const std::string& pageUrl, const int64_t duration)
250 {
251     Recorder::EventParamsBuilder builder;
252     builder.SetType(std::to_string(PageEventType::ROUTER_PAGE))
253         .SetText(pageUrl)
254         .SetExtra(KEY_DURATION, std::to_string(duration));
255     EventController::Get().NotifyEvent(
256         EventCategory::CATEGORY_PAGE, static_cast<int32_t>(EventType::PAGE_HIDE), std::move(builder.build()));
257 }
258 
OnClick(EventParamsBuilder && builder)259 void EventRecorder::OnClick(EventParamsBuilder&& builder)
260 {
261     if (!taskExecutor_) {
262         auto container = Container::Current();
263         CHECK_NULL_VOID(container);
264         taskExecutor_ = container->GetTaskExecutor();
265     }
266     CHECK_NULL_VOID(taskExecutor_);
267     builder.SetPageUrl(GetPageUrl());
268     builder.SetNavDst(navDstName_);
269     auto params = builder.build();
270     taskExecutor_->PostTask(
271         [taskExecutor = taskExecutor_, params]() {
272             EventController::Get().NotifyEvent(
273                 EventCategory::CATEGORY_COMPONENT, static_cast<int32_t>(EventType::CLICK), std::move(params));
274         },
275         TaskExecutor::TaskType::UI);
276 }
277 
OnChange(EventParamsBuilder && builder)278 void EventRecorder::OnChange(EventParamsBuilder&& builder)
279 {
280     builder.SetPageUrl(GetPageUrl());
281     builder.SetNavDst(navDstName_);
282     auto params = builder.build();
283     EventController::Get().NotifyEvent(
284         EventCategory::CATEGORY_COMPONENT, static_cast<int32_t>(EventType::CHANGE), std::move(params));
285 }
286 
OnEvent(EventParamsBuilder && builder)287 void EventRecorder::OnEvent(EventParamsBuilder&& builder)
288 {
289     builder.SetPageUrl(GetPageUrl());
290     builder.SetNavDst(navDstName_);
291     auto eventType = builder.GetEventType();
292     auto params = builder.build();
293     EventController::Get().NotifyEvent(
294         EventCategory::CATEGORY_COMPONENT, static_cast<int32_t>(eventType), std::move(params));
295 }
296 
OnNavDstShow(EventParamsBuilder && builder)297 void EventRecorder::OnNavDstShow(EventParamsBuilder&& builder)
298 {
299     navDstName_ = builder.GetText();
300     navShowTime_ = GetCurrentTimestamp();
301     builder.SetPageUrl(GetPageUrl());
302     builder.SetType(std::to_string(PageEventType::NAV_PAGE));
303     auto params = builder.build();
304     EventController::Get().NotifyEvent(
305         EventCategory::CATEGORY_PAGE, static_cast<int32_t>(EventType::PAGE_SHOW), std::move(params));
306 }
307 
OnNavDstHide(EventParamsBuilder && builder)308 void EventRecorder::OnNavDstHide(EventParamsBuilder&& builder)
309 {
310     if (builder.GetText() == navDstName_) {
311         navDstName_ = "";
312         if (navShowTime_ > 0) {
313             int64_t duration = GetCurrentTimestamp() - navShowTime_;
314             builder.SetExtra(KEY_DURATION, std::to_string(duration));
315             navShowTime_ = 0;
316         }
317     }
318     builder.SetPageUrl(GetPageUrl());
319     builder.SetType(std::to_string(PageEventType::NAV_PAGE));
320     auto params = builder.build();
321     EventController::Get().NotifyEvent(
322         EventCategory::CATEGORY_PAGE, static_cast<int32_t>(EventType::PAGE_HIDE), std::move(params));
323 }
324 
OnExposure(EventParamsBuilder && builder)325 void EventRecorder::OnExposure(EventParamsBuilder&& builder)
326 {
327     auto params = builder.build();
328     EventController::Get().NotifyEvent(
329         EventCategory::CATEGORY_EXPOSURE, static_cast<int32_t>(EventType::EXPOSURE), std::move(params));
330 }
331 } // namespace OHOS::Ace::Recorder
332