• 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/node_data_cache.h"
16 
17 #include <string>
18 
19 #include "base/json/json_util.h"
20 #include "base/log/log_wrapper.h"
21 #include "core/common/container.h"
22 #include "core/common/recorder/event_recorder.h"
23 
24 namespace OHOS::Ace::Recorder {
25 constexpr int32_t PAGE_URL_SUFFIX_LENGTH = 3;
26 
GetCurrentPageUrl()27 const std::string GetCurrentPageUrl()
28 {
29     CHECK_RUN_ON(UI);
30     auto container = Container::Current();
31     CHECK_NULL_RETURN(container, "");
32     auto frontEnd = container->GetFrontend();
33     CHECK_NULL_RETURN(frontEnd, "");
34     auto pageUrl = frontEnd->GetCurrentPageUrl();
35     // remove .js suffix if exists
36     if (StringUtils::EndWith(pageUrl, ".js")) {
37         return pageUrl.substr(0, pageUrl.length() - PAGE_URL_SUFFIX_LENGTH);
38     }
39     return pageUrl;
40 }
41 
Get()42 NodeDataCache& NodeDataCache::Get()
43 {
44     static NodeDataCache cache;
45     return cache;
46 }
47 
NodeDataCache()48 NodeDataCache::NodeDataCache()
49 {
50     container_ = std::make_shared<NodeDataContainer>();
51     mergedConfig_ = std::make_shared<MergedConfig>();
52 }
53 
OnPageReady()54 void NodeDataCache::OnPageReady()
55 {
56     prePageUrl_ = pageUrl_;
57     pageUrl_ = GetCurrentPageUrl();
58 }
59 
OnPageShow(const std::string & pageUrl)60 void NodeDataCache::OnPageShow(const std::string& pageUrl)
61 {
62     prePageUrl_ = pageUrl_;
63     pageUrl_ = pageUrl;
64 }
65 
OnBeforePagePop(bool destroy)66 void NodeDataCache::OnBeforePagePop(bool destroy)
67 {
68     if (destroy) {
69         Clear(prePageUrl_);
70     } else {
71         Clear(pageUrl_);
72     }
73     shouldCollectFull_ = false;
74 }
75 
UpdateConfig(std::shared_ptr<MergedConfig> && mergedConfig)76 void NodeDataCache::UpdateConfig(std::shared_ptr<MergedConfig>&& mergedConfig)
77 {
78     std::unique_lock<std::mutex> lock(cacheLock_);
79     mergedConfig_ = mergedConfig;
80     shouldCollectFull_ = false;
81 }
82 
PutString(const std::string & id,const std::string & value)83 bool NodeDataCache::PutString(const std::string& id, const std::string& value)
84 {
85     if (id.empty() || value.empty() || value.length() > MAX_DATA_LENGTH) {
86         return false;
87     }
88     std::unique_lock<std::mutex> lock(cacheLock_);
89     if (pageUrl_.empty()) {
90         pageUrl_ = GetCurrentPageUrl();
91     }
92     auto iter = mergedConfig_->shareNodes.find(pageUrl_);
93     if (!shouldCollectFull_ && iter == mergedConfig_->shareNodes.end()) {
94         return false;
95     }
96     if (shouldCollectFull_ || iter->second.find(id) != iter->second.end()) {
97         auto iter = container_->find(pageUrl_);
98         if (iter == container_->end()) {
99             auto pageContainer = std::unordered_map<std::string, std::string>();
100             pageContainer.emplace(id, value);
101             container_->emplace(pageUrl_, std::move(pageContainer));
102         } else {
103             if (iter->second.size() >= MAX_SIZE_PER_PAGE) {
104                 return false;
105             }
106             iter->second[id] = value;
107         }
108     }
109     return true;
110 }
111 
PutBool(const std::string & id,bool value)112 bool NodeDataCache::PutBool(const std::string& id, bool value)
113 {
114     std::string strVal = value ? "true" : "false";
115     return PutString(id, strVal);
116 }
117 
PutInt(const std::string & id,int value)118 bool NodeDataCache::PutInt(const std::string& id, int value)
119 {
120     return PutString(id, std::to_string(value));
121 }
122 
PutStringArray(const std::string & id,const std::vector<std::string> & value)123 bool NodeDataCache::PutStringArray(const std::string& id, const std::vector<std::string>& value)
124 {
125     auto jsonArray = JsonUtil::CreateArray(true);
126     for (size_t i = 0; i < value.size(); i++) {
127         jsonArray->Put(std::to_string(i).c_str(), value.at(i).c_str());
128     }
129     return PutString(id, jsonArray->ToString());
130 }
131 
PutMultiple(const std::string & id,const std::string & name,bool value)132 bool NodeDataCache::PutMultiple(const std::string& id, const std::string& name, bool value)
133 {
134     auto json = JsonUtil::Create(true);
135     json->Put(KEY_TEXT, name.c_str());
136     json->Put(KEY_CHECKED, value);
137     return PutString(id, json->ToString());
138 }
139 
PutMultiple(const std::string & id,const std::string & name,int index)140 bool NodeDataCache::PutMultiple(const std::string& id, const std::string& name, int index)
141 {
142     auto json = JsonUtil::Create(true);
143     json->Put(KEY_TEXT, name.c_str());
144     json->Put(KEY_INDEX, index);
145     return PutString(id, json->ToString());
146 }
147 
PutMultiple(const std::string & id,const std::string & name,const std::vector<std::string> & value)148 bool NodeDataCache::PutMultiple(const std::string& id, const std::string& name, const std::vector<std::string>& value)
149 {
150     auto json = JsonUtil::Create(true);
151     json->Put(KEY_TEXT, name.c_str());
152     auto jsonArray = JsonUtil::CreateArray(false);
153     for (size_t i = 0; i < value.size(); i++) {
154         jsonArray->Put(std::to_string(i).c_str(), value.at(i).c_str());
155     }
156     json->Put(KEY_TEXT_ARRAY, jsonArray);
157     return PutString(id, json->ToString());
158 }
159 
GetNodeData(const std::string & pageUrl,std::unordered_map<std::string,std::string> & nodes)160 void NodeDataCache::GetNodeData(const std::string& pageUrl, std::unordered_map<std::string, std::string>& nodes)
161 {
162     if (pageUrl.empty()) {
163         return;
164     }
165     std::unique_lock<std::mutex> lock(cacheLock_);
166     auto iter = container_->find(pageUrl);
167     if (iter == container_->end()) {
168         return;
169     }
170     lock.unlock();
171     for (auto nodeIter = nodes.begin(); nodeIter != nodes.end(); nodeIter++) {
172         auto it = iter->second.find(nodeIter->first);
173         if (it != iter->second.end()) {
174             nodes[it->first] = it->second;
175         }
176     }
177 }
178 
Clear(const std::string & pageUrl)179 void NodeDataCache::Clear(const std::string& pageUrl)
180 {
181     if (pageUrl.empty()) {
182         return;
183     }
184     std::unique_lock<std::mutex> lock(cacheLock_);
185     auto iter = container_->find(pageUrl);
186     if (iter != container_->end()) {
187         container_->erase(iter);
188     }
189 }
190 
Reset()191 void NodeDataCache::Reset()
192 {
193     std::unique_lock<std::mutex> lock(cacheLock_);
194     container_->clear();
195     pageUrl_ = "";
196     prePageUrl_ = "";
197 }
198 
GetExposureCfg(const std::string & inspectId,ExposureCfg & cfg)199 void NodeDataCache::GetExposureCfg(const std::string& inspectId, ExposureCfg& cfg)
200 {
201     if (pageUrl_.empty()) {
202         pageUrl_ = GetCurrentPageUrl();
203     }
204     auto iter = mergedConfig_->exposureNodes.find(pageUrl_);
205     if (iter == mergedConfig_->exposureNodes.end()) {
206         return;
207     }
208     auto cfgIter = iter->second.find({ inspectId, 0.0, 0 });
209     if (cfgIter == iter->second.end()) {
210         return;
211     }
212     cfg.id = cfgIter->id;
213     cfg.ratio = cfgIter->ratio;
214     cfg.duration = cfgIter->duration;
215 }
216 } // namespace OHOS::Ace::Recorder
217